0

I've been having some trouble with trying to get a bullet to fire at angle that I put in. I am using eclipse with java.

My code:

x += (int) (spd * Math.cos(dir));
y -= (int) (spd * Math.sin(dir));`

The feel like the reason it's not working is because it is casted to an int which possibly makes it so inaccurate. But in order for it to draw the rectangle it needs ints.

When inputting dir as 0 it's fine and shoots to the right. The problem is when I put in 90, instead of shooting striaght up it shoots off a little to the left.

Any idea on how I can fix this? Thanks!

drneel
  • 2,887
  • 5
  • 30
  • 48
mkjrfan
  • 77
  • 1
  • 8

4 Answers4

5

No, you're making a classic mistake: Java trig functions need radians, not degrees. It's not 90 that you should pass; it's π/2.0.

So be sure to convert angles in degrees to radians by multiplying by π/180.0.

This is true for C, C++, Java, JavaScript, C#, and every other language I know. I cannot name a single language that uses degrees for angles.

double radians = dir*Math.PI/180.0;
x += (int)(spd*Math.cos(dir));
y -= (int) (spd * Math.sin(dir));`  // I don't know why you do this.  Funny left-handed coordinate system.

Speed is the magnitude of the velocity vector. The equations, as written, only express velocity as (vx, vy) components.

If you want displacements, you'll have to multiply by a time step:

vx = speed*Math.cos(angle);
vy = speed*Math.sin(angle);
dx = vx*dt;
dy = vy*dt;
x += dx;  // movement in x-direction after dt time w/ constant velocity
y += dy;  // movement in y-direction after dt time w/ constant velocity

If there's acceleration involved (e.g. gravity), you should calculate the change in velocity over time the same way.

duffymo
  • 305,152
  • 44
  • 369
  • 561
  • Oh yeah, that too! Totally missed that part. – Amadan Jul 11 '13 at 01:27
  • I think that's the real root of the problem. – duffymo Jul 11 '13 at 01:27
  • Okay I'm not really sure how to explain what happened but I did this: dir = dir * Math.PI / 2.0; But what comes out is truly bizarre in the fact that the bullets seem to circle around each other. – mkjrfan Jul 11 '13 at 01:29
  • Actually I fixed that weird problem by putting it in the constructor class but it then only fires in 4 directions. Edit: Actually (again) your right it works I just put pi/2.0 which is what I saw first not 180. Sorry but thanks for your help! – mkjrfan Jul 11 '13 at 01:32
  • 90 degrees = π/2.0 radians. I don't know what you're doing. – duffymo Jul 11 '13 at 01:34
  • No I was just testing for 90 degrees, but I did want all angles. – mkjrfan Jul 11 '13 at 01:37
  • I get it; that's why I told you how to convert any angle. I'll bet your code still has lots of problems. – duffymo Jul 11 '13 at 01:39
2

Keep coordinates as floats, cast them only in the call to your drawing method (or cast them into another variable). You need to keep the precise values for the next iteration.

Amadan
  • 191,408
  • 23
  • 240
  • 301
  • Well what I did was I took out the (int)s and placed it into the get method, but it still only shoots in about 8-9 different directions. – mkjrfan Jul 11 '13 at 01:27
1

Yes, you need to keep the angle as floats.

But more likely, you said you're using 0 and 90. Math.cos() and Math.sin() take radian values. If you're passing in degrees, you'll definitely have things headed in the wrong direction. Convert from degrees to radians, and your directions will likely be much better.

user1676075
  • 3,056
  • 1
  • 19
  • 26
0

One problem is that round off error propogates when you increment x and y for each iteration. One posssible solution is to compute the x and y coordinates based on a counter instead:

x = (int) (time * spd * Math.cos(dir));
y = (int) (time * spd * Math.sin(dir));

Here I use the variable name time for the counter to indicate that it is some measure of the amount of time that has passed since the bullet was fired.

Code-Apprentice
  • 81,660
  • 23
  • 145
  • 268