flaghacker - 9 months ago 37

Java Question

I'm making a simple 2d Java game similar to goemetry wars. I'm currently programming the player's shooting.

I have a target point specified by the mouse location. Now I want to add a bit of randomization, so that the shooting angle has a random offset. I am currently converting the point to a vector directly. My idea was to convert the vector to an angle, apply the randomization to that angle, and then, convert the angle back to a vector (given the length of the vector).

I can't figure out how to convert the angle back to a vector. I don't need code, it's basically just a question about the maths.

If there's a better way to randomize the shooting, I would love to hear that too! I can!t apply the randomization to the point because there are other things then the mouse that can set it.

Answer

As everybody seems to have just answered in the comments, here goes the answer to your question as it is formulated : you need to use the polar coordinate system.

Let's call your angle `a`

, the angle you want to add to it `b`

, so the modified angle is `a+b`

.

In the polar coordinate system, your point is represented by an angle `a = Math.atan2(y, x)`

and a radius `r = sqrt(x*x + y*y)`

. If you just use the angle, you loose some information, which is at which distance the mouse is from your (0,0) point.

Converting back from your polar representation (after the angle has been modified) is now possible : `x = r * Math.cos(a+b)`

, `y = r * Math.sin(a+b)`

By using some cool trigonometry formulas, we can do better. We don't need to go to an angle and come back to a vector, we can modify the x and y values of the vector directly, still changing the angle like you want.

Remember that we want to find `x'=r cos(a+b)`

and `y'=r sin(a+b)`

. We will obviously the following formulas :

Now let us multiply by `r`

on both sides to get what whe want.

We now recognize `x=r cos(a)`

and `y=r sin(a)`

, so we have the final expression :

If you come to think of it, for small values of `b`

(which is what you want), `sin(b)`

is close to 0, and `cos(b)`

is close to 1, so the perturbation is small.

Not only do you reduce the number of trigonometry operations from 3 to 2, but you also have a cos and a sin of small values, which is nice if they are computed from Taylor series, makes convergence very fast. But that's implementation dependent.

NB: An alternative (and more elegant?) way to find the same result (and exact same formulas) is to use a rotation matrix.

Whoopsie, you said you didn't want code. Well let's do it like this : I don't post it here, but if you want to compare with how I'd do it once you're done coding your implementation, you can see mine in action here : http://ideone.com/zRV4lL

Source (Stackoverflow)