### Author Topic: Bullet trig questions  (Read 3052 times)

0 Members and 1 Guest are viewing this topic.

#### LemonDrop

• LV2 Member (Next: 40)
• Posts: 26
• Rating: +4/-0
##### Bullet trig questions
« on: November 03, 2013, 01:41:58 am »
So I have been trying to make a bullet movement system based off a concept like this:

(I am pretty sure this math is correct)

The inverse tangent function makes sense with how it returns a number between 0-255 but I don't really get how the sine and cosine ones work. They accept the same angle the arctan one outputs, but then they output a value between -127 to 127 which is odd. Like I guess that 127 is supposed to represent the value 1 and -127 as -1, but I don't know how I would make a conversion like that inside code.

Heres what I was working on:
(X and Y are firing coordinates and W and Z are the target coordinates (x and y respectively).
Code: [Select]
If getKey(27) and (R=0) and (B<10) .MAKE NEW BULLET 22->R B+1->B*6+50+L1->I Y->{I} X->{I-1} .SET SIGNS / WIDTH / HEIGHT (1 being positive, 0 being negitive) If Y>Z 0->{I-2} Y-Z->J Else 1->{I-2} Z-Y->J End If X>W 0->{I-3} X-W->K Else 1->{I-3} W-X->K End .ANGLE tan^-1(K,J)->{I-4} .VELOCITY 1->{I-5}End.BUL_PROCESSFor(I,1,B) 6*I+50+L1->J .FIND NEW DISPLACEMENT VIA ANGLE/HYP (VELOCITY) cos({J-4})/127*{J-5}->K .This is where I have no idea what I am doing sin({J-4})/127*{J-5}->L .UPDATE POSITION BASED ON SIGN If {J-2} K+{J}->{J} Else K-{J}->{J} End If {J-3} L+{J-1}->{J-1} Else L-{J-1}->{J-1} End .REMOVE OUT OF BOUNDS If ({J}=57) or ({J}=0) or ({J-1}=89) or ({J-1}=0) Copy(6*B+50+L1,J,6)^^r B-- I-- EndEnd
I know the problem lies somewhere with how I am using the sine and cosine functions (or atleast tried to), but I dont know how to fix it because theres no much documentation on stuff like this. Anyone see a way to fix this?

#### Hayleia

• Programming Absol
• Coder Of Tomorrow
• LV12 Extreme Poster (Next: 5000)
• Posts: 3367
• Rating: +393/-7
##### Re: Bullet trig questions
« Reply #1 on: November 03, 2013, 02:05:08 am »
Like I guess that 127 is supposed to represent the value 1 and -127 as -1, but I don't know how I would make a conversion like that inside code.
Well... divide by 127 ?
Be sure though not to divide right after you made the (co)sine calculation or you'll always get 0 or 1 or -1. For example, if you have to do sin(a)*r, do sin(a)*r/127 and not sin(a)/127*r.
Also, if you don't care about losing a bit of precision, divide by 128 instead of 127. It is a less ugly number.
« Last Edit: November 03, 2013, 02:05:30 am by Hayleia »
I own: 83+ ; 84+SE ; 76.fr ; CX CAS ; Prizm ; 84+CSE
Sorry if I answer with something that seems unrelated, English is not my primary language and I might not have understood well. Sorry if I make English mistakes too.

#### LemonDrop

• LV2 Member (Next: 40)
• Posts: 26
• Rating: +4/-0
##### Re: Bullet trig questions
« Reply #2 on: November 03, 2013, 02:35:10 am »
Well... divide by 127 ?
Be sure though not to divide right after you made the (co)sine calculation or you'll always get 0 or 1 or -1. For example, if you have to do sin(a)*r, do sin(a)*r/127 and not sin(a)/127*r.
Also, if you don't care about losing a bit of precision, divide by 128 instead of 127. It is a less ugly number.
Problem with that still is if the r value (or velocity, whatever you want to call it) is something like 1, and the result from the sin/cos isnt 127, it will just round down to 0 or whatever and not move. I was thinking about multiplying the coordinates by 2 then dividing them again to get more precision or something but that doesn't seem like it would fix the problem.

#### Eiyeron

• Urist McEiyolobster
• LV10 31337 u53r (Next: 2000)
• Posts: 1430
• Rating: +130/-10
• (-_(//));
##### Re: Bullet trig questions
« Reply #3 on: November 03, 2013, 02:48:39 am »
V/*127*5
/* = fixed-point division.

Else you can use subpixels! And for drawing: Pxl-on(x/128, y/128)

#### LemonDrop

• LV2 Member (Next: 40)
• Posts: 26
• Rating: +4/-0
##### Re: Bullet trig questions
« Reply #4 on: November 03, 2013, 02:50:54 am »
Ah I'll try that out. I also just thought, maybe I shouldn't be adding to the previous frames coordinates, and maybe just re-calculate the coordinates alltogether just with the "velocity" being the thing that stacks each frame. I think that will give it a lot more precision or something.

#### Eiyeron

• Urist McEiyolobster
• LV10 31337 u53r (Next: 2000)
• Posts: 1430
• Rating: +130/-10
• (-_(//));
##### Re: Bullet trig questions
« Reply #5 on: November 03, 2013, 02:55:56 am »
Precision: Subpixels is a method who lets for instance for each pixel 128 values to have some precision.

For instance sx = [0,127] corresponds to x=1, sx= [128,255] <=> x=2...
With this, you'll only have to divide sx and sy by 128 to have pixel coords. And what's great is that division is optimized by Axe!

#### LemonDrop

• LV2 Member (Next: 40)
• Posts: 26
• Rating: +4/-0
##### Re: Bullet trig questions
« Reply #6 on: November 03, 2013, 01:59:27 pm »
So I tried my idea of using a constantly stacking radius vs adding on to previous coordinates and got this:

Thanks for the help guys (wouldn't have thought of that without all this talk about it).

#### Xeda112358

• they/them
• Moderator
• LV12 Extreme Poster (Next: 5000)
• Posts: 4704
• Rating: +719/-6
• Calc-u-lator, do doo doo do do do.
##### Re: Bullet trig questions
« Reply #7 on: November 03, 2013, 02:31:38 pm »
If you want completely accurate precision that is very fast (at the cost of requiring more RAM), it might actually be more beneficial to store the following information about each bullet:
Code: [Select]
x coordy coordwidthheightremainderEach frame, you would do something like the following:
Code: [Select]
for(a=0,#ofbullets-1)  call AdjustCoords  pxl-change(x,y)  x?buf(5*a)  y?buf(5*a+1)  w?buf(5*a+2)  h?buf(5*a+3)  r?buf(5*a+4)AdjustCoords:buf(5*a)?xbuf(5*a+1)?ybuf(5*a+2)?wbuf(5*a+3)?hbuf(5*a+4)?rpxl-change(x,y)if remainder >0  x+1?x  r-h?r  returnIf remainder=<0  y+1?y  r-w?r  returnEssentially, it makes sure that the bullet stays as close to being on track as it can. If it moves too far in the x direction, it corrects by moving in the y direction. All the while, it adjusts the remainder (if remainder dips below 0, then we know it has moved too far off track and we need to adjust by moving in the y direction.

The pseudocode isn't perfect-- it only accounts for being able to move right or up. You will want to store the x and y directions of the bullets as well. The rest of the data is derived from:

initial (x,y) depends on where the bullet originates
initial (w,h) will remain constant and comes from subtracting the enemy objects coordinates from the bullet origin coordinates. If these are positive, then direction will be 1 for the given direction. If either is negative, direction needs to be set as -1 and then you need to make it positive with abs().
initial remainder should be set as w
Finally, (w,h) needs to be readjusted by multiplying them by 2.

(in non-integer arithmetic, we would just set initial remainder as w/2, but we would lose accuracy in integers if w was odd, so we just use w and then double width and height)

An increment, add/subtract and compare is much faster than computing arctangent, multiplying/dividing and using sin() or cos(). It also does not require inflated pixels, but it can work just fine with them, too. I have vague memories of doing something like this over the summer that got hundreds of bullets on screen at 6MHz. I'll try to find it and edit this post.

EDIT: Oh, it was actually an old topic that you posted in, but for a refresher: http://ourl.ca/19321/356834
« Last Edit: November 03, 2013, 02:38:01 pm by Xeda112358 »

#### LemonDrop

• LV2 Member (Next: 40)
• Posts: 26
• Rating: +4/-0
##### Re: Bullet trig questions
« Reply #8 on: November 03, 2013, 02:45:52 pm »
Yea that was the old system and I did get it working but it had a lot of weird issues such as sometimes the bullets would have really sharp paths and sometimes they would just go for a bit then dive straight down depending on what its target was, that is probably my fault but I'll test around some more to see if this is better.