PDA

View Full Version : Accessing SIN/COS tables in SPIN



Javalin
05-16-2008, 11: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-17-2008, 12:20 AM
The Floating Point object on OBEX has the sin function included.

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

Mike Green
05-17-2008, 12:29 AM
Here on Graham Stabler's Good Thread Index, follow link to Propeller Guts Download: http://forums.parallax.com/showthread.php?p=609066.

Javalin
05-17-2008, 07: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, 03:11 AM
I had posted a tutorial in the Spin Code Examples for Beginners thread, here...
http://forums.parallax.com/showthread.php?p=606978

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

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

Ariba
05-18-2008, 03: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, 02:48 PM
Hi Andy, Tracy,

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

James

Javalin
05-20-2008, 08: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, 11: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, 02:58 AM
Thanks Andy!

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

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

James

Javalin
05-22-2008, 01: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, 01: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

PUB circle(x,y,radius) | i
repeat i from 0 to 360 'draw circle
term.plot(x+sin(i,radius), y+cos(i,radius))


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, 01:17 AM
AH! Eureka! I gettit!

Thanks!

james