Task: Angles (geometric), normalization and conversion


C++: #include <functional>
#include <iostream>
#include <iomanip>
#include <math.h>
#include <sstream>
#include <vector>
#include <boost/algorithm/string.hpp>

template<typename T>
T normalize(T a, double b) { return std::fmod(a, b); }

inline double d2d(double a) { return normalize<double>(a, 360); }
inline double g2g(double a) { return normalize<double>(a, 400); }
inline double m2m(double a) { return normalize<double>(a, 6400); }
inline double r2r(double a) { return normalize<double>(a, 2*M_PI); }

double d2g(double a) { return g2g(a * 10 / 9); }
double d2m(double a) { return m2m(a * 160 / 9); }
double d2r(double a) { return r2r(a * M_PI / 180); }
double g2d(double a) { return d2d(a * 9 / 10); }
double g2m(double a) { return m2m(a * 16); }
double g2r(double a) { return r2r(a * M_PI / 200); }
double m2d(double a) { return d2d(a * 9 / 160); }
double m2g(double a) { return g2g(a / 16); }
double m2r(double a) { return r2r(a * M_PI / 3200); }
double r2d(double a) { return d2d(a * 180 / M_PI); }
double r2g(double a) { return g2g(a * 200 / M_PI); }
double r2m(double a) { return m2m(a * 3200 / M_PI); }

void print(const std::vector<double> &values, const char *s, std::function<double(double)> f) {
    using namespace std;
    ostringstream out;
    out << "                  ┌───────────────────┐\n";
    out << "                  │ " << setw(17) << s << " │\n";
    out << "┌─────────────────┼───────────────────┤\n";
    for (double i : values)
        out << "│ " << setw(15) << fixed << i << defaultfloat << " │ " << setw(17) << fixed << f(i) << defaultfloat << " │\n";
    out << "└─────────────────┴───────────────────┘\n";
    auto str = out.str();
    boost::algorithm::replace_all(str, ".000000", "       ");
    cout << str;
}

int main() {
    std::vector<double> values = { -2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000 };
    print(values, "normalized (deg)", d2d);
    print(values, "normalized (grad)", g2g);
    print(values, "normalized (mil)", m2m);
    print(values, "normalized (rad)", r2r);

    print(values, "deg -> grad ", d2g);
    print(values, "deg -> mil ", d2m);
    print(values, "deg -> rad ", d2r);

    print(values, "grad -> deg ", g2d);
    print(values, "grad -> mil ", g2m);
    print(values, "grad -> rad ", g2r);

    print(values, "mil -> deg ", m2d);
    print(values, "mil -> grad ", m2g);
    print(values, "mil -> rad ", m2r);

    print(values, "rad -> deg ", r2d);
    print(values, "rad -> grad ", r2g);
    print(values, "rad -> mil ", r2m);

    return 0;
}




Java: import java.text.DecimalFormat;



public class AnglesNormalizationAndConversion {

    public static void main(String[] args) {
        DecimalFormat formatAngle = new DecimalFormat("######0.000000");
        DecimalFormat formatConv = new DecimalFormat("###0.0000");
        System.out.printf("                               degrees    gradiens        mils     radians%n");
        for ( double angle : new double[] {-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000} ) {
            for ( String units : new String[] {"degrees", "gradiens", "mils", "radians"}) {
                double d = 0, g = 0, m = 0, r = 0;
                switch (units) {
                case "degrees":
                    d = d2d(angle);
                    g = d2g(d);
                    m = d2m(d);
                    r = d2r(d);
                    break;
                case "gradiens":
                    g = g2g(angle);
                    d = g2d(g);
                    m = g2m(g);
                    r = g2r(g);
                    break;
                case "mils":
                    m = m2m(angle);
                    d = m2d(m);
                    g = m2g(m);
                    r = m2r(m);
                    break;
                case "radians":
                    r = r2r(angle);
                    d = r2d(r);
                    g = r2g(r);
                    m = r2m(r);
                    break;
                }
                System.out.printf("%15s  %8s = %10s  %10s  %10s  %10s%n", formatAngle.format(angle), units, formatConv.format(d), formatConv.format(g), formatConv.format(m), formatConv.format(r));
            }
        }
    }

    private static final double DEGREE = 360D;
    private static final double GRADIAN = 400D;
    private static final double MIL = 6400D;
    private static final double RADIAN = (2 * Math.PI);
    
    private static double d2d(double a) {
        return a % DEGREE;
    }
    private static double d2g(double a) {
        return a * (GRADIAN / DEGREE);
    }
    private static double d2m(double a) {
        return a * (MIL / DEGREE);
    }
    private static double d2r(double a) {
        return a * (RADIAN / 360);
    }

    private static double g2d(double a) {
        return a * (DEGREE / GRADIAN);
    }
    private static double g2g(double a) {
        return a % GRADIAN;
    }
    private static double g2m(double a) {
        return a * (MIL / GRADIAN);
    }
    private static double g2r(double a) {
        return a * (RADIAN / GRADIAN);
    }
    
    private static double m2d(double a) {
        return a * (DEGREE / MIL);
    }
    private static double m2g(double a) {
        return a * (GRADIAN / MIL);
    }
    private static double m2m(double a) {
        return a % MIL;
    }
    private static double m2r(double a) {
        return a * (RADIAN / MIL);
    }
    
    private static double r2d(double a) {
        return a * (DEGREE / RADIAN);
    }
    private static double r2g(double a) {
        return a * (GRADIAN / RADIAN);
    }
    private static double r2m(double a) {
        return a * (MIL / RADIAN);
    }
    private static double r2r(double a) {
        return a % RADIAN;
    }
    
}