Rotate $xyz$ by use of pitch and yaw around origin

672 Views Asked by At

I have a project for a game which uses pitch/yaw for the direction of a players head. The pitch ranges from $0$ to $180$ and the yaw is $0$ to $360$.

Yaw modifies $X$ and $Z$, pitch modifies the $Y$, however I need to keep the $xyz$ at this distance from the origin $(0,0,0)$. So modifying the $Y$ means that the $X$ and $Z$ need to be modified in order to keep the $xyz$ this distance away from the origin.

I asked in the gaming community, and the large majority of replies came up with this. https://github.com/md-5/SmallPlugins/blob/master/TestPlugin/src/main/java/net/md_5/TestPlugin.java#L101

The problem is, the $X$ and $Z$ curve inwards as the pitch approaches the upper and lower limits. http://upload.wikimedia.org/wikipedia/commons/7/7e/Sphere_wireframe_10deg_6r.svg

I ask that you don't reply with the formulas found in Wikipedia, as I can't understand the more complex ones. But rather post it in a single line such as "$\cos(x)\cdot$(pitch + yaw)"

1

There are 1 best solutions below

7
On

If you just want to define a heading direction based on absolute pitch and yaw angles, then the code they gave you is correct, but they swapped Y and Z from your definition. This is what you'd want:

    double sRadians = Math.toRadians( yaw );
    double tRadians = Math.toRadians( pitch );
    double x = radius * Math.cos( sRadians ) * Math.sin( tRadians );
    double y = radius * Math.cos( tRadians );
    double z = radius * Math.sin( sRadians ) * Math.sin( tRadians );

Which is just specifying a vector of length radius in spherical coordinates given by yaw and pitch in degrees, as you specified.

Also, could you please clarify:

The problem is, the X and Z curve inwards as the pitch approaches the upper and lower limits.

You need this behavior in order for the vector to have a fixed length. It's how the coordinate system works.

If you actually want to rotate a given vector given pitch and yaw angles, then you need to specify an order in which the two rotations will take place, as 3D rotations are not commutative.

EDIT: now that the context is clear, just make:

double textDistance = /* distance to text relative to the player */;
double textPitch = /* pitch of the text relative to player's pitch */;
double textYaw = /* yaw of the text relative to player's yaw */;
double sRadians = Math.toRadians( playerYaw + textYaw );
double tRadians = Math.toRadians( playerPitch + textPitch );
double x = textDistance * Math.cos( sRadians ) * Math.sin( tRadians );
double y = textDistance * Math.cos( tRadians );
double z = textDistance * Math.sin( sRadians ) * Math.sin( tRadians );

Then add $(x,y,z)$ to the player's coordinate to get the text's coordinate.