finding distance between 2 objects in 2d space?

Started by
12 comments, last by graveyard filla 19 years, 10 months ago
high, im working on a 2d rpg/shooter. anyway, im very poor in math (only know some basic algebra).. anyway, the player and enemy could have a gun and shoot at each other. heres the problem : i want guns to have a range x which means the bullet dies after it is x pixels away from where it was fired.... how do i go about calculating how far away the bullet is from its owner, given i have the owners x/y position and bullets x/y position? keep in mind this is all in 2d space (0,0 is top left corner, x and y increase going right/down) also, i didnt know how to figure out to make the bullet have a strait path untill i posted on this site before. people told me "normalize the vector blah blah".. anyway, i just copied and pasted their math in my code to get my bullets to move in a strait line to their target (i didnt understand it and no one really explained.. im not sure what a vector is) ... like i said, im really poor in math. if anyone could explain it a little in detail (right now im taking college algabra in school (college) and the latest thing we learned about is logarithms...) thanks for any help, ps could anyone reccomend a good book for learning basic 2d math? maybe i should open my school text book (it has linear algabra in it im pretty sure, is this what i look for?).. thanks for any help!!! [edited by - graveyard filla on May 31, 2004 2:36:54 AM]
FTA, my 2D futuristic action MMORPG
Advertisement
You can think of the distance as the hypotenuse of a right triangle, where one side is y2-y1 and one side is x2-x1. This being said, you can use the pythagorean theorem to find the distance between the two objects: sqrt((y2-y1)^2 + (x2-x1)^2) where (x1, y1) is the position of the person and (x2, y2) is the position of the bullet.
My fellow Americans I have just signed legislation that outlaws Russia forever. Bombing will commence in five minutes.
to find the distance between two points use:
x3 = x2 - x1;
y3 = y2 - y1;

dist = sqrt(x3 * x3 + y3 * y3)

where x2 and x1 are your 2 points that you want to test.

This formula uses pythagoras'' theorem, where the length of the hypotenuse is equal to the square root of the two other sides squared and added (ie h^2 = x^2 + y^2. Search it on google
Since doing a lot of square roots can be costly, you can skip that part. Of course then, you''d have to check the "distance" against the range squared, but it still works and it''s faster.
what you want is a book on trigonometry and algebra.
He did ask for the *distance* . With regards to the 'where can I find a good book on trig/algebra' question, I would have to say the best one I ever saw was a little book called "Before Calculus 3" by Leonard Leithold. I bought it back in 8th grade which wasn't so long ago and well, it was so easy I was able to self-study my way through in a matter of weeks, and I'm no math genius.

[edited by - uber_n00b on May 31, 2004 2:49:53 AM]
My fellow Americans I have just signed legislation that outlaws Russia forever. Bombing will commence in five minutes.
Yes true, sqrt is costly and should be avoided where possible, but I think that optimisation is the least of graveyards concerns right now.
wow what a fast response.. thanks guys (slowly cuts and pastes code wishing i payed attention in high school..)

so this is trig or linear alg or what? and could anyone try to attempt to explain exactly how this equation works (sadly i dont even know what a hypotonuse is.. some sort of large animal which lives in a swamp i think??)? thanks alot for all your guys help!!!

[edited by - graveyard filla on May 31, 2004 4:14:26 AM]
FTA, my 2D futuristic action MMORPG
Well, let me see...
inline float PixelSpaceDistance(int x, int y){   float Distance;   _asm {      fild x      fmul st(0), st(0)      fild y      fmul st(0), st(0)      fadd st(0), st(1)      fsqrt      fstp Distance   }   return Distance;}

I''ve gotta keep up the practice. Sry, I haven''t learned SSE yet, but tonight!...
"I study differential and integral calculus in my spare time." -- Karl Marx
Trying to explain how handy vectors are a bit: in 2D (in 3D it's the same btw), a vector can represent the coordinates of a point (an enemy, a bullet, a player, ...), but a vector can also represent the velocity of a bullet, the acceration of a bullet, a direction of a player, etc...

If the vector represents a position, you can think of it as the coordinates of an object on a map: it's just it's coordinate in the horizontal direction and it's coordinate in the vertical direction.

If you want to give a bullet a certain speed in a certain direction (that is, a velocity), you can either do it with goniometrical formulas and angles, but do NOT do this. Much better is to give the bullet it's own velocity vector: for example velocity (10,0) would could the bullet goes at 10 pixel / second in the x direction and 0 in the y direction, so it'll move in the horizontal direction with speed 1 (of course you can choose how fast this is yourself, but don't forget to make it time based and not 1 pixel / frame because then it'll go faster on faster computers and slower on slow computers)

To implement this velocity, you add (10,0) to the coordinates of the bullet each time: for example if you add (10,0) each time to the bullet, and the coordinate of it is now (100,100), it'll be (110,100) after 1 second, (120,100) after 2 seconds, etc... but of course you'll want to add (1,0) every 10th of a second instead or (0.1,0) every 100th of a second to make it more fluent.

Now say you want the bullet to go in a direction of 45° from the top left to the bottom right, then you make the velocity vector of the bullet (10,10): it'll go at 10 pixel / second in the x direction and 10 pixel / second in the y direction, and if you think about it, that's 45° in the direction I mentioned.

However, what if you want the absolute speed to be exactly as fast as the case where it goes horizontaly, i.e. 10 pixels / second? if it goes 10 pixels/second down and 10 pixels/second right, it's actually going at sqrt(2)*10 pixels / second, because, the diagonal of a square is longer than the sides! And it's exactly sqrt(2) ~= 1.41 times longer. That's why your normalize your vector: you divide the (10,10) through sqrt(10*10 + 10*10) = 14.14..., and the result is (10,10)/14.14 = (0.707,0.707) and then you get a vector of unit length (because, you have divided it through it's lengt! sqrt(x*x + y*y) is namely the length of a vector, that explains also the distance formula you asked about). A vector of unit length means the bullet will go 1 pixel/second (or if it goes the direction of 45°, 1/0.707th part of the diagonal of a square every second which is the same length as 1 side of a square). So, if you want it to be 10 pixels/second instead, multiply this unit vector by 10, and you get (7.07,7.07).

So a bullet that goes with velocity (7.07,7.07) and one with velocity (10,0) will appear to have the same speed to you, only the direction is different.

And one more smart thing to do, is to give your player guy not a single value representing it's angle, but also a vector representing it's direction! Then the unit vector of the velocity of the bullet is simply the direction of your player, normalized! To rotate your guy with an angle Alfa, you have to multiply it's direction vector with a 2x2 matrix

[cos(Alfa) sin(Alfa)]
[-sin(Alfa) cos(Alfa)]

To multiply a vector (x,y) with a matrix

[a b]
[c d]

the result is simply the vector

(a*x+b*y, c*x+d*y)

If you make the direction of the player normalized from the start, it'll always remain normalized no matter how much your rotate it with this matrix.

So basicly to give a bullet a certain speed at a certain angle, make the velocity of the bullet the normalized direction of the player, and then multiply that vector by the speed you want the bullet to have.

You can look up more about this on mathworld, for example here's their article about rotation matrices: http://mathworld.wolfram.com/RotationMatrix.html


There are many handy formulas with vectors btw, for example the dot product (look it up on mathworld, it's useful to find the angle between two vectors for example, but you probably never need this if you do everything with vectors you never need angles), and the distance between two vectors which is in general form:

distance between (a,b) and (c,d) =

sqrt ( (a-c)*(a-c) + (b-d)*(b-d) ) and this is because in a triengle witha 90° corner (dunno english name of such triangle) A²=B²+C²

Also Samith is right, don't take the sqrt, simply use (a-c)*(a-c)+(b-d)*(b-d), and if you want the bullet to die out at distance 20, just let it die out if that formula without sqrt is 20*20 = 400.

3D engines also work purely on vectors (or quaternions ) and multiplications with 3x3 and 4x4 matrices, so it's a very good thing to learn the basics in 2D now!

I hope my explanation was a bit useful

[edited by - Boops on May 31, 2004 5:35:30 AM]

This topic is closed to new replies.

Advertisement