cross product vs angle
I have computed the cross product and the angle between the same 2 vectors.
The results confuse me, for some input vectors they have different signs for other input they have the same sign.
Shouldn't they have the same sign ?
i compute the angle with atan2(cross,dot)
[Edited by - republicall on December 7, 2009 8:44:10 AM]
How are you using atan2 with a cross product? A cross product produces a vector which is perpendicular to both the input vectors. You can use the dot product of the two vectors to calculate the angle:
a . b = |a||b|cos(theta)
So then cos(theta) = (a . b) / (|a||b|). You can use acos() to get the angle (in radians).
a . b = |a||b|cos(theta)
So then cos(theta) = (a . b) / (|a||b|). You can use acos() to get the angle (in radians).
There is another correspondence w.r.t. the cross-product:
|a x b| == |a| * |b| * sin( <a,b> )
The atan2 computes an angle in all 4 quadrants, so the result will be in the range [-pi,+pi]. The dot-product / cross-product considers the angle just between the 2 vectors (i.e. without giving one of the both vectors a precedence). Such an angle is always in the range [0,+pi]. Only if you compute the angle explicitely from the one vector to the other (i.e. not just between 2 vectors) the result can be greater than pi.
|a x b| == |a| * |b| * sin( <a,b> )
The atan2 computes an angle in all 4 quadrants, so the result will be in the range [-pi,+pi]. The dot-product / cross-product considers the angle just between the 2 vectors (i.e. without giving one of the both vectors a precedence). Such an angle is always in the range [0,+pi]. Only if you compute the angle explicitely from the one vector to the other (i.e. not just between 2 vectors) the result can be greater than pi.
The angle you get from the dot product and acos is the smallest angle between the two vectors. It's always between 0 and 180 degrees.
The angle you get from the cross product and asin is always between -90 and 90 degrees. It's the signed angle that you need to rotate one vector until it becomes parallel to the other (which includes pointing in the opposite direction!). It's "signed" in that the rotation is considered positive in one direction and negative in another; the convention which assigns signs to these directions is the right hand rule.
The angle you get from the dot product, cross product, and atan2, is between 0 and 2 PI (or -PI and PI) and gives the signed angle you need to rotate one vector until it points in the same direction as the other. Notice how "points in the same direction" in this sentence is slightly different from "becomes parallel to" in the last paragraph.
The angle you get from the cross product and asin is always between -90 and 90 degrees. It's the signed angle that you need to rotate one vector until it becomes parallel to the other (which includes pointing in the opposite direction!). It's "signed" in that the rotation is considered positive in one direction and negative in another; the convention which assigns signs to these directions is the right hand rule.
The angle you get from the dot product, cross product, and atan2, is between 0 and 2 PI (or -PI and PI) and gives the signed angle you need to rotate one vector until it points in the same direction as the other. Notice how "points in the same direction" in this sentence is slightly different from "becomes parallel to" in the last paragraph.
Quote:Original post by Xycaleth
How are you using atan2 with a cross product? A cross product produces a vector which is perpendicular to both the input vectors. You can use the dot product of the two vectors to calculate the angle:
a . b = |a||b|cos(theta)
So then cos(theta) = (a . b) / (|a||b|). You can use acos() to get the angle (in radians).
Apparently there's some confusion on this subject, and I've never quite been able to get a straight answer from anyone, but...
Some web ressources mention a "perpendicular dot product", which for the two 2d vectors A and B is defined:
A "perpdot" B = A.x * B.y - A.y * B.x
as opposed to the "regular" dot product, which is:
A dot B = A.x * B.x + A.y * B.y
Some people also call the perpendicular dot product a "2d cross product", which imo is slightly misleading, since you'd expect it to return a vector and not a scalar.
http://mathworld.wolfram.com/PerpDotProduct.html
Cheers,
Mike
thanks for the answers
first to say this is for 2d :)
but i have to dissagree with both:
1. this are some gamedev post:
>>>
Remember that acos() returns the angle in radians, so you'll have to convert before calling glRotate(). Also, an alternate way of finding the (signed) angle between vectors of arbitrary (non-zero) length in 2d is:
angle = atan2(perpdot(a,b), dot(a,b));
dir = Math.toDegrees(Math.atan2(pos.perpDot(dirVector), pos.dot(dirVector)));
<<<
atan2(v1.x*v2.y - v1.y*v2.x, v1.x*v2.x+v1.y*v2.y))
<<<
vector2 diff = target - position;
float angle = atan2(perp_dot(forward, diff), dot(forward, diff));
<<<
2.
>>>
and the sign of the cross product tells you if you should turn clockwise or counterclockwise).
<<<
i use the next 2 functions with the same results(from this i guess the function is ok):
double CGame::AngleInDegrees_uv(D3DXVECTOR2* u, D3DXVECTOR2* v)
{
float dot = D3DXVec2Dot(u, v);
float cross = D3DXVec2CCW(u, v);
double radians = atan2(cross, dot);
return radians;
}
//*********************************************************************************
double CGame::Angle2Vectors2d_uv(D3DXVECTOR2* u, D3DXVECTOR2* v)
{
double angle = atan2(v->y, v->x) - atan2(u->y, u->x);
return angle;
}
later edit:
the error was somewhere else
but you can use the functions above in 2d
first to say this is for 2d :)
but i have to dissagree with both:
1. this are some gamedev post:
>>>
Remember that acos() returns the angle in radians, so you'll have to convert before calling glRotate(). Also, an alternate way of finding the (signed) angle between vectors of arbitrary (non-zero) length in 2d is:
angle = atan2(perpdot(a,b), dot(a,b));
dir = Math.toDegrees(Math.atan2(pos.perpDot(dirVector), pos.dot(dirVector)));
<<<
atan2(v1.x*v2.y - v1.y*v2.x, v1.x*v2.x+v1.y*v2.y))
<<<
vector2 diff = target - position;
float angle = atan2(perp_dot(forward, diff), dot(forward, diff));
<<<
2.
>>>
and the sign of the cross product tells you if you should turn clockwise or counterclockwise).
<<<
i use the next 2 functions with the same results(from this i guess the function is ok):
double CGame::AngleInDegrees_uv(D3DXVECTOR2* u, D3DXVECTOR2* v)
{
float dot = D3DXVec2Dot(u, v);
float cross = D3DXVec2CCW(u, v);
double radians = atan2(cross, dot);
return radians;
}
//*********************************************************************************
double CGame::Angle2Vectors2d_uv(D3DXVECTOR2* u, D3DXVECTOR2* v)
{
double angle = atan2(v->y, v->x) - atan2(u->y, u->x);
return angle;
}
later edit:
the error was somewhere else
but you can use the functions above in 2d
Quote:Original post by h4tt3nQuote:Original post by Xycaleth
How are you using atan2 with a cross product? A cross product produces a vector which is perpendicular to both the input vectors. You can use the dot product of the two vectors to calculate the angle:
a . b = |a||b|cos(theta)
So then cos(theta) = (a . b) / (|a||b|). You can use acos() to get the angle (in radians).
Apparently there's some confusion on this subject, and I've never quite been able to get a straight answer from anyone, but...
Some web ressources mention a "perpendicular dot product", which for the two 2d vectors A and B is defined:
A "perpdot" B = A.x * B.y - A.y * B.x
as opposed to the "regular" dot product, which is:
A dot B = A.x * B.x + A.y * B.y
Some people also call the perpendicular dot product a "2d cross product", which imo is slightly misleading, since you'd expect it to return a vector and not a scalar.
http://mathworld.wolfram.com/PerpDotProduct.html
Cheers,
Mike
In a way, the perpendicular dot product does return a vector. If you extend the 2D vectors to 3D by setting Z=0, the cross product of the two vectors is a vector with X=0 and Y=0, and Z becomes the perpendicular dot product.
If you extend vector notations to 3D and reduce vectors with zero-components, it can be considered that the 2D cross product returns a vector. And the result is consistent with what the corresponding 3D cross product is.
The exterior product is something that multiplies two 1-co-vectors (of dimension n) and results in a 2-co-vector (of dimension n*(n-1)/2).
In the case of R^3, the result is in another vector space of dimension 3. Although we are talking about technically different R^3s, there are natural ways to pass from one to another, given by the Euclidean metric (the details of this are a little fuzzy in my head, after 10 years of not doing Geometry). This is one way of defining the cross product.
In the case of R^2, the result is in another vector space of dimension 1, and that's why it looks like a scalar. This is one way of defining the "cross product" in dimension 2.
I'm not sure if that's the explanation that h4tt3n was looking for...
In the case of R^3, the result is in another vector space of dimension 3. Although we are talking about technically different R^3s, there are natural ways to pass from one to another, given by the Euclidean metric (the details of this are a little fuzzy in my head, after 10 years of not doing Geometry). This is one way of defining the cross product.
In the case of R^2, the result is in another vector space of dimension 1, and that's why it looks like a scalar. This is one way of defining the "cross product" in dimension 2.
I'm not sure if that's the explanation that h4tt3n was looking for...
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement