Skip to main content
replaced http://stackoverflow.com/ with https://stackoverflow.com/
Source Link

I will try to break down the step-by-step questions I'd take to solve this problem, with the hope it helps you to understand how to go about solving vector-related problems in the future.

Note: I'll be using radians, and even if your final on-screen output is in degrees I recommend you do calculations in radians as opposed to degrees, since they behave more nicely in a number of ways (for example, you don't have to use additional scaling factors when recalculating angular velocity or acceleration). There's a reason why just about any math library uses radians. Also, sin and cos are defined assuming angles increase going counterclockwise, so you may have to adjust for that. If you prefer clockwise angles and degrees, that's just a matter of multiplying by -1 and 180/pi respectively where appropriate.

Q) What is pitch?
A) pitch is the angle between a direction and the horizontal component of that direction (which we'll call heading). of course, "horizontal" depends on your definition of "up", so we use the gravity vector.

float pitch(Vector3 direction, Vector3 gravity) { Vector3 heading = projectOnPlane(direction, gravity); return angleBetween(direction, heading); } 

Q) What is Yaw?
A) Yaw is the angle between the heading and north. So, it looks very similar to the pitch equation:

float pitch(Vector3 direction, Vector3 gravity, Vector3 north) { Vector3 heading = projectOnPlane(direction, gravity); return angleBetween(direction, north); } 

Q) Okay, but how do I get the heading -- the "horizontal" component (i.e. perpendicular to gravity) of a direction?
A) formula: enter image description here See this formula from Wikipedia:Vector Projection, although you may find easier places to read on vector projection. To project on to a plane, you subtract the vector projection on the normal vector of the plane from the original vector. Or, phrased in english, to get the horizontal component of a vector, you subtract the vertical component from the original vector. Translated verbatim into code:

float projectOnPlane(Vector3 a, Vector3 b) { Vector3 bProjection = (Vector3.Dot(a, b) / b.Length) * (b / b.Length); return a - bProjection; } 

Q) How do I get the angle between two vectors?
A) Most places tell give you some Equation that looks like http://i.imgur.com/asWcnH0.png. However, this will return the same value for either a clockwise or counterclockwise rotation, and we want the signed angle. So, we want the Atan2-based formulaAtan2-based formula:

 float angleBetween(Vector3 a, Vector3 b) { return Math.Atan2(Vector3.Cross(a, b).Length, Vector3.Dot(a, b)); } 

Tada! we're done!

I will try to break down the step-by-step questions I'd take to solve this problem, with the hope it helps you to understand how to go about solving vector-related problems in the future.

Note: I'll be using radians, and even if your final on-screen output is in degrees I recommend you do calculations in radians as opposed to degrees, since they behave more nicely in a number of ways (for example, you don't have to use additional scaling factors when recalculating angular velocity or acceleration). There's a reason why just about any math library uses radians. Also, sin and cos are defined assuming angles increase going counterclockwise, so you may have to adjust for that. If you prefer clockwise angles and degrees, that's just a matter of multiplying by -1 and 180/pi respectively where appropriate.

Q) What is pitch?
A) pitch is the angle between a direction and the horizontal component of that direction (which we'll call heading). of course, "horizontal" depends on your definition of "up", so we use the gravity vector.

float pitch(Vector3 direction, Vector3 gravity) { Vector3 heading = projectOnPlane(direction, gravity); return angleBetween(direction, heading); } 

Q) What is Yaw?
A) Yaw is the angle between the heading and north. So, it looks very similar to the pitch equation:

float pitch(Vector3 direction, Vector3 gravity, Vector3 north) { Vector3 heading = projectOnPlane(direction, gravity); return angleBetween(direction, north); } 

Q) Okay, but how do I get the heading -- the "horizontal" component (i.e. perpendicular to gravity) of a direction?
A) formula: enter image description here See this formula from Wikipedia:Vector Projection, although you may find easier places to read on vector projection. To project on to a plane, you subtract the vector projection on the normal vector of the plane from the original vector. Or, phrased in english, to get the horizontal component of a vector, you subtract the vertical component from the original vector. Translated verbatim into code:

float projectOnPlane(Vector3 a, Vector3 b) { Vector3 bProjection = (Vector3.Dot(a, b) / b.Length) * (b / b.Length); return a - bProjection; } 

Q) How do I get the angle between two vectors?
A) Most places tell give you some Equation that looks like http://i.imgur.com/asWcnH0.png. However, this will return the same value for either a clockwise or counterclockwise rotation, and we want the signed angle. So, we want the Atan2-based formula:

 float angleBetween(Vector3 a, Vector3 b) { return Math.Atan2(Vector3.Cross(a, b).Length, Vector3.Dot(a, b)); } 

Tada! we're done!

I will try to break down the step-by-step questions I'd take to solve this problem, with the hope it helps you to understand how to go about solving vector-related problems in the future.

Note: I'll be using radians, and even if your final on-screen output is in degrees I recommend you do calculations in radians as opposed to degrees, since they behave more nicely in a number of ways (for example, you don't have to use additional scaling factors when recalculating angular velocity or acceleration). There's a reason why just about any math library uses radians. Also, sin and cos are defined assuming angles increase going counterclockwise, so you may have to adjust for that. If you prefer clockwise angles and degrees, that's just a matter of multiplying by -1 and 180/pi respectively where appropriate.

Q) What is pitch?
A) pitch is the angle between a direction and the horizontal component of that direction (which we'll call heading). of course, "horizontal" depends on your definition of "up", so we use the gravity vector.

float pitch(Vector3 direction, Vector3 gravity) { Vector3 heading = projectOnPlane(direction, gravity); return angleBetween(direction, heading); } 

Q) What is Yaw?
A) Yaw is the angle between the heading and north. So, it looks very similar to the pitch equation:

float pitch(Vector3 direction, Vector3 gravity, Vector3 north) { Vector3 heading = projectOnPlane(direction, gravity); return angleBetween(direction, north); } 

Q) Okay, but how do I get the heading -- the "horizontal" component (i.e. perpendicular to gravity) of a direction?
A) formula: enter image description here See this formula from Wikipedia:Vector Projection, although you may find easier places to read on vector projection. To project on to a plane, you subtract the vector projection on the normal vector of the plane from the original vector. Or, phrased in english, to get the horizontal component of a vector, you subtract the vertical component from the original vector. Translated verbatim into code:

float projectOnPlane(Vector3 a, Vector3 b) { Vector3 bProjection = (Vector3.Dot(a, b) / b.Length) * (b / b.Length); return a - bProjection; } 

Q) How do I get the angle between two vectors?
A) Most places tell give you some Equation that looks like http://i.imgur.com/asWcnH0.png. However, this will return the same value for either a clockwise or counterclockwise rotation, and we want the signed angle. So, we want the Atan2-based formula:

 float angleBetween(Vector3 a, Vector3 b) { return Math.Atan2(Vector3.Cross(a, b).Length, Vector3.Dot(a, b)); } 

Tada! we're done!

Source Link
Jimmy
  • 9.1k
  • 1
  • 32
  • 44

I will try to break down the step-by-step questions I'd take to solve this problem, with the hope it helps you to understand how to go about solving vector-related problems in the future.

Note: I'll be using radians, and even if your final on-screen output is in degrees I recommend you do calculations in radians as opposed to degrees, since they behave more nicely in a number of ways (for example, you don't have to use additional scaling factors when recalculating angular velocity or acceleration). There's a reason why just about any math library uses radians. Also, sin and cos are defined assuming angles increase going counterclockwise, so you may have to adjust for that. If you prefer clockwise angles and degrees, that's just a matter of multiplying by -1 and 180/pi respectively where appropriate.

Q) What is pitch?
A) pitch is the angle between a direction and the horizontal component of that direction (which we'll call heading). of course, "horizontal" depends on your definition of "up", so we use the gravity vector.

float pitch(Vector3 direction, Vector3 gravity) { Vector3 heading = projectOnPlane(direction, gravity); return angleBetween(direction, heading); } 

Q) What is Yaw?
A) Yaw is the angle between the heading and north. So, it looks very similar to the pitch equation:

float pitch(Vector3 direction, Vector3 gravity, Vector3 north) { Vector3 heading = projectOnPlane(direction, gravity); return angleBetween(direction, north); } 

Q) Okay, but how do I get the heading -- the "horizontal" component (i.e. perpendicular to gravity) of a direction?
A) formula: enter image description here See this formula from Wikipedia:Vector Projection, although you may find easier places to read on vector projection. To project on to a plane, you subtract the vector projection on the normal vector of the plane from the original vector. Or, phrased in english, to get the horizontal component of a vector, you subtract the vertical component from the original vector. Translated verbatim into code:

float projectOnPlane(Vector3 a, Vector3 b) { Vector3 bProjection = (Vector3.Dot(a, b) / b.Length) * (b / b.Length); return a - bProjection; } 

Q) How do I get the angle between two vectors?
A) Most places tell give you some Equation that looks like http://i.imgur.com/asWcnH0.png. However, this will return the same value for either a clockwise or counterclockwise rotation, and we want the signed angle. So, we want the Atan2-based formula:

 float angleBetween(Vector3 a, Vector3 b) { return Math.Atan2(Vector3.Cross(a, b).Length, Vector3.Dot(a, b)); } 

Tada! we're done!