;-----------------------------
; From: Joe Koss
; Subject: Sin/Cos Table
Q.
I want to start to do some grafix programing and to do what I want I
need SIN/COS functions. The best way to do this is to generate a
table of predefined variables. I saw that some programs use Integers
in SIN/COS table. Can somebody explain to me how do I convert real
values of SIN/COS functions into integers and how I use them later.
A.
The technique is called Fixed Point .. and it is actually very simple ..
Tradition SIN and COS functions return a value from -1 to +1 .. using
some form of floating point storage .. since handling floating point in
assembly is not only tedious, but defeats the purpose of assembly unless
you require a mathco .. a way is needed to do all calculations in
integer ..
The best way to teach someone Fixed Point IMHO is to just show them some
logical steps that work because fixed point works (with rounding errors
and all that)
Ordinarily: s = sin(n)*v
Using fixed: s = integer(sin(n)*256)*v/256
S will have the same value (less the floating point portion) in both
examples .. 256 would be the constant that defines the accuracy of the
fixed point method
if sin(n) = .5 and v = 100 then:
s = 50 in the first equation and:
s = 50 in the second equation too
the second equation unrolls to:
(.5 * 256) * 100 / 256 =
128 * 100 / 256 =
12800 / 256 =
50
In assembly .. you generally don't store floating point values -at all-
.. instead the sin function is PRE-calculated and multiplied by 256 (256
is my choice, any # can be used as long as it is used with both the
multiplication and division)
256 gives you 9-bit accuracy .. while 32768 gives you 16-bit accuracy
--
On another forseable situation you may have problems with: SIN typically
takes input in radians .. there is no good reason for this beyond being
a hardcore mathemetician .. you can give input in any unit you wish ..
I generally spread out my SIN function into 256 steps (instead of
passing in a value from 0 to MaxRadian I pass in a value from 0 to 255)
To create such a table in qbasic:
open "mytable.dw" for output as #1
for n = 0 to 255 : print #1, " dw ";int(sin(n*3.1415/128)*256) : next
close
note that in the qbasic code: 256 needs to be used in the division in
your asm code when using the table (it is the same 256 as in the fixed
point examples) that is created .. you can changed 256 to just about
anything .. the larger it is .. the more accuracy you have.