Shop OBEX P1 Docs P2 Docs Learn Events
Accessing SIN/COS tables in SPIN — Parallax Forums

Accessing SIN/COS tables in SPIN

JavalinJavalin Posts: 892
edited 2008-05-21 17:17 in Propeller 1
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

Comments

  • Ken PetersonKen Peterson Posts: 806
    edited 2008-05-16 16:20
    The Floating Point object on OBEX has the sin function included.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
  • Mike GreenMike Green Posts: 23,101
    edited 2008-05-16 16:29
    Here on Graham Stabler's Good Thread Index, follow link to Propeller Guts Download: http://forums.parallax.com/showthread.php?p=609066.
  • JavalinJavalin Posts: 892
    edited 2008-05-17 11:08
    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 AllenTracy Allen Posts: 6,660
    edited 2008-05-17 19:11
    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
  • AribaAriba Posts: 2,685
    edited 2008-05-17 19:38
    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[noparse][[/noparse]angle]
      if z
        s := -s                    ' return sin = -$FFFF..+$FFFF
    
    



    Andy
  • JavalinJavalin Posts: 892
    edited 2008-05-18 06:48
    Hi Andy, Tracy,

    Thanks!!!!! smile.gif

    James
  • JavalinJavalin Posts: 892
    edited 2008-05-20 12:37
    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
  • AribaAriba Posts: 2,685
    edited 2008-05-20 15:32
    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[noparse][[/noparse]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
  • JavalinJavalin Posts: 892
    edited 2008-05-20 18:58
    Thanks Andy!
  • JavalinJavalin Posts: 892
    edited 2008-05-21 14:32
    Andy,

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

    James
  • JavalinJavalin Posts: 892
    edited 2008-05-21 17:06
    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[noparse][[/noparse]$E000 + y]              
        1 : result := word[noparse][[/noparse]$F000 - y]               ' 2049 angles, 16 bit sin(angle) values corresponding 0 to 90 degrees. 
        2 : result := -word[noparse][[/noparse]$E000 + y]              ' the same table is folded over and mirrored for all 360 degrees
        3 : result := -word[noparse][[/noparse]$F000 - y]              ' value returned in the range of -$ffff to +$ffff
      return result
    

    Post Edited (Javalin) : 5/21/2008 5:11:26 PM GMT
  • AribaAriba Posts: 2,685
    edited 2008-05-21 17:08
    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[noparse][[/noparse]angle]
      if z
        s := -s
      return (s*range)~>16     ' return sin = -range..+range
    
    PUB cos(degree,range)
      return sin(degree+90,range)
    
    



    Andy
  • JavalinJavalin Posts: 892
    edited 2008-05-21 17:17
    AH! Eureka! I gettit!

    Thanks!

    james
Sign In or Register to comment.