Jump to content
Sign in to follow this  
w1k

Action! - sin/cos

Recommended Posts

Hello, where can i found action! support sin/cos functions? thank you

Share this post


Link to post
Share on other sites

Hello, where can i found action! support sin/cos functions? thank you

Greetings, I don't know anything about action! but since you've not had any replies yet, I thought I might post this.

Sorry, it's a bit technical and assembly based, hopefully someone with more action! experience can help you out, until then here is some info.

In my limited experience, the most common implementation of sin/cos functions are through look-up tables.

In one of my programs that's how I implemented it. I used a domain of 0-63 which would coincide with 0-360 degrees. Some programs may require more precision, in my case this was acceptable.

I used a calculator program to pre-calculate the values, I saved my worksheet:

0-63 degrees sine          cosine      0-63degrees  sine         cosine
0    0       0             1           32  180.000   0           -1
1    5.625   0.09801714    0.99518473  33  185.625  -0.09801714  -0.99518473
2    11.250  0.19509032    0.98078528  34  191.250  -0.19509032  -0.98078528
3    16.875  0.29028468    0.95694034  35  196.875  -0.29028468  -0.95694034
4    22.500  0.38268343    0.92387953  36  202.500  -0.38268343  -0.92387953
5    28.125  0.47139674    0.88192126  37  208.125  -0.47139674  -0.88192126
6    33.750  0.55557023    0.83146961  38  213.750  -0.55557023  -0.83146961
7    39.375  0.63439328    0.77301045  39  219.375  -0.63439328  -0.77301045
8    45.000  0.70710678    0.70710678  40  225.000  -0.70710678  -0.70710678
9    50.625  0.77301045    0.63439328  41  230.625  -0.77301045  -0.63439328
10   56.250  0.83146961    0.55557023  42  236.250  -0.83146961  -0.55557023
11   61.875  0.88192126    0.47139674  43  241.875  -0.88192126  -0.47139674
12   67.500  0.92387953    0.38268343  44  247.500  -0.92387953  -0.38268343
13   73.125  0.95694034    0.29028468  45  253.125  -0.95694034  -0.29028468
14   78.750  0.98078528    0.19509032  46  258.750  -0.98078528  -0.19509032
15   84.375  0.99518473    0.09801714  47  264.375  -0.99518473  -0.09801714
16   90.000  1             0           48  270.000  -1            0
17   95.625  0.99518473   -0.09801714  49  275.625  -0.99518473   0.09801714
18  101.250  0.98078528   -0.19509032  50  281.250  -0.98078528   0.19509032
19  106.875  0.95694034   -0.29028468  51  286.875  -0.95694034   0.29028468
20  112.500  0.92387953   -0.38268343  52  292.500  -0.92387953   0.38268343
21  118.125  0.88192126   -0.47139674  53  298.125  -0.88192126   0.47139674
22  123.750  0.83146961   -0.55557023  54  303.750  -0.83146961   0.55557023
23  129.375  0.77301045   -0.63439328  55  309.375  -0.77301045   0.63439328
24  135.000  0.70710678   -0.70710678  56  315.000  -0.70710678   0.70710678
25  140.625  0.63439328   -0.77301045  57  320.625  -0.63439328   0.77301045
26  146.250  0.55557023   -0.83146961  58  326.250  -0.55557023   0.83146961
27  151.875  0.47139674   -0.88192126  59  331.875  -0.47139674   0.88192126
28  157.500  0.38268343   -0.92387953  60  337.500  -0.38268343   0.92387953
29  163.125  0.29028468   -0.95694034  61  343.125  -0.29028468   0.95694034
30  168.750  0.19509032   -0.98078528  62  348.750  -0.19509032   0.98078528
31  174.275  0.099753915  -0.99501214  63  354.375  -0.09801714   0.99518473

I then encoded those values in binary in my assembler program:

sinlow
               .byte ~00000000
               .byte ~00011001
               .byte ~00110010
               .byte ~01001010
               .byte ~01100010
               .byte ~01111001
               .byte ~10001110
               .byte ~10100010
               .byte ~10110101
               .byte ~11000110
               .byte ~11010101
               .byte ~11100010
               .byte ~11101101
               .byte ~11110101
               .byte ~11111011
               .byte ~11111111
               .byte ~00000000
               .byte ~11111111
               .byte ~11111011
               .byte ~11110101
               .byte ~11101101
               .byte ~11100010
               .byte ~11010101
               .byte ~11000110
               .byte ~10110101
               .byte ~10100010
               .byte ~10001110
               .byte ~01111001
               .byte ~01100010
               .byte ~01001010
               .byte ~00110010
               .byte ~00011001
               .byte ~00000000
               .byte ~11100111
               .byte ~11001110
               .byte ~10110110
               .byte ~10011110
               .byte ~10000111
               .byte ~01110010
               .byte ~01011110
               .byte ~01001011
               .byte ~00111010
               .byte ~00101011
               .byte ~00011110
               .byte ~00010011
               .byte ~00001011
               .byte ~00000101
               .byte ~00000001
               .byte ~00000000
               .byte ~00000001
               .byte ~00000101
               .byte ~00001011
               .byte ~00010011
               .byte ~00011110
               .byte ~00101011
               .byte ~00111010
               .byte ~01001011
               .byte ~01011110
               .byte ~01110010
               .byte ~10000111
               .byte ~10011110
               .byte ~10110110
               .byte ~11001110
               .byte ~11100111
sinhigh
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000001
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~00000000
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111
               .byte ~11111111

I only encoded the values for sin, because if you look at the table above, you can get cos values from the sin table by manipulating the look-up index. They are just shifted over. In my case this is how I did it, shifting the index over 48 spots, and wrapping it:

               ; x = sin(playerangle)
               ldx     playerangle
               lda     sinlow,x
               sta     workbytes
               lda     sinhigh,x
               sta     workbytes+1

               <snip>

               ; y = cos(playerangle) = sin((playerangle+48)&63)
               txa
               clc
               adc     #48
               and     #63
               tax
               lda     sinlow,x
               sta     workbytes
               lda     sinhigh,x
               sta     workbytes+1

I am sure there are better/more efficient ways to do this, and it might not help anyway as you are using action!. Either way, good luck, I hope you find something that works.

Share this post


Link to post
Share on other sites

You could have either A. better resolution (0-90 in 1 degree steps) or B. a smaller table (only 16 records) if you just went from 0 to 90 degrees and calculated reference angles, then adding the + or - based on quadrant.

Share this post


Link to post
Share on other sites

Hello, where can i found action! support sin/cos functions? thank you

Greetings, I don't know anything about action! but since you've not had any replies yet, I thought I might post this.

Sorry, it's a bit technical and assembly based, hopefully someone with more action! experience can help you out, until then here is some info.

In my limited experience, the most common implementation of sin/cos functions are through look-up tables.

In one of my programs that's how I implemented it. I used a domain of 0-63 which would coincide with 0-360 degrees. Some programs may require more precision, in my case this was acceptable.

...

I am sure there are better/more efficient ways to do this, and it might not help anyway as you are using action!. Either way, good luck, I hope you find something that works.

Actually, this is not quite the common implementation. Modern code uses a polynomial approximation, using a minimax-polynomial of sin and cos (minimizing the maximal error over an interval) and the functional equation (periodicity) of sin and cos. Atari Basic uses a pretty stupid Taylor approximation, which is also a polynomial, but isn't very precise. It is slower than necessary, and less precise than possible.

 

A pretty traditional way that uses a lookup table, requires only additions and shifts but is considerably more precise than a direct lookup is the CORDIC algorithm. You'll find it explained at Wikipedia, there to compute the arcus tangens (its traditional approach), but similar approaches are possible for sin and cos. It's the type of code you found in most pocket calculators.

 

Greetings,

Thomas

Share this post


Link to post
Share on other sites

Depending on what you are after (speed, precision, memory used, etc), your technique will vary.

One of my 8 bit favorites was cutting a circle into 256 angles, and pre-calculating a table for each of those "angles", you can then use the angle with the 6502's indexing modes to quickly get your value. fun stuff

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...