PDA

View Full Version : Accessing SIN/COS tables in SPIN

Javalin
05-16-2008, 10:13 PM
Hello all,

Is there some example code available for accessing the sine/cosine tables via SPIN?

I've looked in the manual, and some of the float examples/library's

Particuarly I am after SIN functions

Cheers

James

Ken Peterson
05-16-2008, 11:20 PM
The Floating Point object on OBEX has the sin function included.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔

Mike Green
05-16-2008, 11:29 PM

Javalin
05-17-2008, 06:08 PM
Thanks Mike - i'd seen this - so I assume its a write-your-own. Watch this space I guess.

Ken - The floating point object is ASM only.....

Cheers both,

James

Tracy Allen
05-18-2008, 02:11 AM
I had posted a tutorial in the Spin Code Examples for Beginners thread, here...

There are a couple of versions, both spin and asm.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Tracy Allen
www.emesystems.com (http://www.emesystems.com)

Ariba
05-18-2008, 02:38 AM
Here is a straight forward conversion from the ASM code in Propeller Guts to Spin:

PUB sin(angle) : s | c,z
c := angle & \$800 'angle: 0..8192 = 360°
z := angle & \$1000
if c
angle := -angle
angle |= \$E000>>1
angle <<= 1
s := word[angle]
if z
s := -s ' return sin = -\$FFFF..+\$FFFF

Andy

Javalin
05-18-2008, 01:48 PM
Hi Andy, Tracy,

Thanks!!!!! http://forums.parallax.com/images/smilies/smile.gif

James

Javalin
05-20-2008, 07:37 PM
Tracy,

Couple of possibly silly questions if I may!

1) If I am passing an angle in degrees to the "fullsine" function - do I need to * 22 to get the 0-8192 = 0-360 resolution? I guess so?

2) Is there an easy way of converting the 2's complement output to a decimal distance (+ or -) ??

My Math is rubbish - sorry!

Cheers,

James

Ariba
05-20-2008, 10:32 PM
This slighty extended code fom above shows how to convert degree and output range:

PUB sin(degree, range) : s | c,z,angle
angle := (degree*91)~>2 ' *22.75
c := angle & \$800
z := angle & \$1000
if c
angle := -angle
angle |= \$E000>>1
angle <<= 1
s := word[angle]
if z
s := -s
return (s*range)~>16 ' return sin = -range..+range

Andy

Post Edited (Ariba) : 5/20/2008 3:38:55 PM GMT

Javalin
05-21-2008, 01:58 AM
Thanks Andy!

Javalin
05-21-2008, 09:32 PM
Andy,

Sorry - Im not sure what the range parameter here is doing? Can you give an example?

James

Javalin
05-22-2008, 12:06 AM
Ok - so degree's (he,he) of success:

Using Tracy's fullsine function to find the opposite on a triangle, I do the following and I get:

ˇ "result a=682 hyp=5 sine=44 opp=220"

Sure Im doing something really stupid but alsoˇreally struggling to get my head around this one.

According to excel (and my drawing) I should get:

ˇ Hyp = 6 (actually 5.8 but rounded)
ˇ Sineˇ= 0.515 ish
ˇˇOpposite is 3.

Cheers all

James

' work out the Hypot
distX := 3
distY := 5
mdLatDistance := ^^((distX*distX)+(distY*distY))

' angle is 31 degree's. so my Opposite should be 3 ish
angle1 := 31 * 22
mdLatSine := fullsine(||angle1) / 728
mdLatResult := mdLatSine * mdLatDistance

' debug the results
debug.str(string("result a="))
debug.dec(angle1)
debug.str(string(" hyp="))
debug.dec(mdLatDistance)
debug.str(string(" sine="))
debug.dec(mdlatsine)
debug.str(string(" opp="))
debug.dec(mdlatresult)
debug.putc(13)

' the following PRI takes the angle as input and looks up the sine of the angle in the HUB rom sine table
' The input angle is 0 to 8181 corresponding to 0 to 360 degrees or 0 to 2 pi radians
' The result is a twos complement number in the range of +/- 65535, representing + and minus 1.
PRI fullsine(x) | y, q ' x is 0 to 2^13 (0 to 8191) for 0 to 360 degrees
q := x >> 11 ' two highest bits of 13 are the quadrant, 0, 1, 2 or 3
y := (x & \$7ff) << 1 ' 0 to 90- degrees, are contained in 11 bits, shift left one for Word offset
' this is the address offset into the sine table in hub rom
' note: the parentheses are important for operator precedence
case q ' select quadrant 0,1,2,3
0 : result := word[\$E000 + y]
1 : result := word[\$F000 - y] ' 2049 angles, 16 bit sin(angle) values corresponding 0 to 90 degrees.
2 : result := -word[\$E000 + y] ' the same table is folded over and mirrored for all 360 degrees
3 : result := -word[\$F000 - y] ' value returned in the range of -\$ffff to +\$ffff
return result

Post Edited (Javalin) : 5/21/2008 5:11:26 PM GMT

Ariba
05-22-2008, 12:08 AM
Normally the result of a sin function is in the range -1..+1, but if you work with integers you need a bigger range.
with the function above: sin(x,1000) gives a result from -1000 to +1000, sin(x,256) results in -256..+256

with concrete numbers:
sin(0,1000) = 0, sin(45,1000) = 707, sin(90,1000) = 1000 and so on...

Here is an example that uses sin and cos to draw circles on PropTerminal:

{{ Draw a Circle on PropTerminal }}

CON _clkmode = xtal1 + pll16x
_xinfreq = 5_000_000

OBJ
term : "PC_Interface"

PUB Main
term.start(31,30) 'start the interface
repeat until term.abs_x > 0 'wait until mouse over Terminal

circle(100,50,30)
circle(150,80,50)
circle(200,20,10)

repeat

repeat i from 0 to 360 'draw circle

PUB sin(degree, range) : s | c,z,angle
angle := (degree*91)~>2 ' *22.75
c := angle & \$800
z := angle & \$1000
if c
angle := -angle
angle |= \$E000>>1
angle <<= 1
s := word[angle]
if z
s := -s
return (s*range)~>16 ' return sin = -range..+range

PUB cos(degree,range)
return sin(degree+90,range)

Andy

Javalin
05-22-2008, 12:17 AM
AH! Eureka! I gettit!

Thanks!

james