If you look up Angle in the Wikipedia, it claims that there are four (4) methods of measuring angles: Degrees, Radians, Turns, and Gons. But they are really five (5) and that is BAM or Binary Angular Measurement.
If we get rid of Turns, and Gons. That leaves three (3): Degrees, Radians, BAM. Only Radians and Degrees units of measurement do well with Floating Point math. But when we use BAMs its BAM32 or BAM16 and they are Fixed Point Math. So I will show you Degrees to Radian back to Degrees and will show you the math behind a BAM (Not Fixed Point).
SSR Engineering, Inc. "BAMs are used to represent an angular measure; there are 65,535 BAMs per 360°. An angle provided in BAMs can be converted to degrees by the following relationship:" |
Angle (Degrees) = (360 / 65,535) * Angle (BAMs) |
, You can re-write this as follows to make this universal: where Angle, Bams are variables where n represents the power of 2 Angle = (360 / 2**(n-1)) * Bams
Therefore you can rewrite this into a function:
typedef int degrees; degrees Bams2degrees( double Bans, int n){ return (360/ pow(2,(n-1)) * Bams); } |
This is written in ANSI C. I have typedef both Degrees and Radians, to make the library more readable.
typedef double Degrees;
typedef double Radians;
Radians <> Degrees | Knots | Nautical Miles | DMS <> Degrees |
---|---|---|---|
// Radians 2 Degrees Degrees rad2d( Radians rad ) { | // Knots 2 Degrees double kn2d( double knots ) { return( knots/60 );} | // Nautical Miles 2 Degrees Degrees nm2d( double d ){ return( d * pi/180.0 * 60.0 );} | // dms2d should take any struct of type dms_s and convert to degrees double dms2d( struct dms_s DMS) { Degrees d; |
// Degrees 2 Radians Radians d2rad( Degrees d ) { return( d * pi/180.0 );} | // Knots 2 MPH double kn2mph( double knots ){ return( d2rad( kn2d( knots )));} | // Degrees 2 Nautical Miles double d2nm( Degrees d ) { | |
Note that the C Math Library does not have pi defined: pi = atan2(1,1) *4;
struct dms_s { Degrees deg; char hemisphere; // This is a hold over from Perl and not used };
struct location_s { char ID[5]; // IDs are 4 letters long + trailing \n" struct dms_s NS; struct dms_s EW; double alt; // Station altitude. in feet };
struct DMS_s { double D; // Degrees double M; // Minutes double S; // Seconds } DMS; | // Nautical Miles 2 Standard Mile double nm2sm( double nm ) { return( nm * 1.151 );} | // d2dms should take a decimal angle and convert it to any struct of type dms_s void d2dms( Degrees d ){ int s; // the +0.5 is to get rid of the rounding errors. // there are 3600 seconds in one degree s = (int)(d*36000000+0.5); DMS.S = s%600000/10000.0; s = s/600000.0; DMS.M = s%60; s = s/60; // the %360 is to make sure that we don't report 360 degrees. DMS.D = s%360; return;} | |
// Radians 2 Nautical Miles Radians2nm( Radians rad ){ return( rad * 3437.7387 );} |
I have included the following information for a .h or header file.
Description of Functions | Function header file information |
---|---|
Degrees to: | |
Degrees 2 DMS | void d2dms( Degrees d ); |
Degrees 2 Nautical Miles | double d2nm( Degrees d ); |
Degrees 2 Radians | Radians d2rad( Degrees d ); |
DMS 2 Dregees | double dms2d( struct dms_s DMS); |
Knots to: | |
Knots 2 Degrees | double kn2d( double knots ); |
Knots 2 MPH | double kn2mph( double knots ); |
Nautical Miles to: | |
Nautical Miles 2 Degrees | Degrees nm2d( double d ); |
Nautical Miles 2 Standard Mile | double nm2sm( double nm ); |
Radians to: | |
Radians 2 Degrees | Degrees rad2d( Radians rad ) |
Radians 2 Nautical Mile | Radians2nm( Radians rad ); |
I have included the following description of a BAM. This is what a BAM16 is. You can create BAM32 with which you can describe any location on Earth with the size of a postage stamp.
Real Time Systems Design And Analysis
Chapter 7.5.3. - Binary Angular Measure
Another type of scaled number is based on the property that adding 180o to any
angle is analogous to taking its two’s complement. This technique, called binary angular measurement (BAM) works as follows.
Consider the LSB of an n-bit word to be 2n−1 · 180 degrees with the most significant bit (MSB) = 180 degrees.
The range of any angle θ represented this way is 0 ≤ θ ≤ 360 − 180 · 2(n−1)
degrees. A 16-bit BAM word is shown in Figure 7.6. For more accuracy, BAM can be extended to two more words.
Each n-bit word has a maximum value of: 2n - 2-(n−1) · 180o = 360o - LSB
with granularity: 2-(n−1) · 180o = LSB
Consider the 16-bit BAM word: 0000 0000 10100 110
Its binary angular measurement is 166 · 180o · 2−15 = 0.9118o.
180 | 90 | 45 | 22.5 | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | 180 · 2-14 | 180 · 2-15 |
Figure 7.6 16 bit Binary Angular Mesurement word [Lapante] |
BAM can be added and subtracted together and multiplied and divided by constants as if they were unsigned integers, and converted at the last stage to produce floating-point results.
It is easy to show that the overflow condition for BAM numbers presents no problem as the angle simply wraps around to 0.
BAM is frequently used in navigation software, robotic control, and in conjunction with digitizing imaging devices.