Data commit

This commit is contained in:
Ingy döt Net 2023-07-01 11:58:00 -04:00
parent 7387c8f97b
commit cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions

View file

@ -0,0 +1,3 @@
---
from: http://rosettacode.org/wiki/Angles_(geometric),_normalization_and_conversion
note: geometry

View file

@ -0,0 +1,118 @@
This task is about the normalization and/or conversion of (geometric) angles using
some common scales.
The angular scales that will be used in this task are:
::*   degree
::*   gradian
::*   mil
::*   radian
;Definitions:
The angular scales used or referenced here:
::*   '''turn'''   is a full turn or 360 degrees, also shown as 360º
::* &nbsp; '''degree''' &nbsp; is &nbsp; <big>'''<sup>1</sup>/<sub>360</sub>'''</big> &nbsp; of a turn
::* &nbsp; '''gradian''' &nbsp; is &nbsp; <big>'''<sup>1</sup>/<sub>400</sub>'''</big> &nbsp; of a turn
::* &nbsp; '''mil''' &nbsp; is &nbsp; <big>'''<sup>1</sup>/<sub>6400</sub>'''</big> &nbsp; of a turn
::* &nbsp; '''radian''' &nbsp; is &nbsp; <big>'''<sup>1</sup>/<sub>2<big><big><math>\pi</math></big></big></sub></big>''' &nbsp; of a turn &nbsp; (or &nbsp; <big>'''<sup>0.5</sup>/<sub><big><big><math>\pi</math></big></big></sub>'''</big> &nbsp; of a turn)
Or, to put it another way, &nbsp; for a full circle:
::* &nbsp; there are &nbsp; '''360''' &nbsp; degrees
::* &nbsp; there are &nbsp; '''400''' &nbsp; gradians
::* &nbsp; there are &nbsp; '''6,400''' &nbsp; mils
::* &nbsp; there are &nbsp; '''2<big><big><math>\pi</math></big></big>''' &nbsp; radians &nbsp; (roughly equal to '''6.283<small>+</small>''')
A &nbsp; '''mil''' &nbsp; is approximately equal to a &nbsp; ''milliradian'' &nbsp; (which is &nbsp; <big>'''<sup>1</sup>/<sub>1000</sub>'''</big> &nbsp; of a radian).
There is another definition of a &nbsp; '''mil''' &nbsp; which
is &nbsp; '''<sup>1</sup>/<sub>1000</sub>''' &nbsp; of a radian &nbsp; ─── this
definition <u>won't</u> be used in this Rosetta Code task.
'''Turns''' &nbsp; are sometimes known or shown as:
:::* &nbsp; turn(s)
:::* &nbsp; 360 degrees
:::* &nbsp; unit circle
:::* &nbsp; a (full) circle
'''Degrees''' &nbsp; are sometimes known or shown as:
:::* &nbsp; degree(s)
:::* &nbsp; deg
:::* &nbsp; º &nbsp; &nbsp; &nbsp; (a symbol)
:::* &nbsp; ° &nbsp; &nbsp; &nbsp; (another symbol)
'''Gradians''' &nbsp; are sometimes known or shown as:
:::* &nbsp; gradian(s)
:::* &nbsp; grad(s)
:::* &nbsp; grade(s)
:::* &nbsp; gon(s)
:::* &nbsp; metric degree(s)
:::* &nbsp; (Note that &nbsp; '''centigrade''' &nbsp; was used for <sup>1</sup>/<sub>100</sub><sup>th</sup> of a grade, see the note below.)
'''Mils''' &nbsp; are sometimes known or shown as:
:::* &nbsp; mil(s)
:::* &nbsp; NATO mil(s)
'''Radians''' &nbsp; are sometimes known or shown as:
:::* &nbsp; radian(s)
:::* &nbsp; rad(s)
;Notes:
In continental Europe, the French term &nbsp; '''centigrade''' &nbsp; was used
for &nbsp; '''<sup>1</sup>/<sub>100</sub>''' &nbsp; of a grad (grade); &nbsp; this was
one reason for the adoption of the term &nbsp; '''Celsius''' &nbsp; to
replace &nbsp; '''centigrade''' &nbsp; as the name of a temperature scale.
Gradians were commonly used in civil engineering.
Mils were normally used for artillery &nbsp; (elevations of the gun barrel for ranging).
;Positive and negative angles:
Although the definition of the measurement of an angle doesn't support the
concept of a negative angle, &nbsp; it's frequently useful to impose a convention that
allows positive and negative angular values to represent orientations and/or rotations
in opposite directions relative to some reference. &nbsp; It is this reason that
negative angles will keep their sign and <u>not</u> be normalized to positive angles.
;Normalization:
Normalization &nbsp; (for this Rosetta Code task) &nbsp; will keep the same
sign, &nbsp; but it will reduce the magnitude to less than a full circle; &nbsp; in
other words, less than 360º.
Normalization &nbsp; <u>shouldn't</u> &nbsp; change &nbsp; '''-45º''' &nbsp; to &nbsp; '''315º''',
An angle of &nbsp; '''0º''', &nbsp; '''+0º''', &nbsp; '''0.000000''', &nbsp; or &nbsp; '''-0º''' &nbsp; should be
shown as &nbsp; '''0º'''.
;Task:
::* &nbsp; write a function (or equivalent) to do the normalization for each scale
:::::* Suggested names:
:::::* '''d2d''', &nbsp; '''g2g''', &nbsp; '''m2m''', &nbsp; and &nbsp;'''r2r'''
::* &nbsp; write a function (or equivalent) to convert one scale to another
:::::* Suggested names for comparison of different computer language function names:
:::::* '''d2g''', &nbsp; '''d2m''', &nbsp; and &nbsp; '''d2r''' &nbsp; for degrees
:::::* '''g2d''', &nbsp; '''g2m''', &nbsp; and &nbsp; '''g2r''' &nbsp; for gradians
:::::* '''m2d''', &nbsp; '''m2g''', &nbsp; and &nbsp; '''m2r''' &nbsp; for mils
:::::* '''r2d''', &nbsp; '''r2g''', &nbsp; and &nbsp; '''r2m''' &nbsp; for radians
::* &nbsp; normalize all angles used &nbsp; (except for the "original" or "base" angle)
::* &nbsp; show the angles in every scale and convert them to all other scales
::* &nbsp; show all output here on this page
For the (above) conversions, &nbsp; use these dozen numbers &nbsp; (in the order shown):
:* &nbsp; '''-2 &nbsp; -1 &nbsp; 0 &nbsp; 1 &nbsp; 2 &nbsp; 6.2831853 &nbsp; 16 &nbsp; 57.2957795 &nbsp; 359 &nbsp; 399 &nbsp; 6399 &nbsp; 1000000'''
<br><br>

View file

@ -0,0 +1,45 @@
V values = [Float(-2), -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000]
F normd(x) {R fmod(x, 360)}
F normg(x) {R fmod(x, 400)}
F normm(x) {R fmod(x, 6400)}
F normr(x) {R fmod(x, (2 * math:pi))}
F d2g(x) {R normd(x) * 10 / 9}
F d2m(x) {R normd(x) * 160 / 9}
F d2r(x) {R normd(x) * math:pi / 180}
F g2d(x) {R normg(x) * 9 / 10}
F g2m(x) {R normg(x) * 16}
F g2r(x) {R normg(x) * math:pi / 200}
F m2d(x) {R normm(x) * 9 / 160}
F m2g(x) {R normm(x) / 16}
F m2r(x) {R normm(x) * math:pi / 3200}
F r2d(x) {R normr(x) * 180 / math:pi}
F r2g(x) {R normr(x) * 200 / math:pi}
F r2m(x) {R normr(x) * 3200 / math:pi}
print( Degrees Normalized Gradians Mils Radians)
print(‘───────────────────────────────────────────────────────────────────────────────────’)
L(val) values
print(#7.7 #7.7 #7.7 #7.7 #7.7.format(val, normd(val), d2g(val), d2m(val), d2r(val)))
print()
print( Gradians Normalized Degrees Mils Radians)
print(‘───────────────────────────────────────────────────────────────────────────────────’)
L(val) values
print(#7.7 #7.7 #7.7 #7.7 #7.7.format(val, normg(val), g2d(val), g2m(val), g2r(val)))
print()
print( Mils Normalized Degrees Gradians Radians)
print(‘───────────────────────────────────────────────────────────────────────────────────’)
L(val) values
print(#7.7 #7.7 #7.7 #7.7 #7.7.format(val, normm(val), m2d(val), m2g(val), m2r(val)))
print()
print( Radians Normalized Degrees Gradians Mils)
print(‘───────────────────────────────────────────────────────────────────────────────────’)
L(val) values
print(#7.7 #7.7 #7.7 #7.7 #7.7.format(val, normr(val), r2d(val), r2g(val), r2m(val)))

View file

@ -0,0 +1,63 @@
# syntax: GAWK -f ANGLES_(GEOMETRIC)_NORMALIZATION_AND_CONVERSION.AWK
# gawk starts showing discrepancies at test case number 7 when compared with C#
BEGIN {
pi = atan2(0,-1)
data_leng = split("-2,-1,0,1,2,6.2831853,16,57.2957795,359,399,6399,1000000",data_arr,",")
unit_leng = split("degree,gradian,mil,radian",unit_arr,",")
printf("%-10s %-10s %-8s %-12s %-12s %-12s %-12s test#\n","angle","normalized","unit","degrees","gradians","mils","radians")
for (a=1; a<=data_leng; a++) {
angle = data_arr[a]
arr["degree"] = normalize(angle,360)
arr["gradian"] = normalize(angle,400)
arr["mil"] = normalize(angle,6400)
arr["radian"] = normalize(angle,pi*2)
print("") # optional blank line between groupings
for (b=1; b<=unit_leng; b++) {
key1 = unit_arr[b]
printf("%-10s %-10s %-8s",angle,arr[key1],unit_arr[b])
for (c=1; c<=unit_leng; c++) {
key2 = unit_arr[c]
func_name = sprintf("%s2%s",key1,key2)
printf(" %-12s",(key1 == key2) ? arr[key2] : @func_name(arr[key2]))
}
printf(" %d\n",a)
}
}
# normalize_usage_stats()
exit(0)
}
function normalize(angle,n, a) {
a = angle
profile_arr[a][n]["+"] = 0
profile_arr[a][n]["-"] = 0
while (angle <= -n) { angle += n ; profile_arr[a][n]["+"]++ }
while (angle >= n) { angle -= n ; profile_arr[a][n]["-"]++ }
return(angle)
}
function normalize_usage_stats( a,b,c,n,total) {
print("")
PROCINFO["sorted_in"] = "@ind_num_asc"
for (a in profile_arr) {
for (b in profile_arr[a]) {
for (c in profile_arr[a][b]) {
n = profile_arr[a][b][c]
if (n == 0) { continue }
printf("%10s %10s %1s %7d\n",a,b,c,n)
total += n
}
}
}
printf("%31d total\n",total)
}
function degree2gradian(angle) { return(angle * 10 / 9) }
function degree2mil(angle) { return(angle * 160 / 9) }
function degree2radian(angle) { return(angle * pi / 180) }
function gradian2degree(angle) { return(angle * 9 / 10) }
function gradian2mil(angle) { return(angle * 16) }
function gradian2radian(angle) { return(angle * pi / 200) }
function mil2degree(angle) { return(angle * 9 / 160) }
function mil2gradian(angle) { return(angle / 16) }
function mil2radian(angle) { return(angle * pi / 3200) }
function radian2degree(angle) { return(angle * 180 / pi) }
function radian2gradian(angle) { return(angle * 200 / pi) }
function radian2mil(angle) { return(angle * 3200 / pi) }

View file

@ -0,0 +1,70 @@
testAngles := [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000]
result .= "Degrees Degrees Gradians Mils Radians`n"
for i, a in testAngles
result .= a "`t" Deg2Deg(a) "`t" Deg2Grad(a) "`t" Deg2Mil(a) "`t" Deg2Rad(a) "`n"
result .= "`nGradians Degrees Gradians Mils Radians`n"
for i, a in testAngles
result .= a "`t" Grad2Deg(a) "`t" Grad2Grad(a) "`t" Grad2Mil(a) "`t" Grad2Rad(a) "`n"
result .= "`nMills Degrees Gradians Mils Radians`n"
for i, a in testAngles
result .= a "`t" Mil2Deg(a) "`t" Mil2Grad(a) "`t" Mil2Mil(a) "`t" Mil2Rad(a) "`n"
result .= "`nRadians Degrees Gradians Mils Radians`n"
for i, a in testAngles
result .= a "`t" Rad2Deg(a) "`t" Rad2Grad(a) "`t" Rad2Mil(a) "`t" Rad2Rad(a) "`n"
MsgBox, 262144, , % result
return
;-------------------------------------------------------
Deg2Deg(Deg){
return Mod(Deg, 360)
}
Deg2Grad(Deg){
return Deg2Deg(Deg) * 400 / 360
}
Deg2Mil(Deg){
return Deg2Deg(Deg) * 6400 / 360
}
Deg2Rad(Deg){
return Deg2Deg(Deg) * (π:=3.141592653589793) / 180
}
;-------------------------------------------------------
Grad2Grad(Grad){
return Mod(Grad, 400)
}
Grad2Deg(Grad){
return Grad2Grad(Grad) * 360 / 400
}
Grad2Mil(Grad){
return Grad2Grad(Grad) * 6400 / 400
}
Grad2Rad(Grad){
return Grad2Grad(Grad) * (π:=3.141592653589793) / 200
}
;-------------------------------------------------------
Mil2Mil(Mil){
return Mod(Mil, 6400)
}
Mil2Deg(Mil){
return Mil2Mil(Mil) * 360 / 6400
}
Mil2Grad(Mil){
return Mil2Mil(Mil) * 400 / 6400
}
Mil2Rad(Mil){
return Mil2Mil(Mil) * (π:=3.141592653589793) / 3200
}
;-------------------------------------------------------
Rad2Rad(Rad){
return Mod(Rad, 2*(π:=3.141592653589793))
}
Rad2Deg(Rad){
return Rad2Rad(Rad) * 180 / (π:=3.141592653589793)
}
Rad2Grad(Rad){
return Rad2Rad(Rad) * 200 / (π:=3.141592653589793)
}
Rad2Mil(Rad){
return Rad2Rad(Rad) * 3200 / (π:=3.141592653589793)
}
;-------------------------------------------------------

View file

@ -0,0 +1,68 @@
#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;
}

View file

@ -0,0 +1,64 @@
using System;
public static class Angles
{
public static void Main() => Print(-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 6399, 1_000_000);
public static void Print(params double[] angles) {
string[] names = { "Degrees", "Gradians", "Mils", "Radians" };
Func<double, double> rnd = a => Math.Round(a, 4);
Func<double, double>[] normal = { NormalizeDeg, NormalizeGrad, NormalizeMil, NormalizeRad };
Func<double, double>[,] convert = {
{ a => a, DegToGrad, DegToMil, DegToRad },
{ GradToDeg, a => a, GradToMil, GradToRad },
{ MilToDeg, MilToGrad, a => a, MilToRad },
{ RadToDeg, RadToGrad, RadToMil, a => a }
};
Console.WriteLine($@"{"Angle",-12}{"Normalized",-12}{"Unit",-12}{
"Degrees",-12}{"Gradians",-12}{"Mils",-12}{"Radians",-12}");
foreach (double angle in angles) {
for (int i = 0; i < 4; i++) {
double nAngle = normal[i](angle);
Console.WriteLine($@"{
rnd(angle),-12}{
rnd(nAngle),-12}{
names[i],-12}{
rnd(convert[i, 0](nAngle)),-12}{
rnd(convert[i, 1](nAngle)),-12}{
rnd(convert[i, 2](nAngle)),-12}{
rnd(convert[i, 3](nAngle)),-12}");
}
}
}
public static double NormalizeDeg(double angle) => Normalize(angle, 360);
public static double NormalizeGrad(double angle) => Normalize(angle, 400);
public static double NormalizeMil(double angle) => Normalize(angle, 6400);
public static double NormalizeRad(double angle) => Normalize(angle, 2 * Math.PI);
private static double Normalize(double angle, double N) {
while (angle <= -N) angle += N;
while (angle >= N) angle -= N;
return angle;
}
public static double DegToGrad(double angle) => angle * 10 / 9;
public static double DegToMil(double angle) => angle * 160 / 9;
public static double DegToRad(double angle) => angle * Math.PI / 180;
public static double GradToDeg(double angle) => angle * 9 / 10;
public static double GradToMil(double angle) => angle * 16;
public static double GradToRad(double angle) => angle * Math.PI / 200;
public static double MilToDeg(double angle) => angle * 9 / 160;
public static double MilToGrad(double angle) => angle / 16;
public static double MilToRad(double angle) => angle * Math.PI / 3200;
public static double RadToDeg(double angle) => angle * 180 / Math.PI;
public static double RadToGrad(double angle) => angle * 200 / Math.PI;
public static double RadToMil(double angle) => angle * 3200 / Math.PI;
}

View file

@ -0,0 +1,39 @@
#define PI 3.141592653589793
#define TWO_PI 6.283185307179586
double normalize2deg(double a) {
while (a < 0) a += 360;
while (a >= 360) a -= 360;
return a;
}
double normalize2grad(double a) {
while (a < 0) a += 400;
while (a >= 400) a -= 400;
return a;
}
double normalize2mil(double a) {
while (a < 0) a += 6400;
while (a >= 6400) a -= 6400;
return a;
}
double normalize2rad(double a) {
while (a < 0) a += TWO_PI;
while (a >= TWO_PI) a -= TWO_PI;
return a;
}
double deg2grad(double a) {return a * 10 / 9;}
double deg2mil(double a) {return a * 160 / 9;}
double deg2rad(double a) {return a * PI / 180;}
double grad2deg(double a) {return a * 9 / 10;}
double grad2mil(double a) {return a * 16;}
double grad2rad(double a) {return a * PI / 200;}
double mil2deg(double a) {return a * 9 / 160;}
double mil2grad(double a) {return a / 16;}
double mil2rad(double a) {return a * PI / 3200;}
double rad2deg(double a) {return a * 180 / PI;}
double rad2grad(double a) {return a * 200 / PI;}
double rad2mil(double a) {return a * 3200 / PI;}

View file

@ -0,0 +1,29 @@
(defun DegToDeg (a) (rem a 360))
(defun GradToGrad (a) (rem a 400))
(defun MilToMil (a) (rem a 6400))
(defun RadToRad (a) (rem a (* 2 pi)))
(defun DegToGrad (a) (GradToGrad (* (/ a 360) 400)))
(defun DegToRad (a) (RadToRad (* (/ a 360) (* 2 pi))))
(defun DegToMil (a) (MilToMil (* (/ a 360) 6400)))
(defun GradToDeg (a) (DegToDeg (* (/ a 400) 360)))
(defun GradToRad (a) (RadToRad (* (/ a 400) (* 2 pi))))
(defun GradToMil (a) (MilToMil (* (/ a 400) 6400)))
(defun MilToDeg (a) (DegToDeg (* (/ a 6400) 360)))
(defun MilToGrad (a) (GradToGrad (* (/ a 6400) 400)))
(defun MilToRad (a) (RadToRad (* (/ a 6400) (* 2 pi))))
(defun RadToDeg (a) (DegToDeg (* (/ a (* 2 pi)) 360)))
(defun RadToGrad (a) (GradToGrad (* (/ a (* 2 pi)) 400)))
(defun RadToMil (a) (MilToMil (* (/ a (* 2 pi)) 6400)))
(defun angles (&rest angles)
(if (not angles) (setf angles '(-2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000)))
(dolist (a angles)
(format t "UNIT ~15@a ~15@a ~15@a ~15@a ~15@a~%" "VAL*" "DEG" "GRAD" "MIL" "RAD")
(format t "Deg | ~15f | ~15f | ~15f | ~15f | ~15f~%" a (DegToDeg a) (DegToGrad a) (DegToMil a) (DegToRad a))
(format t "Grad | ~15f | ~15f | ~15f | ~15f | ~15f~%" a (GradToDeg a) (GradToGrad a) (GradToMil a) (GradToRad a))
(format t "Mil | ~15f | ~15f | ~15f | ~15f | ~15f~%" a (MilToDeg a) (MilToGrad a) (MilToMil a) (MilToRad a))
(format t "Rad | ~15f | ~15f | ~15f | ~15f | ~15f~%~%" a (RadToDeg a) (RadToGrad a) (RadToMil a) (RadToRad a))))

View file

@ -0,0 +1,127 @@
program normalization_and_conversion;
{$APPTYPE CONSOLE}
uses
System.SysUtils,
System.Math;
function d2d(d: double): double;
begin
result := FMod(d, 360);
end;
function g2g(g: double): double;
begin
result := FMod(g, 400);
end;
function m2m(m: double): double;
begin
result := FMod(m, 6400);
end;
function r2r(r: double): double;
begin
result := FMod(r, 2 * Pi);
end;
function d2g(d: double): double;
begin
result := d2d(d) * 400 / 360;
end;
function d2m(d: double): double;
begin
result := d2d(d) * 6400 / 360;
end;
function d2r(d: double): double;
begin
result := d2d(d) * Pi / 180;
end;
function g2d(g: double): double;
begin
result := g2g(g) * 360 / 400;
end;
function g2m(g: double): double;
begin
result := g2g(g) * 6400 / 400;
end;
function g2r(g: double): double;
begin
result := g2g(g) * Pi / 200;
end;
function m2d(m: double): double;
begin
result := m2m(m) * 360 / 6400;
end;
function m2g(m: double): double;
begin
result := m2m(m) * 400 / 6400;
end;
function m2r(m: double): double;
begin
result := m2m(m) * Pi / 3200;
end;
function r2d(r: double): double;
begin
result := r2r(r) * 180 / Pi;
end;
function r2g(r: double): double;
begin
result := r2r(r) * 200 / Pi;
end;
function r2m(r: double): double;
begin
result := r2r(r) * 3200 / Pi;
end;
function s(f: double): string;
begin
var wf := FloatToStrF(f, ffGeneral, 16, 64).Split([FormatSettings.DecimalSeparator], TStringSplitOptions.ExcludeEmpty);
if Length(wf) = 1 then
exit(format('%7s ', [wf[0]]));
var le := length(wf[1]);
if le > 7 then
le := 7;
Result := format('%7s.%-7s', [wf[0], copy(wf[1], 0, le)]);
end;
begin
var angles: TArray<Double> := [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359,
399, 6399, 1000000];
var ft := '%s %s %s %s %s';
writeln(format(ft, [' degrees ', 'normalized degs', ' gradians ',
' mils ', ' radians']));
for var a in angles do
writeln(format(ft, [s(a), s(d2d(a)), s(d2g(a)), s(d2m(a)), s(d2r(a))]));
writeln(format(ft, [#10' gradians ', 'normalized grds', ' degrees ',
' mils ', ' radians']));
for var a in angles do
writeln(format(ft, [s(a), s(g2g(a)), s(g2d(a)), s(g2m(a)), s(g2r(a))]));
writeln(format(ft, [#10' mils ', 'normalized mils', ' degrees ',
' gradians ', ' radians']));
for var a in angles do
writeln(format(ft, [s(a), s(m2m(a)), s(m2d(a)), s(m2g(a)), s(m2r(a))]));
writeln(format(ft, [#10' radians ', 'normalized rads', ' degrees ',
' gradians ', ' mils ']));
for var a in angles do
writeln(format(ft, [s(a), s(r2r(a)), s(r2d(a)), s(r2g(a)), s(r2m(a))]));
readln;
end.

View file

@ -0,0 +1,25 @@
USING: accessors combinators formatting inverse kernel math
math.constants quotations qw sequences units.si ;
IN: rosetta-code.angles
ALIAS: degrees arc-deg
: gradiens ( n -- d ) 9/10 * degrees ;
: mils ( n -- d ) 9/160 * degrees ;
: normalize ( d -- d' ) [ 2 pi * mod ] change-value ;
CONSTANT: units { degrees gradiens mils radians }
: .row ( angle unit -- )
2dup "%-12u%-12s" printf ( x -- x ) execute-effect
normalize units [ 1quotation [undo] call( x -- x ) ] with
map "%-12.4f%-12.4f%-12.4f%-12.4f\n" vprintf ;
: .header ( -- )
qw{ angle unit } units append
"%-12s%-12s%-12s%-12s%-12s%-12s\n" vprintf ;
: angles ( -- )
.header
{ -2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000 }
units [ .row ] cartesian-each ;
MAIN: angles

View file

@ -0,0 +1,121 @@
#define PI 3.1415926535897932384626433832795028842
#define INVALID -99999
function clamp( byval n as double, lo as double, hi as double ) as double
while n <= lo
n += (hi - lo)/2
wend
while n >= hi
n += (lo - hi)/2
wend
return n
end function
function anglenc( byval angle as double, byval source as string, byval targ as string ) as double
source = ucase(source)
targ = ucase(targ)
select case source
case "D":
angle = clamp(angle, -360, 360)
select case targ
case "D":
return angle
case "G":
return angle*10/9
case "M":
return angle*160/9
case "R":
return angle*PI/180
case "T":
return angle/360
case else
return INVALID
end select
case "G":
angle = clamp(angle, -400, 400)
select case targ
case "D":
return angle*9/10
case "G":
return angle
case "M":
return angle*16
case "R":
return angle*PI/200
case "T":
return angle/400
case else
return INVALID
end select
case "M":
angle = clamp(angle, -6400, 6400)
select case targ
case "D":
return angle*9/160
case "G":
return angle/16
case "M":
return angle
case "R":
return angle*PI/3200
case "T":
return angle/6400
case else
return INVALID
end select
case "R":
angle = clamp(angle, -2*PI, 2*PI)
select case targ
case "D":
return angle*180/PI
case "G":
return angle*200/PI
case "M":
return angle*3200/PI
case "R":
return angle
case "T":
return angle/(2*PI)
case else
return INVALID
end select
case "T":
angle = clamp(angle, -1, 1)
select case targ
case "D":
return angle*360
case "G":
return angle*400
case "M":
return angle*6400
case "R":
return angle*2*PI
case "T":
return angle
case else
return INVALID
end select
case else:
return INVALID
end select
end function
function clip( st as string, num as uinteger ) as string
if len(st)<num then return st
return left(st, num)
end function
dim as string scales = "DGMRT", source, targ
dim as double angles(12) = {-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000}
print "Angle Normalised Unit | D G M R T"
for k as ubyte = 0 to 11
for i as ubyte = 1 to 5
source = mid(scales,i,1)
print angles(k), clip(str(anglenc(angles(k), source, source )), 10), source, "|",
for j as ubyte = 1 to 5
targ = mid(scales, j, 1)
print clip(str(anglenc(angles(k), source, targ )), 10),
next j
print
next i
next k

View file

@ -0,0 +1,75 @@
package main
import (
"fmt"
"math"
"strconv"
"strings"
)
func d2d(d float64) float64 { return math.Mod(d, 360) }
func g2g(g float64) float64 { return math.Mod(g, 400) }
func m2m(m float64) float64 { return math.Mod(m, 6400) }
func r2r(r float64) float64 { return math.Mod(r, 2*math.Pi) }
func d2g(d float64) float64 { return d2d(d) * 400 / 360 }
func d2m(d float64) float64 { return d2d(d) * 6400 / 360 }
func d2r(d float64) float64 { return d2d(d) * math.Pi / 180 }
func g2d(g float64) float64 { return g2g(g) * 360 / 400 }
func g2m(g float64) float64 { return g2g(g) * 6400 / 400 }
func g2r(g float64) float64 { return g2g(g) * math.Pi / 200 }
func m2d(m float64) float64 { return m2m(m) * 360 / 6400 }
func m2g(m float64) float64 { return m2m(m) * 400 / 6400 }
func m2r(m float64) float64 { return m2m(m) * math.Pi / 3200 }
func r2d(r float64) float64 { return r2r(r) * 180 / math.Pi }
func r2g(r float64) float64 { return r2r(r) * 200 / math.Pi }
func r2m(r float64) float64 { return r2r(r) * 3200 / math.Pi }
// Aligns number to decimal point assuming 7 characters before and after.
func s(f float64) string {
wf := strings.Split(strconv.FormatFloat(f, 'g', 15, 64), ".")
if len(wf) == 1 {
return fmt.Sprintf("%7s ", wf[0])
}
le := len(wf[1])
if le > 7 {
le = 7
}
return fmt.Sprintf("%7s.%-7s", wf[0], wf[1][:le])
}
func main() {
angles := []float64{-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795,
359, 399, 6399, 1000000}
ft := "%s %s %s %s %s\n"
fmt.Printf(ft, " degrees ", "normalized degs", " gradians ", " mils ", " radians")
for _, a := range angles {
fmt.Printf(ft, s(a), s(d2d(a)), s(d2g(a)), s(d2m(a)), s(d2r(a)))
}
fmt.Printf(ft, "\n gradians ", "normalized grds", " degrees ", " mils ", " radians")
for _, a := range angles {
fmt.Printf(ft, s(a), s(g2g(a)), s(g2d(a)), s(g2m(a)), s(g2r(a)))
}
fmt.Printf(ft, "\n mils ", "normalized mils", " degrees ", " gradians ", " radians")
for _, a := range angles {
fmt.Printf(ft, s(a), s(m2m(a)), s(m2d(a)), s(m2g(a)), s(m2r(a)))
}
fmt.Printf(ft, "\n radians ", "normalized rads", " degrees ", " gradians ", " mils ")
for _, a := range angles {
fmt.Printf(ft, s(a), s(r2r(a)), s(r2d(a)), s(r2g(a)), s(r2m(a)))
}
}

View file

@ -0,0 +1,70 @@
import java.lang.reflect.Constructor
abstract class Angle implements Comparable<? extends Angle> {
double value
Angle(double value = 0) { this.value = normalize(value) }
abstract Number unitCircle()
abstract String unitName()
Number normalize(double n) { n % this.unitCircle() }
def <B extends Angle> B asType(Class<B> bClass){
if (bClass == this.class) return this
bClass.getConstructor(Number.class).newInstance(0).tap {
value = this.value * unitCircle() / this.unitCircle()
}
}
String toString() {
"${String.format('%14.8f',value)}${this.unitName()}"
}
int hashCode() {
value.hashCode() + 17 * unit().hashCode()
}
int compareTo(Angle that) {
this.value * that.unitCircle() <=> that.value * this.unitCircle()
}
boolean equals(that) {
this.is(that) ? true
: that instanceof Angle ? (this <=> that) == 0
: that instanceof Number ? this.value == this.normalize(that)
: super.equals(that)
}
}
class Degrees extends Angle {
static final int UNIT_CIRCLE = 360
Number unitCircle() { UNIT_CIRCLE }
static final String UNIT = "º "
String unitName() { UNIT }
Degrees(Number value = 0) { super(value) }
}
class Gradians extends Angle {
static final int UNIT_CIRCLE = 400
Number unitCircle() { UNIT_CIRCLE }
static final String UNIT = " grad"
String unitName() { UNIT }
Gradians(Number value = 0) { super(value) }
}
class Mils extends Angle {
static final int UNIT_CIRCLE = 6400
Number unitCircle() { UNIT_CIRCLE }
static final String UNIT = " mil "
String unitName() { UNIT }
Mils(Number value = 0) { super(value) }
}
class Radians extends Angle {
static final double UNIT_CIRCLE = Math.PI*2
Number unitCircle() { UNIT_CIRCLE }
static final String UNIT = " rad "
String unitName() { UNIT }
Radians(Number value = 0) { super(value) }
}

View file

@ -0,0 +1,6 @@
class AngleCategory {
static Degrees getDeg(Number n) { new Degrees(n) }
static Gradians getGrad(Number n) { new Gradians(n) }
static Mils getMil(Number n) { new Mils(n) }
static Radians getRad(Number n) { new Radians(n) }
}

View file

@ -0,0 +1,17 @@
Number.metaClass.mixin AngleCategory
[ -2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000 ].each { rawAngle ->
println "\n raw angle normalized ------------------------------ conversions ------------------------------"
[rawAngle.deg, rawAngle.grad, rawAngle.mil, rawAngle.rad].each { angle ->
printf("%10s %20s %s %s %s %s\n", rawAngle.toString(), angle,
angle as Degrees, angle as Gradians,
angle as Mils, angle as Radians
)
}
}
// some additional checks implied in the task statement
// but not requested for solution demonstration
assert 360.deg == 0.deg
assert 90.deg == 100.grad
assert Math.PI.rad == 3200.mil

View file

@ -0,0 +1,35 @@
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
import Text.Printf
class (Num a, Fractional a, RealFrac a) => Angle a where
fullTurn :: a -- value of the whole turn
mkAngle :: Double -> a
value :: a -> Double
fromTurn :: Double -> a
toTurn :: a -> Double
normalize :: a -> a
-- conversion of angles to rotations in linear case
fromTurn t = angle t * fullTurn
toTurn a = value $ a / fullTurn
-- normalizer for linear angular unit
normalize a = a `modulo` fullTurn
where
modulo x r | x == r = r
| x < 0 = signum x * abs x `modulo` r
| x >= 0 = x - fromInteger (floor (x / r)) * r
-- smart constructor
angle :: Angle a => Double -> a
angle = normalize . mkAngle
-- Two transformers differ only in the order of type application.
from :: forall a b. (Angle a, Angle b) => a -> b
from = fromTurn . toTurn
to :: forall b a. (Angle a, Angle b) => a -> b
to = fromTurn . toTurn

View file

@ -0,0 +1,68 @@
-- radians
newtype Rad = Rad Double
deriving (Eq, Ord, Num, Real, Fractional, RealFrac, Floating)
instance Show Rad where
show (Rad 0) = printf "∠0"
show (Rad r) = printf "∠%.3f" r
instance Angle Rad where
fullTurn = Rad 2*pi
mkAngle = Rad
value (Rad r) = r
-- degrees
newtype Deg = Deg Double
deriving (Eq, Ord, Num, Real, Fractional, RealFrac, Floating)
instance Show Deg where
show (Deg 0) = printf ""
show (Deg d) = printf "%.3g°" d
instance Angle Deg where
fullTurn = Deg 360
mkAngle = Deg
value (Deg d) = d
-- grads
newtype Grad = Grad Double
deriving (Eq, Ord, Num, Real, Fractional, RealFrac, Floating)
instance Show Grad where
show (Grad 0) = printf "0g"
show (Grad g) = printf "%.3gg" g
instance Angle Grad where
fullTurn = Grad 400
mkAngle = Grad
value (Grad g) = g
-- mils
newtype Mil = Mil Double
deriving (Eq, Ord, Num, Real, Fractional, RealFrac, Floating)
instance Show Mil where
show (Mil 0) = printf "0m"
show (Mil m) = printf "%.3gm" m
instance Angle Mil where
fullTurn = Mil 6400
mkAngle = Mil
value (Mil m) = m
-- example of non-linear angular unit
newtype Slope = Slope Double
deriving (Eq, Ord, Num, Real, Fractional, RealFrac, Floating)
instance Show Slope where
show (Slope 0) = printf "0%"
show (Slope m) = printf "%.g" (m * 100) ++ "%"
instance Angle Slope where
fullTurn = undefined
mkAngle = Slope
value (Slope t) = t
toTurn = toTurn @Rad . angle . atan . value
fromTurn = angle . tan . value . fromTurn @Rad
normalize = id

View file

@ -0,0 +1,35 @@
main = do
let xs = [-2, -1, 0, 1, 2, 6.2831853,
16, 57.2957795, 359, 399, 6399, 1000000]
-- using `to` and `angle` with type application
putStrLn "converting to radians"
print $ to @Rad . angle @Rad <$> xs
print $ to @Rad . angle @Deg <$> xs
print $ to @Rad . angle @Grad <$> xs
print $ to @Rad . angle @Mil <$> xs
print $ to @Rad . angle @Slope <$> xs
-- using `from` with type application
putStrLn "\nconverting to degrees"
print $ from @Rad @Deg . angle <$> xs
print $ from @Deg @Deg . angle <$> xs
print $ from @Grad @Deg . angle <$> xs
print $ from @Mil @Deg . angle <$> xs
print $ from @Slope @Deg . angle <$> xs
-- using normalization for each unit
putStrLn "\nconverting to grads"
print $ to @Grad . normalize . Rad <$> xs
print $ to @Grad . normalize . Deg <$> xs
print $ to @Grad . normalize . Grad <$> xs
print $ to @Grad . normalize . Mil <$> xs
print $ to @Grad . normalize . Slope <$> xs
-- using implicit type annotation
putStrLn "\nconverting to mils"
print $ (from :: Rad -> Mil) . angle <$> xs
print $ (from :: Deg -> Mil) . angle <$> xs
print $ (from :: Grad -> Mil) . angle <$> xs
print $ (from :: Mil -> Mil) . angle <$> xs
print $ (from :: Slope -> Mil) . angle <$> xs

View file

@ -0,0 +1,17 @@
TAU =: 2p1 NB. tauday.com
normalize =: * * 1 | | NB. signum times the fractional part of absolute value
TurnTo=: &*
as_turn =: 1 TurnTo
as_degree =: 360 TurnTo
as_gradian =: 400 TurnTo
as_mil =: 6400 TurnTo
as_radian =: TAU TurnTo
Turn =: adverb def 'normalize as_turn inv m'
Degree =: adverb def 'normalize as_degree inv m'
Gradian =: adverb def 'normalize as_gradian inv m'
Mil =: adverb def 'normalize as_mil inv m'
Radian =: adverb def 'normalize as_radian inv m'

View file

@ -0,0 +1,51 @@
NAMES =: > turn`degree`gradian`mil`radian
ALL =: as_turn`as_degree`as_gradian`as_mil`as_radian
to_all=: NAMES ; ALL`:0
VALUES =: _&".'-2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000'
to_all VALUES Turn
+-------+------------------------------------+
|turn |0 0 0 0 0 0.283185 0 0.29578 0 0 0 0|
|degree |0 0 0 0 0 101.947 0 106.481 0 0 0 0|
|gradian|0 0 0 0 0 113.274 0 118.312 0 0 0 0|
|mil |0 0 0 0 0 1812.39 0 1892.99 0 0 0 0|
|radian |0 0 0 0 0 1.77931 0 1.85844 0 0 0 0|
+-------+------------------------------------+
to_all VALUES Degree
+-------+---------------------------------------------------------------------------------------------------------------+
|turn |_0.00555556 _0.00277778 0 0.00277778 0.00555556 0.0174533 0.0444444 0.159155 0.997222 0.108333 0.775 0.777778|
|degree | _2 _1 0 1 2 6.28319 16 57.2958 359 39 279 280|
|gradian| _2.22222 _1.11111 0 1.11111 2.22222 6.98132 17.7778 63.662 398.889 43.3333 310 311.111|
|mil | _35.5556 _17.7778 0 17.7778 35.5556 111.701 284.444 1018.59 6382.22 693.333 4960 4977.78|
|radian | _0.0349066 _0.0174533 0 0.0174533 0.0349066 0.109662 0.279253 1 6.26573 0.680678 4.86947 4.88692|
+-------+---------------------------------------------------------------------------------------------------------------+
to_all VALUES Gradian
+-------+----------------------------------------------------------------------------------------------+
|turn | _0.005 _0.0025 0 0.0025 0.005 0.015708 0.04 0.143239 0.8975 0.9975 0.9975 0|
|degree | _1.8 _0.9 0 0.9 1.8 5.65487 14.4 51.5662 323.1 359.1 359.1 0|
|gradian| _2 _1 0 1 2 6.28319 16 57.2958 359 399 399 0|
|mil | _32 _16 0 16 32 100.531 256 916.732 5744 6384 6384 0|
|radian |_0.0314159 _0.015708 0 0.015708 0.0314159 0.098696 0.251327 0.9 5.63916 6.26748 6.26748 0|
+-------+----------------------------------------------------------------------------------------------+
to_all VALUES Mil
+-------+-------------------------------------------------------------------------------------------------------------------+
|turn |_0.0003125 _0.00015625 0 0.00015625 0.0003125 0.000981748 0.0025 0.00895247 0.0560937 0.0623438 0.999844 0.25|
|degree | _0.1125 _0.05625 0 0.05625 0.1125 0.353429 0.9 3.22289 20.1937 22.4438 359.944 90|
|gradian| _0.125 _0.0625 0 0.0625 0.125 0.392699 1 3.58099 22.4375 24.9375 399.938 100|
|mil | _2 _1 0 1 2 6.28319 16 57.2958 359 399 6399 1600|
|radian |_0.0019635 _0.000981748 0 0.000981748 0.0019635 0.0061685 0.015708 0.05625 0.352447 0.391717 6.2822 1.5708|
+-------+-------------------------------------------------------------------------------------------------------------------+
to_all VALUES Radian
+-------+---------------------------------------------------------------------------------------------------+
|turn |_0.31831 _0.159155 0 0.159155 0.31831 1 0.546479 0.118907 0.136625 0.502822 0.432481 0.943092|
|degree |_114.592 _57.2958 0 57.2958 114.592 360 196.732 42.8063 49.1848 181.016 155.693 339.513|
|gradian|_127.324 _63.662 0 63.662 127.324 400 218.592 47.5626 54.6498 201.129 172.992 377.237|
|mil |_2037.18 _1018.59 0 1018.59 2037.18 6400 3497.47 761.002 874.397 3218.06 2767.88 6035.79|
|radian | _2 _1 0 1 2 6.28319 3.43363 0.747112 0.858437 3.15933 2.71736 5.92562|
+-------+---------------------------------------------------------------------------------------------------+

View file

@ -0,0 +1,102 @@
import java.text.DecimalFormat;
// Title: Angles (geometric), normalization and conversion
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;
}
}

View file

@ -0,0 +1,61 @@
/*****************************************************************\
| Expects an angle, an origin unit and a unit to convert to, |
| where in/out units are: |
| --------------------------------------------------------------- |
| 'D'/'d' ..... degrees 'M'/'d' ..... mils | |
| 'G'/'g' ..... gradians 'R'/'r' ..... radians |
| --------------------------------------------------------------- |
| example: convert 150 degrees to radians: |
| angleConv(150, 'd', 'r') |
\*****************************************************************/
function angleConv(deg, inp, out) {
inp = inp.toLowerCase();
out = out.toLowerCase();
const D = 360,
G = 400,
M = 6400,
R = 2 * Math.PI;
// normalazation
let minus = (deg < 0); // boolean
deg = Math.abs(deg);
switch (inp) {
case 'd': deg %= D; break;
case 'g': deg %= G; break;
case 'm': deg %= M; break;
case 'r': deg %= R;
}
// we use an internal conversion to Turns (full circle) here
let t;
switch (inp) {
case 'd': t = deg / D; break;
case 'g': t = deg / G; break;
case 'm': t = deg / M; break;
case 'r': t = deg / R;
}
// converting
switch (out) {
case 'd': t *= D; break;
case 'g': t *= G; break;
case 'm': t *= M; break;
case 'r': t *= R;
}
if (minus) return 0 - t;
return t;
}
// mass testing
let nums = [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1e6],
units = 'dgmr'.split(''),
x, y, z;
for (x = 0; x < nums.length; x++) {
for (y = 0; y < units.length; y++) {
document.write(`
<p>
<b>${nums[x]}<sub>${units[y]}</sub></b><br>
`);
for (z = 0; z < units.length; z++)
document.write(`
= ${angleConv(nums[x], units[y], units[z])}<sub>${units[z]}</sub>
`);
}
}

View file

@ -0,0 +1,38 @@
### Formatting
# Right-justify but do not truncate
def rjustify(n):
tostring | length as $length | if n <= $length then . else " " * (n-$length) + . end;
# Attempt to align decimals so integer part is in a field of width n
def align($n):
tostring
| index(".") as $ix
| if $ix
then if $n < $ix then .
elif $ix then (.[0:$ix]|rjustify($n)) +.[$ix:]
else rjustify($n)
end
else . + ".0" | align($n)
end ;
# number of decimal places ($n>=0)
def fround($n):
pow(10;$n) as $p
| (. * $p | round ) / $p
| tostring
| index(".") as $ix
| ("0" * $n) as $zeros
| if $ix then . + $zeros | .[0 : $ix + $n + 1]
else . + "." + $zeros
end;
def hide_trailing_zeros:
tostring
| (capture("(?<x>[^.]*[.].)(?<y>00*$)") // null) as $capture
| if $capture
then $capture | (.x + (.y|gsub("0"; " ")))
else .
end;
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;

View file

@ -0,0 +1,56 @@
# Normalization as per the task requirements
def mod($y):
(if . < 0 then -$y else 0 end) as $adjust
| $adjust + . - ($y * ((. / $y)|floor));
def pi: (1|atan) * 4;
def d2d: mod(360);
def g2g: mod(400);
def m2m: mod(6400);
def r2r: mod(2*pi);
def d2g: d2d * 400 / 360;
def d2m: d2d * 6400 / 360;
def d2r: d2d * pi / 180;
def g2d: g2g * 360 / 400;
def g2m: g2g * 6400 / 400;
def g2r: g2g * pi / 200;
def m2d: m2m * 360 / 6400;
def m2g: m2m * 400 / 6400;
def m2r: m2m * pi / 3200;
def r2d: r2r * 180 / pi;
def r2g: r2r * 200 / pi;
def r2m: r2r * 3200 / pi;
def f1(a;b;c;d;e): "\(a|lpad(15)) \(b|lpad(15)) \(c|lpad(15)) \(d|lpad(15)) \(e|lpad(15))";
def f2(a;b;c;d;e):
def al: fround(7) | align(10)| hide_trailing_zeros;
"\(a|al) \(b|al) \(c|al) \(d|al) \(e|al)";
def angles: [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000];
def task1:
f1( "degrees"; "normalized degs"; "gradians"; "mils"; "radians"),
(angles[]
| f2(.; d2d; d2g; d2m; d2r)) ;
def task2:
f1("gradians"; "normalized grds"; "degrees"; "mils"; "radians"),
(angles[]
| f2(.; g2g; g2d; g2m; g2r));
def task3:
f1("mils"; "normalized mils"; "degrees"; "gradians"; "radians"),
(angles[]
| f2(.; m2m; m2d; m2g; m2r));
def task4:
f1( "radians"; "normalized rads"; "degrees"; "gradians"; "mils"),
( angles[]
| f2(.; r2r; r2d; r2g; r2m) );
task1, "",
task2, "",
task3, "",
task4

View file

@ -0,0 +1,39 @@
using Formatting
d2d(d) = d % 360
g2g(g) = g % 400
m2m(m) = m % 6400
r2r(r) = r % 2π
d2g(d) = d2d(d) * 10 / 9
d2m(d) = d2d(d) * 160 / 9
d2r(d) = d2d(d) * π / 180
g2d(g) = g2g(g) * 9 / 10
g2m(g) = g2g(g) * 16
g2r(g) = g2g(g) * π / 200
m2d(m) = m2m(m) * 9 / 160
m2g(m) = m2m(m) / 16
m2r(m) = m2m(m) * π / 3200
r2d(r) = r2r(r) * 180 / π
r2g(r) = r2r(r) * 200 / π
r2m(r) = r2r(r) * 3200 / π
fmt(x::Real, width=16) = Int(round(x)) == x ? rpad(Int(x), width) :
rpad(format(x, precision=7), width)
fmt(x::String, width=16) = rpad(x, width)
const t2u = Dict("degrees" => [d2d, d2g, d2m, d2r],
"gradians" => [g2d, g2g, g2m, g2r], "mils" => [m2d, m2g, m2m, m2r],
"radians" => [r2d, r2g, r2m, r2r])
function testconversions(arr)
println("Number Units Degrees Gradians Mils Radians")
for num in arr, units in ["degrees", "gradians", "mils", "radians"]
print(fmt(num), fmt(units))
for f in t2u[units]
print(fmt(f(num)))
end
println()
end
end
testconversions([-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000])

View file

@ -0,0 +1,53 @@
import java.text.DecimalFormat as DF
const val DEGREE = 360.0
const val GRADIAN = 400.0
const val MIL = 6400.0
const val RADIAN = 2 * Math.PI
fun d2d(a: Double) = a % DEGREE
fun d2g(a: Double) = a * (GRADIAN / DEGREE)
fun d2m(a: Double) = a * (MIL / DEGREE)
fun d2r(a: Double) = a * (RADIAN / 360)
fun g2d(a: Double) = a * (DEGREE / GRADIAN)
fun g2g(a: Double) = a % GRADIAN
fun g2m(a: Double) = a * (MIL / GRADIAN)
fun g2r(a: Double) = a * (RADIAN / GRADIAN)
fun m2d(a: Double) = a * (DEGREE / MIL)
fun m2g(a: Double) = a * (GRADIAN / MIL)
fun m2m(a: Double) = a % MIL
fun m2r(a: Double) = a * (RADIAN / MIL)
fun r2d(a: Double) = a * (DEGREE / RADIAN)
fun r2g(a: Double) = a * (GRADIAN / RADIAN)
fun r2m(a: Double) = a * (MIL / RADIAN)
fun r2r(a: Double) = a % RADIAN
fun main() {
val fa = DF("######0.000000")
val fc = DF("###0.0000")
println(" degrees gradiens mils radians")
for (a in listOf(-2.0, -1.0, 0.0, 1.0, 2.0, 6.2831853, 16.0, 57.2957795, 359.0, 399.0, 6399.0, 1000000.0))
for (units in listOf("degrees", "gradiens", "mils", "radians")) {
val (d,g,m,r) = when (units) {
"degrees" -> {
val d = d2d(a)
listOf(d, d2g(d), d2m(d), d2r(d))
}
"gradiens" -> {
val g = g2g(a)
listOf(g2d(g), g, g2m(g), g2r(g))
}
"mils" -> {
val m = m2m(a)
listOf(m2d(m), m2g(m), m, m2r(m))
}
"radians" -> {
val r = r2r(a)
listOf(r2d(r), r2g(r), r2m(r), r)
}
else -> emptyList()
}
println("%15s %8s = %10s %10s %10s %10s".format(fa.format(a), units, fc.format(d), fc.format(g), fc.format(m), fc.format(r)))
}
}

View file

@ -0,0 +1,17 @@
range = { degrees=360, gradians=400, mils=6400, radians=2.0*math.pi }
function convert(value, fromunit, tounit)
return math.fmod(value * range[tounit] / range[fromunit], range[tounit])
end
testvalues = { -2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000 }
testunits = { "degrees", "gradians", "mils", "radians" }
print(string.format("%15s %8s = %15s %15s %15s %15s", "VALUE", "UNIT", "DEGREES", "GRADIANS", "MILS", "RADIANS"))
for _, value in ipairs(testvalues) do
for _, fromunit in ipairs(testunits) do
local d = convert(value, fromunit, "degrees")
local g = convert(value, fromunit, "gradians")
local m = convert(value, fromunit, "mils")
local r = convert(value, fromunit, "radians")
print(string.format("%15.7f %8s = %15.7f %15.7f %15.7f %15.7f", value, fromunit, d, g, m, r))
end
end

View file

@ -0,0 +1,27 @@
-- if you care..
assert(convert(-360,"degrees","degrees") == 0.0)
assert(convert(360,"degrees","degrees") == 0.0)
assert(convert(-400,"gradians","gradians") == 0.0)
assert(convert(400,"gradians","gradians") == 0.0)
assert(convert(-6400,"mils","mils") == 0.0)
assert(convert(6400,"mils","mils") == 0.0)
assert(convert(-2.0*math.pi,"radians","radians") == 0.0)
assert(convert(2.0*math.pi,"radians","radians") == 0.0)
-- if you must..
function d2d(n) return convert(n,"degrees","degrees") end
function d2g(n) return convert(n,"degrees","gradians") end
function d2m(n) return convert(n,"degrees","mils") end
function d2r(n) return convert(n,"degrees","radians") end
function g2d(n) return convert(n,"gradians","degrees") end
function g2g(n) return convert(n,"gradians","gradians") end
function g2m(n) return convert(n,"gradians","mils") end
function g2r(n) return convert(n,"gradians","radians") end
function m2d(n) return convert(n,"mils","degrees") end
function m2g(n) return convert(n,"mils","gradians") end
function m2m(n) return convert(n,"mils","mils") end
function m2r(n) return convert(n,"mils","radians") end
function r2d(n) return convert(n,"radians","degrees") end
function r2g(n) return convert(n,"radians","gradians") end
function r2m(n) return convert(n,"radians","mils") end
function r2r(n) return convert(n,"radians","radians") end

View file

@ -0,0 +1,31 @@
ClearAll[NormalizeAngle, NormalizeDegree, NormalizeGradian, NormalizeMil, NormalizeRadian]
NormalizeAngle[d_, full_] := Module[{a = d},
If[Abs[a/full] > 4,
a = a - Sign[a] full (Quotient[Abs[a], full] - 4)
];
While[a < -full, a += full];
While[a > full, a -= full];
a
]
ClearAll[Degree2Gradian, Degree2Mil, Degree2Radian, Gradian2Degree, Gradian2Mil, Gradian2Radian, Mil2Degree, Mil2Gradian, Mil2Radian, Radian2Degree, Radian2Gradian, Radian2Mil]
NormalizeDegree[d_] := NormalizeAngle[d, 360]
NormalizeGradian[d_] := NormalizeAngle[d, 400]
NormalizeMil[d_] := NormalizeAngle[d, 6400]
NormalizeRadian[d_] := NormalizeAngle[d, 2 Pi]
Degree2Gradian[d_] := d 400/360
Degree2Mil[d_] := d 6400/360
Degree2Radian[d_] := d Pi/180
Gradian2Degree[d_] := d 360/400
Gradian2Mil[d_] := d 6400/400
Gradian2Radian[d_] := d 2 Pi/400
Mil2Degree[d_] := d 360/6400
Mil2Gradian[d_] := d 400/6400
Mil2Radian[d_] := d 2 Pi/6400
Radian2Degree[d_] := d 180/Pi
Radian2Gradian[d_] := d 400/(2 Pi)
Radian2Mil[d_] := d 6400/(2 Pi)
MapThread[Construct, {{Degree2Gradian, Degree2Mil, Degree2Radian,
Gradian2Degree, Gradian2Mil, Gradian2Radian, Mil2Degree,
Mil2Gradian, Mil2Radian, Radian2Degree, Radian2Gradian,
Radian2Mil}, {-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399,
6399, 1000000}}]

View file

@ -0,0 +1,52 @@
import math
import strformat
const Values = [float -2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000]
func d2d(x: float): float {.inline.} = x mod 360
func g2g(x: float): float {.inline.} = x mod 400
func m2m(x: float): float {.inline.} = x mod 6400
func r2r(x: float): float {.inline.} = x mod (2 * Pi)
func d2g(x: float): float {.inline.} = d2d(x) * 10 / 9
func d2m(x: float): float {.inline.} = d2d(x) * 160 / 9
func d2r(x: float): float {.inline.} = d2d(x) * Pi / 180
func g2d(x: float): float {.inline.} = g2g(x) * 9 / 10
func g2m(x: float): float {.inline.} = g2g(x) * 16
func g2r(x: float): float {.inline.} = g2g(x) * Pi / 200
func m2d(x: float): float {.inline.} = m2m(x) * 9 / 160
func m2g(x: float): float {.inline.} = m2m(x) / 16
func m2r(x: float): float {.inline.} = m2m(x) * Pi / 3200
func r2d(x: float): float {.inline.} = r2r(x) * 180 / Pi
func r2g(x: float): float {.inline.} = r2r(x) * 200 / Pi
func r2m(x: float): float {.inline.} = r2r(x) * 3200 / Pi
# Normalizing and converting degrees.
echo " Degrees Normalized Gradians Mils Radians"
echo "———————————————————————————————————————————————————————————————————————————————————"
for val in Values:
echo fmt"{val:15.7f} {d2d(val):15.7f} {d2g(val):15.7f} {d2m(val):15.7f} {d2r(val):15.7f}"
# Normalizing and converting gradians.
echo ""
echo " Gradians Normalized Degrees Mils Radians"
echo "———————————————————————————————————————————————————————————————————————————————————"
for val in Values:
echo fmt"{val:15.7f} {g2g(val):15.7f} {g2d(val):15.7f} {g2m(val):15.7f} {g2r(val):15.7f}"
# Normalizing and converting mils.
echo ""
echo " Mils Normalized Degrees Gradians Radians"
echo "———————————————————————————————————————————————————————————————————————————————————"
for val in Values:
echo fmt"{val:15.7f} {m2m(val):15.7f} {m2d(val):15.7f} {m2g(val):15.7f} {m2r(val):15.7f}"
# Normalizing and converting radians.
echo ""
echo " Radians Normalized Degrees Gradians Mils"
echo "———————————————————————————————————————————————————————————————————————————————————"
for val in Values:
echo fmt"{val:15.7f} {r2r(val):15.7f} {r2d(val):15.7f} {r2g(val):15.7f} {r2m(val):15.7f}"

View file

@ -0,0 +1,34 @@
use strict;
use warnings;
use feature 'say';
use POSIX 'fmod';
my $tau = 2 * 4*atan2(1, 1);
my @units = (
{ code => 'd', name => 'degrees' , number => 360 },
{ code => 'g', name => 'gradians', number => 400 },
{ code => 'm', name => 'mills' , number => 6400 },
{ code => 'r', name => 'radians' , number => $tau },
);
my %cvt;
for my $a (@units) {
for my $b (@units) {
$cvt{ "${$a}{code}2${$b}{code}" } = sub {
my($angle) = shift;
my $norm = fmod($angle,${$a}{number}); # built-in '%' returns only integers
$norm -= ${$a}{number} if $angle < 0;
$norm * ${$b}{number} / ${$a}{number}
}
}
}
printf '%s'. '%12s'x4 . "\n", ' Angle Unit ', <Degrees Gradians Mills Radians>;
for my $angle (-2, -1, 0, 1, 2, $tau, 16, 360/$tau, 360-1, 400-1, 6400-1, 1_000_000) {
print "\n";
for my $from (@units) {
my @sub_keys = map { "${$from}{code}2${$_}{code}" } @units;
my @results = map { &{$cvt{$_}}($angle) } @sub_keys;
printf '%10g %-8s' . '%12g'x4 . "\n", $angle, ${$from}{name}, @results;
}
}

View file

@ -0,0 +1,21 @@
-->
<span style="color: #008080;">constant</span> <span style="color: #000000;">units</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"degrees"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"gradians"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"mils"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"radians"</span><span style="color: #0000FF;">},</span>
<span style="color: #000000;">turns</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">360</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">400</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">6400</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0.5</span><span style="color: #0000FF;">/</span><span style="color: #004600;">PI</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">convert</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">fdx</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tdx</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">*</span><span style="color: #000000;">turns</span><span style="color: #0000FF;">[</span><span style="color: #000000;">fdx</span><span style="color: #0000FF;">],</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">turns</span><span style="color: #0000FF;">[</span><span style="color: #000000;">tdx</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #004600;">PI</span><span style="color: #0000FF;">,</span><span style="color: #000000;">16</span><span style="color: #0000FF;">,</span><span style="color: #000000;">57.2957795</span><span style="color: #0000FF;">,</span><span style="color: #000000;">359</span><span style="color: #0000FF;">,</span><span style="color: #000000;">399</span><span style="color: #0000FF;">,</span><span style="color: #000000;">6399</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1000000</span><span style="color: #0000FF;">}</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" angle unit %9s %9s %9s %9s\n"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">units</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">fdx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">units</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%9g %-8s"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">units</span><span style="color: #0000FF;">[</span><span style="color: #000000;">fdx</span><span style="color: #0000FF;">]})</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">tdx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">units</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" %9g"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">convert</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">fdx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">tdx</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--

View file

@ -0,0 +1,35 @@
PI = 3.141592653589793
TWO_PI = 6.283185307179586
def normalize2deg(a):
while a < 0: a += 360
while a >= 360: a -= 360
return a
def normalize2grad(a):
while a < 0: a += 400
while a >= 400: a -= 400
return a
def normalize2mil(a):
while a < 0: a += 6400
while a >= 6400: a -= 6400
return a
def normalize2rad(a):
while a < 0: a += TWO_PI
while a >= TWO_PI: a -= TWO_PI
return a
def deg2grad(a): return a * 10.0 / 9.0
def deg2mil(a): return a * 160.0 / 9.0
def deg2rad(a): return a * PI / 180.0
def grad2deg(a): return a * 9.0 / 10.0
def grad2mil(a): return a * 16.0
def grad2rad(a): return a * PI / 200.0
def mil2deg(a): return a * 9.0 / 160.0
def mil2grad(a): return a / 16.0
def mil2rad(a): return a * PI / 3200.0
def rad2deg(a): return a * 180.0 / PI
def rad2grad(a): return a * 200.0 / PI
def rad2mil(a): return a * 3200.0 / PI

View file

@ -0,0 +1,354 @@
''' Python 3.6.5 code using Tkinter graphical user interface.
Angles (geometric), normalization and conversion challenge.
User enteres value for angle and selects a unit, then
presses 'Convert' button.
Values for that angle are shown in degrees, grads, mils
and radians.
'''
from tkinter import *
from tkinter import messagebox
import math
class Angle:
def __init__(self, gw):
self.window = gw
self.unit = StringVar()
self.unit.set(' ')
a1 = "(Enter 'Angle' & select 'Unit',"
a2 = "then click 'Convert')"
self.msga = a1 + '\n' + a2
# dictionary of functions to execute depending
# on which radio button was selected:
self.d_to_deg = {'d':self.d2d,
'g':self.g2d,
'm':self.m2d,
'r':self.r2d}
# top frame:
self.top_fr = Frame(gw,
width=600,
height=100,
bg='dodger blue')
self.top_fr.pack(fill=X)
self.hdg = Label(self.top_fr,
text=' Angle Conversion ',
font='arial 22 bold',
fg='navy',
bg='lemon chiffon')
self.hdg.place(relx=0.5, rely=0.5,
anchor=CENTER)
self.close_btn = Button(self.top_fr,
text='Quit',
bd=5,
bg='navy',
fg='lemon chiffon',
font='arial 12 bold',
command=self.close_window)
self.close_btn.place(relx=0.07, rely=0.5,
anchor=W)
self.clear_btn = Button(self.top_fr,
text='Clear',
bd=5,
bg='navy',
fg='lemon chiffon',
font='arial 12 bold',
command=self.clear_screen)
self.clear_btn.place(relx=0.92, rely=0.5,
anchor=E)
# bottom frame:
self.btm_fr = Frame(gw,
width=600,
height=500,
bg='lemon chiffon')
self.btm_fr.pack(fill=X)
self.msg = Label(self.btm_fr,
text=self.msga,
font='arial 16 bold',
fg='navy',
bg='lemon chiffon')
self.msg.place(relx=0.5, rely=0.1,
anchor=CENTER)
self.nbr_fr = LabelFrame(self.btm_fr,
text=' Angle ',
bg='dodger blue',
fg='navy',
bd=4,
relief=RIDGE,
font='arial 12 bold')
self.nbr_fr.place(relx=0.17, rely=0.27,
anchor=CENTER)
self.nbr_ent = Entry(self.nbr_fr,
justify='center',
font='arial 12 bold',
fg='navy',
bg='lemon chiffon',
bd=4,
width=10)
self.nbr_ent.grid(row=0, column=0,
padx=(8,8),
pady=(8,8))
self.su_fr = LabelFrame(self.btm_fr,
text=' Select Unit ',
bg='dodger blue',
fg='navy',
bd=8,
relief=RIDGE,
font='arial 12 bold')
self.su_fr.place(relx=0.48, rely=0.35,
anchor=CENTER)
self.radiod = Radiobutton(self.su_fr,
text='degree',
font='arial 12 bold',
fg='navy',
bg='dodger blue',
variable=self.unit,
value='d')
self.radiod.pack(side='top', anchor='w')
self.radiog = Radiobutton(self.su_fr,
text='gradian',
font='arial 12 bold',
fg='navy',
bg='dodger blue',
variable=self.unit,
value='g')
self.radiog.pack(side='top', anchor='w')
self.radiom = Radiobutton(self.su_fr,
text='mil',
font='arial 12 bold',
fg='navy',
bg='dodger blue',
variable=self.unit,
value='m')
self.radiom.pack(side='top', anchor='w')
self.radior = Radiobutton(self.su_fr,
text='radian',
font='arial 12 bold',
fg='navy',
bg='dodger blue',
variable=self.unit,
value='r')
self.radior.pack(side='top', anchor='w')
self.convert_btn = Button(self.btm_fr,
text='Convert',
width=14,
bd=5,
bg='dodger blue',
fg='navy',
font='arial 12 bold',
command=self.convert)
self.convert_btn.place(relx=0.93, rely=.25,
anchor=E)
self.res_fr = LabelFrame(self.btm_fr,
text=' Results ',
bg='dodger blue',
fg='navy',
bd=8,
width=230,
height=130,
relief=RIDGE,
font='arial 12 bold')
self.res_fr.place(relx=0.48, rely=0.74,
anchor=CENTER)
objh = 20 # widget height
lblw = 80 # label width
valw = 100 # value width
lblx = 15 # x-position of label in frame
valx = 100 # x-position of value in frame
objy = 5 # y-position of widget in frame
self.deg_lbl = Label(self.res_fr,
text=' degrees: ',
anchor=E,
font='"Noto Mono" 12 bold',
fg='navy',
bg='lemon chiffon')
self.deg_lbl.place(x=lblx, y=objy,
height=objh, width=lblw)
self.deg_val = Label(self.res_fr,
text=' ',
anchor=E,
padx = 3,
font='"Noto Mono" 12 bold',
fg='navy',
bg='lemon chiffon')
self.deg_val.place(x=valx, y=objy,
height=objh, width=valw)
objy = objy + objh # next row
self.grd_lbl = Label(self.res_fr,
text=' grads: ',
anchor=E,
font='"Noto Mono" 12 bold',
fg='navy',
bg='lemon chiffon')
self.grd_lbl.place(x=lblx, y=objy,
height=objh, width=lblw)
self.grd_val = Label(self.res_fr,
text=' ',
anchor=E,
padx = 3,
font='"Noto Mono" 12 bold',
fg='navy',
bg='lemon chiffon')
self.grd_val.place(x=valx, y=objy,
height=objh, width=valw)
objy = objy + objh # next row
self.mil_lbl = Label(self.res_fr,
text=' mils: ',
anchor=E,
font='"Noto Mono" 12 bold',
fg='navy',
bg='lemon chiffon')
self.mil_lbl.place(x=lblx, y=objy,
height=objh, width=lblw)
self.mil_val = Label(self.res_fr,
text=' ',
anchor=E,
padx = 3,
font='"Noto Mono" 12 bold',
fg='navy',
bg='lemon chiffon')
self.mil_val.place(x=valx, y=objy,
height=objh, width=valw)
objy = objy + objh # next row
self.rad_lbl = Label(self.res_fr,
text='radians: ',
anchor=E,
font='"Noto Mono" 12 bold',
fg='navy',
bg='lemon chiffon')
self.rad_lbl.place(x=lblx, y=objy,
height=objh, width=lblw)
self.rad_val = Label(self.res_fr,
text=' ',
anchor=E,
padx = 3,
font='"Noto Mono" 12 bold',
fg='navy',
bg='lemon chiffon')
self.rad_val.place(x=valx, y=objy,
height=objh, width=valw)
# process conversion request:
def convert(self):
# edit requested angle and unit:
try:
a = float(self.nbr_ent.get())
except:
self.err_msg('Angle entry must be numeric')
return
u = self.unit.get()
if u not in self.d_to_deg:
self.err_msg('Unit must be selected')
return
# convert request to degrees:
deg = self.d_to_deg[u](a)
# normalize:
self.deg = self.normalize(deg)
# convert to grads, mils, radians
self.grad = self.d2g(self.deg)
self.mil = self.d2m(self.deg)
self.rad = self.d2r(self.deg)
# show results
self.deg_val.config(text=self.format_angle(self.deg))
self.grd_val.config(text=self.format_angle(self.grad))
self.mil_val.config(text=self.format_angle(self.mil))
self.rad_val.config(text=self.format_angle(self.rad))
return
def d2d(self, a):
return a
def g2d(self, a):
return .9 * a
def r2d(self, a):
return 180 * a / math.pi
def m2d(self, a):
return .05625 * a
def normalize(self, a):
if a >= 0:
x = a % 360
else:
x = -(-a % 360)
if x == -0.0:
x = 0.0
return x
def d2g(self, a):
return 10 * a / 9
def d2m(self, a):
return 160 * a / 9
def d2r(self, a):
return math.pi * a / 180
def format_angle(self, a):
return f'{a:.4f}'
def err_msg(self, msg):
messagebox.showerror('Error Message', msg)
return
# restore screen to it's 'initial' state:
def clear_screen(self):
self.nbr_ent.delete(0, 'end')
self.unit.set(' ')
self.deg_val.config(text='')
self.grd_val.config(text='')
self.mil_val.config(text='')
self.rad_val.config(text='')
return
def close_window(self):
self.window.destroy()
# ************************************************
root = Tk()
root.title('ANGLES')
root.geometry('600x600+100+50')
root.resizable(False, False)
a = Angle(root)
root.mainloop()
# ************************************************
## I wish I could show a screenshot of the tkinter window
## to show how the input and output appear, but I don't know
## if that is possible here.
## I have processed all of the suggested angles and the
## results matched those from a few other languages on this
## page.

View file

@ -0,0 +1,53 @@
/*REXX pgm normalizes an angle (in a scale), or converts angles from a scale to another.*/
numeric digits length( pi() ) - length(.) /*use the "length" of pi for precision.*/
parse arg x /*obtain optional arguments from the CL*/
if x='' | x="," then x= '-2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000'
w= 20; w7= w+7 /*W: # dec digits past the dec. point.*/
@deg = 'degrees'; @grd= "gradians"; @mil = 'mils'; @rad = "radians"
# = words(x)
call hdr @deg @grd @mil @rad
do j=1 for #; y= word(x,j)
say shw(y) fmt(d2d(y)) fmt(d2g(y)) fmt(d2m(y)) fmt(d2r(y))
end /*j*/
call hdr @grd @deg @mil @rad
do j=1 for #; y= word(x,j)
say shw(y) fmt(g2g(y)) fmt(g2d(y)) fmt(g2m(y)) fmt(g2r(y))
end /*j*/
call hdr @mil @deg @grd @rad
do j=1 for #; y= word(x,j)
say shw(y) fmt(m2m(y)) fmt(m2d(y)) fmt(m2g(y)) fmt(m2r(y))
end /*j*/
call hdr @rad @deg @grd @mil
do j=1 for #; y= word(x,j)
say shw(y) fmt(r2r(y)) fmt(r2d(y)) fmt(r2g(y)) fmt(r2m(y))
end /*j*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
fmt: _= format(arg(1), 6,w); L= length(_); return left(format(_/1, 6),L) /*align a #*/
shw: _= format(arg(1),12,9); L= length(_); return left(format(_/1,12),L) /* " " "*/
pi: pi= 3.1415926535897932384626433832795028841971693993751058209749445923078; return pi
d2g: return d2d(arg(1)) * 10 / 9 /*convert degrees ───► gradians. */
d2m: return d2d(arg(1)) * 160 / 9 /*convert degrees ───► mils. */
d2r: return d2d(arg(1)) * pi() / 180 /*convert degrees ───► radians. */
g2d: return g2g(arg(1)) * 0.9 /*convert gradians ───► degrees. */
g2m: return g2g(arg(1)) * 16 /*convert gradians ───► mils. */
g2r: return g2g(arg(1)) * pi() * 0.005 /*convert gradians ───► radians. */
m2d: return m2m(arg(1)) * 9 * 0.00625 /*convert mils ───► degrees. */
m2g: return m2m(arg(1)) / 16 /*convert mils ───► gradians. */
m2r: return m2m(arg(1)) * pi() / 3200 /*convert mils ───► radians. */
r2d: return r2r(arg(1)) * 180 / pi() /*convert radians ───► degrees. */
r2g: return r2r(arg(1)) * 200 / pi() /*convert radians ───► gradians. */
r2m: return r2r(arg(1)) * 3200 / pi() /*convert radians ───► mils. */
d2d: return arg(1) // 360 /*normalize degrees ───► a unit circle.*/
g2g: return arg(1) // 400 /*normalize gradians───► a unit circle.*/
m2m: return arg(1) // 6400 /*normalize mils ───► a unit circle.*/
r2r: return arg(1) // (pi() * 2) /*normalize radians ───► a unit circle.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
hdr: parse arg #o #a #b #c .; _= ''; say /* [↓] the header line*/
@n = 'normalized'
say center(#o,23 ) center(@n #o,w7) center(#a,w7 ) center(#b,w7 ) center(#c,w7 )
say center('',23,_) center('',w7, _) center('',w7,_) center('',w7,_) center('',w7,_)
return /* '↑' seperator line.*/

View file

@ -0,0 +1,49 @@
#lang racket
(define (rem n m)
(let* ((m (abs m)) (-m (- m)))
(let recur ((n n))
(cond [(< n -m) (recur (+ n m))]
[(>= n m) (recur (- n m))]
[else n]))))
(define 2.pi (* 2 pi))
(define (deg->deg a) (rem a 360))
(define (grad->grad a) (rem a 400))
(define (mil->mil a) (rem a 6400))
(define (rad->rad a) (rem a 2.pi))
(define (deg->grad a) (grad->grad (* (/ a 360) 400)))
(define (deg->rad a) (rad->rad (* (/ a 360) 2.pi)))
(define (deg->mil a) (mil->mil (* (/ a 360) 6400)))
(define (grad->deg a) (deg->deg (* (/ a 400) 360)))
(define (grad->rad a) (rad->rad (* (/ a 400) 2.pi)))
(define (grad->mil a) (mil->mil (* (/ a 400) 6400)))
(define (mil->deg a) (deg->deg (* (/ a 6400) 360)))
(define (mil->grad a) (grad->grad (* (/ a 6400) 400)))
(define (mil->rad a) (rad->rad (* (/ a 6400) 2.pi)))
(define (rad->deg a) (deg->deg (* (/ a 2.pi) 360)))
(define (rad->grad a) (grad->grad (* (/ a 2.pi) 400)))
(define (rad->mil a) (mil->mil (* (/ a 2.pi) 6400)))
(define (tabulate #:fmt (fmt (λ (v) (~a (exact->inexact v) #:align 'right #:width 15))) head . vs)
(string-join (cons (~a #:width 6 head) (map fmt vs)) " | "))
(define (report-angle a)
(string-join
(list
(tabulate #:fmt (λ (x) (~a x #:width 15 #:align 'center)) "UNIT" "VAL*" "DEG" "GRAD" "MIL" "RAD")
(tabulate "Deg" a (deg->deg a) (deg->grad a) (deg->mil a) (deg->rad a))
(tabulate "Grad" a (grad->deg a) (grad->grad a) (grad->mil a) (grad->rad a))
(tabulate "Mil" a (mil->deg a) (mil->grad a) (mil->mil a) (mil->rad a))
(tabulate "Rad" a (rad->deg a) (rad->grad a) (rad->mil a) (rad->rad a)))
"\n"))
(module+ test
(displayln
(string-join (map report-angle '(-2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000))
"\n\n")))

View file

@ -0,0 +1,29 @@
my @units =
{ code => 'd', name => 'degrees' , number => 360 },
{ code => 'g', name => 'gradians', number => 400 },
{ code => 'm', name => 'mills' , number => 6400 },
{ code => 'r', name => 'radians' , number => tau },
;
my Code %cvt = (@units X @units).map: -> ($a, $b) {
"{$a.<code>}2{$b.<code>}" => sub ($angle) {
my $norm = $angle % $a.<number>
- ( $a.<number> if $angle < 0 );
$norm * $b.<number> / $a.<number>
}
}
say ' Angle Unit ', @units».<name>».tc.fmt('%11s');
for -2, -1, 0, 1, 2, tau, 16, 360/tau, 360-1, 400-1, 6400-1, 1_000_000 -> $angle {
say '';
for @units -> $from {
my @sub_keys = @units.map: { "{$from.<code>}2{.<code>}" };
my @results = %cvt{@sub_keys}».($angle);
say join ' ', $angle .fmt('%10g'),
$from.<name>.fmt('%-8s'),
@results .fmt('%11g');
}
}

View file

@ -0,0 +1,22 @@
sub postfix:<t>( $t ) { my $a = $t % 1 * τ; $t >=0 ?? $a !! $a - τ }
sub postfix:<d>( $d ) { my $a = $d % 360 * τ / 360; $d >=0 ?? $a !! $a - τ }
sub postfix:<g>( $g ) { my $a = $g % 400 * τ / 400; $g >=0 ?? $a !! $a - τ }
sub postfix:<m>( $m ) { my $a = $m % 6400 * τ / 6400; $m >=0 ?? $a !! $a - τ }
sub postfix:<r>( $r ) { my $a = $r % τ; $r >=0 ?? $a !! $a - τ }
sub postfix:«->t» ($angle) { my $a = $angle / τ; ($angle < 0 and $a == -1) ?? -0 !! $a }
sub postfix:«->d» ($angle) { my $a = $angle / τ * 360; ($angle < 0 and $a == -360) ?? -0 !! $a }
sub postfix:«->g» ($angle) { my $a = $angle / τ * 400; ($angle < 0 and $a == -400) ?? -0 !! $a }
sub postfix:«->m» ($angle) { my $a = $angle / τ * 6400; ($angle < 0 and $a == -6400) ?? -0 !! $a }
sub postfix:«->r» ($angle) { my $a = $angle; ($angle < 0 and $a == -τ) ?? -0 !! $a }
for <-2 -1 0 1 2 6.2831853 16 57.2957795 359 399 6399 1000000> -> $a {
say '';
say ' Quantity Unit ', <turns degrees gradians mils radians>.fmt('%15s');
for 'turns', &postfix:«t», 'degrees', &postfix:«d», 'gradians', &postfix:«g»,
'mils', &postfix:«m», 'radians', &postfix:«r»
-> $unit, &f {
printf "%10s %-10s %15s %15s %15s %15s %15s\n", $a, $unit,
|($a.&f->t, $a.&f->d, $a.&f->g, $a.&f->m, $a.&f->r)».round(.00000001);
}
}

View file

@ -0,0 +1,24 @@
module Angles
BASES = {"d" => 360, "g" => 400, "m" => 6400, "r" => Math::PI*2 ,"h" => 24 }
def self.method_missing(meth, angle)
from, to = BASES.values_at(*meth.to_s.split("2"))
raise NoMethodError, meth if (from.nil? or to.nil?)
mod = (angle.to_f * to / from) % to
angle < 0 ? mod - to : mod
end
end
#Demo
names = Angles::BASES.keys
puts " " + "%12s "*names.size % names
test = [-2, -1, 0, 1, 2*Math::PI, 16, 360/(2*Math::PI), 360-1, 400-1, 6400-1, 1_000_000]
test.each do |n|
names.each do |first|
res = names.map{|last| Angles.send((first + "2" + last).to_sym, n)}
puts first + "%12g "*names.size % res
end
puts
end

View file

@ -0,0 +1,76 @@
use std::{
marker::PhantomData,
f64::consts::PI,
};
pub trait AngleUnit: Copy {
const TURN: f64;
const NAME: &'static str;
}
macro_rules! unit {
($name:ident, $value:expr, $string:expr) => (
#[derive(Debug, Copy, Clone)]
struct $name;
impl AngleUnit for $name {
const TURN: f64 = $value;
const NAME: &'static str = $string;
}
);
}
unit!(Degrees, 360.0, "Degrees");
unit!(Radians, PI * 2.0, "Radians");
unit!(Gradians, 400.0, "Gradians");
unit!(Mils, 6400.0, "Mils");
#[derive(Copy, Clone, PartialEq, PartialOrd)]
struct Angle<T: AngleUnit>(f64, PhantomData<T>);
impl<T: AngleUnit> Angle<T> {
pub fn new(val: f64) -> Self {
Self(val, PhantomData)
}
pub fn normalize(self) -> Self {
Self(self.0 % T::TURN, PhantomData)
}
pub fn val(self) -> f64 {
self.0
}
pub fn convert<U: AngleUnit>(self) -> Angle<U> {
Angle::new(self.0 * U::TURN / T::TURN)
}
pub fn name(self) -> &'static str {
T::NAME
}
}
fn print_angles<T: AngleUnit>() {
let angles = [-2.0, -1.0, 0.0, 1.0, 2.0, 6.2831853, 16.0, 57.2957795, 359.0, 399.0, 6399.0, 1000000.0];
println!("{:<12} {:<12} {:<12} {:<12} {:<12} {:<12}", "Angle", "Unit", "Degrees", "Gradians", "Mils", "Radians");
for &angle in &angles {
let deg = Angle::<T>::new(angle).normalize();
println!("{:<12} {:<12} {:<12.4} {:<12.4} {:<12.4} {:<12.4}",
angle,
deg.name(),
deg.convert::<Degrees>().val(),
deg.convert::<Gradians>().val(),
deg.convert::<Mils>().val(),
deg.convert::<Radians>().val(),
);
}
println!();
}
fn main() {
print_angles::<Degrees>();
print_angles::<Gradians>();
print_angles::<Mils>();
print_angles::<Radians>();
}

View file

@ -0,0 +1,78 @@
import Foundation
func normalize(_ f: Double, N: Double) -> Double {
var a = f
while a < -N { a += N }
while a >= N { a -= N }
return a
}
func normalizeToDeg(_ f: Double) -> Double {
return normalize(f, N: 360)
}
func normalizeToGrad(_ f: Double) -> Double {
return normalize(f, N: 400)
}
func normalizeToMil(_ f: Double) -> Double {
return normalize(f, N: 6400)
}
func normalizeToRad(_ f: Double) -> Double {
return normalize(f, N: 2 * .pi)
}
func d2g(_ f: Double) -> Double { f * 10 / 9 }
func d2m(_ f: Double) -> Double { f * 160 / 9 }
func d2r(_ f: Double) -> Double { f * .pi / 180 }
func g2d(_ f: Double) -> Double { f * 9 / 10 }
func g2m(_ f: Double) -> Double { f * 16 }
func g2r(_ f: Double) -> Double { f * .pi / 200 }
func m2d(_ f: Double) -> Double { f * 9 / 160 }
func m2g(_ f: Double) -> Double { f / 16 }
func m2r(_ f: Double) -> Double { f * .pi / 3200 }
func r2d(_ f: Double) -> Double { f * 180 / .pi }
func r2g(_ f: Double) -> Double { f * 200 / .pi }
func r2m(_ f: Double) -> Double { f * 3200 / .pi }
let angles = [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 6399, 1_000_000]
let names = ["Degrees", "Gradians", "Mils", "Radians"]
let fmt = { String(format: "%.4f", $0) }
let normal = [normalizeToDeg, normalizeToGrad, normalizeToMil, normalizeToRad]
let convert = [
[{ $0 }, d2g, d2m, d2r],
[g2d, { $0 }, g2m, g2r],
[m2d, m2g, { $0 }, m2r],
[r2d, r2g, r2m, { $0 }]
]
let ans =
angles.map({ angle in
(0..<4).map({ ($0, normal[$0](angle)) }).map({
(fmt(angle),
fmt($0.1),
names[$0.0],
fmt(convert[$0.0][0]($0.1)),
fmt(convert[$0.0][1]($0.1)),
fmt(convert[$0.0][2]($0.1)),
fmt(convert[$0.0][3]($0.1))
)
})
})
print("angle", "normalized", "unit", "degrees", "grads", "mils", "radians")
for res in ans {
for unit in res {
print(unit)
}
print()
}

View file

@ -0,0 +1,53 @@
import math
import strconv
fn d2d(d f64) f64 { return math.mod(d, 360) }
fn g2g(g f64) f64 { return math.mod(g, 400) }
fn m2m(m f64) f64 { return math.mod(m, 6400) }
fn r2r(r f64) f64 { return math.mod(r, 2*math.pi) }
fn d2g(d f64) f64 { return d2d(d) * 400 / 360 }
fn d2m(d f64) f64 { return d2d(d) * 6400 / 360 }
fn d2r(d f64) f64 { return d2d(d) * math.pi / 180 }
fn g2d(g f64) f64 { return g2g(g) * 360 / 400 }
fn g2m(g f64) f64 { return g2g(g) * 6400 / 400 }
fn g2r(g f64) f64 { return g2g(g) * math.pi / 200 }
fn m2d(m f64) f64 { return m2m(m) * 360 / 6400 }
fn m2g(m f64) f64 { return m2m(m) * 400 / 6400 }
fn m2r(m f64) f64 { return m2m(m) * math.pi / 3200 }
fn r2d(r f64) f64 { return r2r(r) * 180 / math.pi }
fn r2g(r f64) f64 { return r2r(r) * 200 / math.pi }
fn r2m(r f64) f64 { return r2r(r) * 3200 / math.pi }
fn s(f f64) string {
wf := strconv.format_fl(f, strconv.BF_param{
len0: 15
len1: 7
positive: f>=0
}).split('.')
if wf[1] == '0000000' {
return "${wf[0]:7} "
}
mut le := wf[1].len
if le > 7 {
le = 7
}
return "${wf[0]:7}.${wf[1][..le]:-7}"
}
fn main() {
angles := [-2.0, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000]
println(" degrees normalized degs gradians mils radians")
for a in angles {
println('${s(a)} ${s(d2d(a))} ${s(d2g(a))} ${s(d2m(a))} ${s(d2r(a))}')
}
println("\n gradians normalized grds degrees mils radians")
for a in angles {
println('${s(a)} ${s(g2g(a))} ${s(g2d(a))} ${s(g2m(a))} ${s(g2r(a))}')
}
println("\n mils normalized mils degrees gradians radians")
for a in angles {
println('${s(a)} ${s(m2m(a))} ${s(m2d(a))} ${s(m2g(a))} ${s(m2r(a))}')
}
println("\n radians normalized rads degrees gradians mils ")
for a in angles {
println('${s(a)} ${s(r2r(a))} ${s(r2d(a))} ${s(r2g(a))} ${s(r2m(a))}')
}
}

View file

@ -0,0 +1,39 @@
import "/fmt" for Fmt
var d2d = Fn.new { |d| d % 360 }
var g2g = Fn.new { |g| g % 400 }
var m2m = Fn.new { |m| m % 6400 }
var r2r = Fn.new { |r| r % (2*Num.pi) }
var d2g = Fn.new { |d| d2d.call(d) * 400 / 360 }
var d2m = Fn.new { |d| d2d.call(d) * 6400 / 360 }
var d2r = Fn.new { |d| d2d.call(d) * Num.pi / 180 }
var g2d = Fn.new { |g| g2g.call(g) * 360 / 400 }
var g2m = Fn.new { |g| g2g.call(g) * 6400 / 400 }
var g2r = Fn.new { |g| g2g.call(g) * Num.pi / 200 }
var m2d = Fn.new { |m| m2m.call(m) * 360 / 6400 }
var m2g = Fn.new { |m| m2m.call(m) * 400 / 6400 }
var m2r = Fn.new { |m| m2m.call(m) * Num.pi / 3200 }
var r2d = Fn.new { |r| r2r.call(r) * 180 / Num.pi }
var r2g = Fn.new { |r| r2r.call(r) * 200 / Num.pi }
var r2m = Fn.new { |r| r2r.call(r) * 3200 / Num.pi }
var f1 = "$15m $15m $15m $15m $15m"
var f2 = "$15.7g $15.7g $15.7g $15.7g $15.7g"
var angles = [-2, -1, 0, 1, 2, 6.2831853, 16, 57.2957795, 359, 399, 6399, 1000000]
Fmt.print(f1, "degrees", "normalized degs", "gradians", "mils", "radians")
for (a in angles) {
Fmt.print(f2, a, d2d.call(a), d2g.call(a), d2m.call(a), d2r.call(a))
}
f1 = "\n" + f1
Fmt.print(f1, "gradians", "normalized grds", "degrees", "mils", "radians")
for (a in angles) {
Fmt.print(f2, a, g2g.call(a), g2d.call(a), g2m.call(a), g2r.call(a))
}
Fmt.print(f1, "mils", "normalized mils", "degrees", "gradians", "radians")
for (a in angles) {
Fmt.print(f2, a, m2m.call(a), m2d.call(a), m2g.call(a), m2r.call(a))
}
Fmt.print(f1, "radians", "normalized rads", "degrees", "gradians", "mils")
for (a in angles) {
Fmt.print(f2, a, r2r.call(a), r2d.call(a), r2g.call(a), r2m.call(a))
}

View file

@ -0,0 +1,63 @@
def Pi = 3.14159265358979323846, N=12, Tab=9;
func real D2D; real D; return Mod(D, 360.);
func real G2G; real G; return Mod(G, 400.);
func real M2M; real M; return Mod(M, 6400.);
func real R2R; real R; return Mod(R, 2.*Pi);
func real D2G; real D; return 400. * D2D(D) / 360.;
func real D2M; real D; return 6400.* D2D(D) / 360.;
func real D2R; real D; return 2.*Pi* D2D(D) / 360.;
func real G2D; real G; return 360. * G2G(G) / 400.;
func real G2M; real G; return 6400.* G2G(G) / 400.;
func real G2R; real G; return 2.*Pi* G2G(G) / 400.;
func real M2D; real M; return 360. * M2M(M) / 6400.;
func real M2G; real M; return 400. * M2M(M) / 6400.;
func real M2R; real M; return 2.*Pi* M2M(M) / 6400.;
func real R2D; real R; return 360. * R2R(R) / (2.*Pi);
func real R2G; real R; return 400. * R2R(R) / (2.*Pi);
func real R2M; real R; return 6400.* R2R(R) / (2.*Pi);
real Angle; int I;
[Angle:=
[-2., -1., 0., 1., 2., 6.2831853, 16., 57.2957795, 359., 399., 6399., 1000000.];
Format(7, 7);
Text(0, "
Degrees Normalized Gradians Mils Radians
");
for I:= 0 to N-1 do
[RlOut(0, Angle(I)); ChOut(0, Tab);
RlOut(0, D2D(Angle(I))); ChOut(0, Tab);
RlOut(0, D2G(Angle(I))); ChOut(0, Tab);
RlOut(0, D2M(Angle(I))); ChOut(0, Tab);
RlOut(0, D2R(Angle(I))); CrLf(0);
];
Text(0, "
Gradians Normalized Degrees Mils Radians
");
for I:= 0 to N-1 do
[RlOut(0, Angle(I)); ChOut(0, Tab);
RlOut(0, G2G(Angle(I))); ChOut(0, Tab);
RlOut(0, G2D(Angle(I))); ChOut(0, Tab);
RlOut(0, G2M(Angle(I))); ChOut(0, Tab);
RlOut(0, G2R(Angle(I))); CrLf(0);
];
Text(0, "
Mils Normalized Degrees Gradians Radians
");
for I:= 0 to N-1 do
[RlOut(0, Angle(I)); ChOut(0, Tab);
RlOut(0, M2M(Angle(I))); ChOut(0, Tab);
RlOut(0, M2D(Angle(I))); ChOut(0, Tab);
RlOut(0, M2G(Angle(I))); ChOut(0, Tab);
RlOut(0, M2R(Angle(I))); CrLf(0);
];
Text(0, "
Radians Normalized Degrees Gradians Mils
");
for I:= 0 to N-1 do
[RlOut(0, Angle(I)); ChOut(0, Tab);
RlOut(0, R2R(Angle(I))); ChOut(0, Tab);
RlOut(0, R2D(Angle(I))); ChOut(0, Tab);
RlOut(0, R2G(Angle(I))); ChOut(0, Tab);
RlOut(0, R2M(Angle(I))); CrLf(0);
];
]

View file

@ -0,0 +1,15 @@
var [const]
tau=(0.0).pi*2,
units=Dictionary( // code:(name, units in circle)
"d", T("degrees", 360.0), "g",T("gradians",400.0),
"m", T("mills", 6400.0), "r",T("radians", tau) ),
cvtNm="%s-->%s".fmt,
cvt= // "d-->r":fcn(angle){}, "r-->d":fcn(angle){} ...
Walker.cproduct(units.keys,units.keys).pump(Dictionary(),fcn([(a,b)]){
return(cvtNm(a,b), // "d-->r"
'wrap(angle){ angle=angle.toFloat();
u:=units[a][1];
(angle%u)*units[b][1] / u
})
})
;

View file

@ -0,0 +1,12 @@
codes:=units.keys;
println(" Angle Unit ",
codes.apply(fcn(k){ units[k][0] }).apply("%11s".fmt).concat(" "));
foreach angle in (T(-2.0,-1, 0, 1, 2, tau, 16, 360.0/tau, 360-1, 400-1, 6400-1, 1_000_000)){
println();
foreach from in (codes){
subKeys:=codes.apply(cvtNm.fp(from)); // ("d-->d","d-->g","d-->m","d-->r")
r:=subKeys.pump(List,'wrap(k){ cvt[k](angle) });
println("%10g %-8s %s".fmt(angle,units[from][0],
r.apply("%12g".fmt).concat(" ")));
}
}