Skip to content

Vectors, Location, Yaw and Pitch in C#raft

spazzarama edited this page Nov 13, 2011 · 8 revisions

The Minecraft protocol defines a coordinate system that has East running along the Z+ axis, and North along the X+ axis, with up being the Y+ axis. The protocol uses non-standard approaches to the pitch and yaw that have resulted in specific changes in the vector implementation. If reusing the Vector3 class it is important to be aware of these quirks.

Pitch (rotation around the X-axis)

Pitch in the Minecraft protocol has -90 as straight up and 90 as straight down, 0 being directly level ahead. The Vector3 class reflects this within its “facing direction” constructor taking a yaw and pitch to generate a unit vector.

 public Vector3(double yawDegrees, double pitchDegrees)
{
...
    // Y based on the angle of pitch. We negate because -90 points up and should be +1 not -1
    Y = -Math.Sin(pitch.ToRadians());
...

Yaw (rotation around the Y-axis)

The Minecraft protocol differs to conventional trigonometry when dealing with the Yaw angle.

Yaw is measured in degrees, and does not follow classical trigonometry rules.
The unit circle of yaw on the xz-plane starts at (0, 1) and turns backwards towards (-1, 0),
or in other words, it turns clockwise instead of counterclockwise.
http://mc.kev009.com/Protocol#Player_Look_.280×0C.29

This all stems from the fact that in Minecraft North = x- instead of x+.

So when visualising the xz-plane using conventional trigonometry you must pretend you are looking from the ground to the sky, rather than looking down from the sky to the ground (the radians / degrees go counter-clockwise). This diagram shows the Minecraft X, Z, and Yaw positive directions (notice that x+ points up, but is south, and z+ is east):
Minecraft X and Z axis represented using conventional trigonometry - counter-clockwise radians

Here is a more natural diagram (x- is north and z+ is east in the true sense), although the direction of angles in the circle are now clockwise instead of counter-clockwise:
Minecraft X and Z axis represented with clockwise radians(remember also that 270 degrees is equal to -90)

This change of direction necessitates the following changes when dealing with the Sine of angles of Yaw in the Vector3 class:

1. Creating a “Facing Direction” unit Vector – Vector3.ctor(double yaw, double pitch)

...
// Shorten X down from 1 based on the angle of pitch
// We negate because a yaw of -90 or 270 (South) should
// be +1 not -1 (yaw+ is clockwise whereas radians are normally counter-clockwise)
X = -(cosPitchRadians * Math.Sin(yawRadians)); 
...

2. Rotating a Vector around the Y-axis – Vector3.Yaw(double)

...
// Negate Sine as X+ is North in trigonometry rules and we need it to be South, Z+ is east, angle+ is clockwise
double x = (v1.Z * -Math.Sin(yawAngle)) + (v1.X * Math.Cos(yawAngle));
double y = v1.Y;
// Negate Sine as X+ is normally North in trigonometry and we need it to be South, Z+ is east, angle+ is clockwise
double z = (v1.Z * Math.Cos(yawAngle)) - (v1.X * -Math.Sin(yawAngle));
return new Vector3(x, y, z);
...

3. Lastly determining the signed angle between vectors (which way to rotate for shortest angle to point at destination vector) – Vector3.SignedAngle

public static double SignedAngle(Vector3 source, Vector3 dest, Vector3 destsRight)
{
...
// Note: destsRight is a Vector perpendicular to the right (+90 degrees in yaw+ clockwise world) of the vector "dest"
double rightDot = Vector3.DotProduct(source, destsRight);
...
// If angle+ was counter-clockwise instead of clockwise this would be 'rightDot < 0.0'
if (rightDot > 0.0) 
    angleBetween *= -1.0;
...
Clone this wiki locally