4
\$\begingroup\$

I want to fire an arrow toward the mouse location.

X0 = the players X location
X1 = the mouse X location
Y0 = the players Y location
Y1 = the mouse Y location

I want to make a method which takes degrees as a parameter, and sets the Yspeed and Xspeed accordingly, so the arrow can reach the mouse position, starting at the player position.

I am using float coordinates (i.e. float x, y, z).

How can I do this?

\$\endgroup\$
1
  • 2
    \$\begingroup\$ Why do you want a method working on degrees? That's rarely the best representation. Often you're better off by using a {dx,dy} pair. \$\endgroup\$
    – MSalters
    Dec 3, 2012 at 12:54

3 Answers 3

7
\$\begingroup\$

This " answer " is to add some visual information to the answers already given. enter image description here

2: We first create a vector ( 2D in this case with component x and y ) by taking the difference from both positions ( mouse - player ).

3: We then Normalize it to create a so called " unit vector ". Which means to bring the length of our vector to 1. This is done by dividing both x and y component of the vector by the length/magnitude. We need this because this is our direction vector. It simply tells in which direction we are heading for the x and y axis.

4: Now we have the direction we just need to multiply it by a scalar ( or simply put by your speed). Since the length is 1. Any number we multiply with will result in a new vector with the length equal to your given speed. Just remember that a unit vector represents the direction of your vector. Basically the red dotted lines is how much it moves in the x direction and how much it moves in the y direction per frame.

So recap:
Unit vector = direction
Magnitude/Length/speed = steps to move per frame on x and y axis.

(The lengths in the drawing are just for visual aid, they are not meant to be accurate )

Hope this helps.

\$\endgroup\$
2
  • \$\begingroup\$ Awesome answer. I was having trouble to understand how this kind of algorithm worked, and all "explanations" I found so far pretty much just kept throwing a bunch of numbers and equations at me with no proper explanation, seemingly thinking I'm some kind clairvoyant who can understand WTF things like (v_x^2+v_y^2+v_z^2-v_b^2)t^2 + 2*(v_x*c_1+v_y*c_2+v_z*c_3)t + (c_1^2+c_2^2+c_3^2) = 0 mean. That is until I found this properly dissected and explained answer. Have my +1, you deserve every byte (<- being literal) of it! =D \$\endgroup\$ Jun 18, 2013 at 0:41
  • \$\begingroup\$ @TheLima Those equations become more clear down the road. But yeah I'm not that strong with math either and stuff like that can be really demotivating. \$\endgroup\$
    – Sidar
    Jun 18, 2013 at 5:44
3
\$\begingroup\$

You are trying to fire an arrow from point a(player) to b(mouse position) in 2d space?

you can simply do the following formula to get the direction. (rather than degree)

v1 = ( Player.x, Player.y );
v2 = ( Mouse.x, Mouse.y );
dir = v2 - v1;
dir.normalize();
arrow.xy += dir * speed;

hope this helps you achive what you want.

\$\endgroup\$
3
  • \$\begingroup\$ I have 2 seprate fields for x and y and i want to calculate the speed of each one so it moves in that direction ps. im using java \$\endgroup\$ Dec 3, 2012 at 10:26
  • \$\begingroup\$ the equation is still the same. v1&v2 are 2 vectors that store x&y. you can break it donw to xd = x1 - x0; yd = y1 - y0; \$\endgroup\$
    – Tordin
    Dec 3, 2012 at 10:41
  • \$\begingroup\$ @gopgop That's exactly what his code does. You need to get both the x and y components ( convert it to the same space if neede-> global/local). Divide the difference by it's length ( normalize ) to get the direction. Then you need a scalar to give it a new magnitude. Philips answer does exactly the same. \$\endgroup\$
    – Sidar
    Dec 3, 2012 at 10:42
3
\$\begingroup\$

The ratio of the horizontal to the vertical component of the vector is proportional to the ratio of the horizontal and vertical difference in position. The proportion factor is the speed divide by the direct distance (calculated by the pythagorean theorem).

distance.x = target.x - start.x;        
distance.y = target.y - start.y; 
distance_direct = square_root((distance.x * distance.x) + (distance.y * distance.y)); // pythagoras

vector.x = distance.x * (speed / distance_direct);
vector.y = distance.y * (speed / distance_direct);

Note that this will result in a division by zero when the distance is zero (start and target position are identical). That makes sense, because in that case the vector is undefined (in what direction do you not-go when you want to stay where you are?). This case needs to be handled separately.

Note that there is no reason to use degree here. When you have an angle in degree and a speed, you can convert it to x and y direction using sine and cosine:

vector.x = sin(angle) * speed
vector.y = cos(angle) * speed

In most programming languages, the sine and cosine functions use radiants, not degrees. That means a full 360° circle is 2*PI (approximately 6.283185) you can convert degree to radiants by multiplying them with PI / 180 or approximately 0.01745329.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .