Skip to main content
GameDev.net gamedev.net
🔒 Locked

Is it a vector problem?

Started by desertcube Dec 31, 2003 at 5:34 AM 6 replies 850+ views
Original Post
desertcube
desertcube
I hope this is the write place to post this, after all it is related to maths. At the moment I have three points (lets say A, B, C) which are just X and Y co-ordinates on the screen (e.g ''A'' might have X=100 and Y=200) and two lines connecting them, A to B and A to C. I need a way of finding the angle between these two lines. I''m not sure if the solution to this problem is to do with vectors, as I don''t know much about them apart from what I''ve read in here on gamedev, the Vectors and Matrixs primer, but I didn''t understand all of it. Do I need to do some more research into vectors or am I heading in the wrong direction? I think the scalar product, or dot product, sounds like it may help, but am very confused how to implement it in my example. Thanks for your time and any help is welcome.
sphinx23
sphinx23
the dot product is the way to go with vectors. the dot product returns the cosine of the vectors, so in your case:

u = B-A
v = C-A

normalize(u)
normalize(v)

dot = u*v
acos(dot) = angle

where * is the dot product

[edited by - sphinx23 on December 31, 2003 7:04:03 AM]
oliii
oliii
I'd say you need to research a bit more on vector and trigonometry.

in 2D, if you have two directional vectors u and v, and you want the angle(u, v)

cosine(angle(u, v)) = u . v / (|u| * |v|)
sine (angle(u, v)) = u x v / (|u| * |v|)

and

u . v = u.x*v.x + u.y*v.y
u x v = u.x*v.y - u.y*v.x

and to find angle(u, v)

angle(u, v) = arctangent(sine(angle(u, v)) / cosine(angle(u, v)))
angle(u, v) = arctangent((u x v) / (u . v))

I do specify in 2D, as in 3D, the cross product is slightly different.


with atan() (arctangent in C/C++), and acos() and asin(), you have to be careful of the signs of (u x v) and (u . v). The range of the angle returned will be between [0, PI], or [-PI/2, PI/2] (or if you prefer between [0, 180 degrees], or [-90, 90] degrees).

in C and C++, you have the function atan2(y, x), which takes care of the signs of y anx and return the angle between u and v in the range [-PI, PI] ([-180, 180 degrees]).

so, in short, in C


float Dot (Vector2 u, Vector2 v)
{
return u.x*v.x + u.y*v.y;
}
float Cross(Vector2 u, Vector2 v)
{
return u.x*v.y - u.y*v.x;
}
Vector2 Sub(Vector2 u, Vector2 v)
{
return Vector(u.x-v.x, u.y-v.y);
}

float RadiansToDegrees(float rad)
{
return rad * 57.29578f;
}

float AngleInDegrees(Vector2 A, Vector2 B, Vector2 C)
{
Vector2 u = Sub(B, A);
Vector2 v = Sub(C, A);

float dot = Dot (u, v);
float cross = Cross(u, v);

float radians = atan2(cross, dot);

return RadiansToDegrees(radians);
}


[edited by - oliii on December 31, 2003 7:57:06 AM]
Everything is better with Metal.
desertcube
desertcube
I've tried your way sphinx and it works like a charm!
Oliii, is there any advantage to your way? The way I've done it does seem a litlle messier, but will I get the same results?

[edited by - desertcube on December 31, 2003 8:00:45 AM]
Zipster
Zipster
His method expresses the angle in terms of an arctangent so he can break tangent down into sine and cosine, which both have special vector operations. It''s the same thing really, if you understand the theory.
oliii
oliii
the acos() only returns an angle in the range [0, Pi], which maybe not enough (depends what you want). And I don't normalise, which is faster, but that's a moot point.

and also, it will fail if u . v > 1.0f (like u . v = 1.0000000001f). But that's also debatable.

[edited by - oliii on January 1, 2004 6:12:47 PM]
Everything is better with Metal.
YoshiN
YoshiN
quote:
Original post by oliii
the acos() only returns an angle in the range [0, Pi], which maybe not enough (depends what you want). And I don''t normalise, which is faster, but that''s a moot point.

and also, it will fail if u . v > 1.0f (like u . v = 1.0000000001f). But that''s also debatable.

[edited by - oliii on January 1, 2004 6:12:47 PM]


You''re not normalizing but you are dividing the by the product of the magnitude which is almost the same thing. Timing wise it doesn''t seem like either is faster.
-YoshiXGXCX ''99
desertcube
desertcube
Thanks for all your replies, I''ve got the problem fixed. It''s not really a time critical part of the program, so it doesn''t matter which one is faster, but I''ve used the angle(u, v) = arctangent((u x v) / (u . v)) way as it gives me angles over 90 degrees.
Thanks again.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.