Binary Degrees

Jeremy Leach

Senior Member
This is just a little alternative way of working with angles and Sin and Cos....

I'm working with vectors and typically you have to work out the X and Y components of a Vector, where X = VSinA and Y = VCosA

On the picaxes that support Sin and Cos, the angle argument is in degrees. However, code-wise I feel it's far easier to work in 0 to 256 ('binary degrees')instead of 0 to 360. If you are increasing or decreasing an angle it will 'wrap around' simply using binary degrees.

Also, to get best accuracy when performing vector maths, I think it's handy if Sin and Cos are expressed as N/255, where N is a number from a lookup table.

So, for instance, X = VSinA = V * N /255

If V is a byte value and N is a byte value then this calculation will never overflow in picaxe maths, but it also gets maximum accuracy without getting into 32 bit maths etc.

I call these N values Sin255 and Cos255.

Here's a 64 byte EEPROM lookup for the Sin255 values. (0 to 64 binary degrees = 0 to 90 normal degrees).
Code:
EEPROM 0,(0,6,13,19,25,31,37,44,50,56,62,68,74,80,86,92,98,103,109,115,120,126,131,136,142,147,152,157,162,
167,171,176,180,185,189,193,197,201,205,208,212,215,219,222,225,228,231,233,236,238,240,242,244,246,247,
249,250,251,252,253,254,254,255,255,255)
So to obtain the Sin255 of a binary angle, just do:
Code:
Read BinAngle,Sin255
In degrees, SinA = Cos(90-A)
So in binary degrees, SinA = Cos(64 - A)

So to obtain the Cos of a binary angle, just do:
Code:
Temp = 64 - BinAngle
Read Temp,Cos255
Example:
Code:
BinAngle = 20
Vector = 88
 
Read BinAngle,Sin255
Temp = 64 - BinAngle
Read Temp,Cos255
 
Xcomponent = 88 * Sin255 /255
Ycomponent = 88 * Cos255/255
It's just my take on things though !
 
Last edited:

BeanieBots

Moderator
I think you make a very valid point Jez.
Many compass modules already offer a "256 degree circle" for much the same reasoning.
 

Jeremy Leach

Senior Member
Yep, it's obvious really, but thought I'd make the point ;) Sometimes we just get so used to numbering systems we forget that they are all invented and we can use whatever is best to get the job done !

Actually, I'm going one further in my own Vector maths ...

Instead of Sin255, I'm using Sin65536 - with a 128 byte lookup table (64 words).

So XComponent = V * N/65536
Where N is the lookup value Word, and V is a Word.

V*N can obviously overflow, but if we think of the result as high and low word:
V*N = (MSW * 65536) + LSW
Therefore V*N/65536 = MSW + (LSW/65536) = MSW (whole part only)

So in code...
Code:
CalcVectorComponents:
    Index = BinAngle * 2
    Read Index,Word Sin65536
    Index= 128 - Index
    Read Index, Word Cos65536
    XComponent = V ** Sin65536 
    YComponent = V ** Cos65536
Return
One point about this method though .... N should be 65536 for 90 degrees (64 binary degrees). But we can't store 65536 in a word, so the lookup table sets this to 65535 instead. The error in the calculated component is insignificant though (actually = V/65536 which is always <1).

If anyone's interested, here's the 128 byte EEPROM lookup table of Sin65536 values, in LSW MSW pairs:
Code:
EEPROM 0,(0,0,72,6,144,12,213,18,24,25,86,31,144,37,196,43,241,49,23,56,52,62,71,68,80,74,77,80,62,86,34,92,248,97,190,103,
116,109,26,115,173,120,47,126,156,131,246,136,58,142,104,147,128,152,128,157,104,162,54,167,235,171,134,176,5,
181,104,185,175,189,216,193,228,197,209,201,159,205,77,209,219,212,72,216,148,219,190,222,198,225,170,228,108,
231,10,234,131,236,217,238,9,241,20,243,250,244,186,246,84,248,200,249,21,251,59,252,59,253,19,254,196,254,78,255,
177,255,236,255,255,255)
 
Last edited:
Top