Yaw conversion, step AND roll to vector x, y, z in world coordinates

I'm working on simple 3D graphics in OpenGL (java LWGJL), and I'm trying to figure out how to convert the yaw, pitch, and roll to the x, y, and z components of my Vector motion. I know how to do this using only pitch and yaw (as explained here ), but I did not find anything, explains how to integrate the roll into this formula.

I know that yawing and pitching is all that is needed to define a vector in three-dimensional space, but I also need a roll in this case. I have keys attached to various movements relative to the camera in the basic WASD configuration ( A is local to the left, W is local, and SPACE is local), so the roll affects the movement of the camera (for example, pressing D with a roll of pi / 2 (by default ) moves the camera to the right (in world coordinates), but pressing D with a roll of pi moves the camera up in world coordinates)).

Here is the code that I still have:

//b = back //f = forward //r = right //l = left //u = up //d = down private void move() { double dX = 0, dY = 0, dZ = 0; if (f ^ b) { dZ += cos(yaw) * cos(pitch) * (b ? 1 : -1); dX += sin(yaw) * cos(pitch) * (b ? 1 : -1); dY += -sin(pitch) * (b ? 1 : -1); } if (l ^ r) { dZ += sin(yaw) * sin(roll) * (l ? 1 : -1); dX += cos(yaw) * - sin(roll) * (l ? 1 : -1); dY += cos(roll) * (l ? 1 : -1); } if (u ^ d) //this part is particularly screwed up { dZ += sin(pitch) * sin(roll) * (u ? 1 : -1); dX += cos(roll) * (u ? 1 : -1); dY += cos(pitch) * sin(roll) * (u ? 1 : -1); } motion.x = (float) dX; motion.y = (float) dY; motion.z = (float) dZ; if (motion.length() != 0) { motion.normalise(); motion.scale(2); } x += motion.x; y += motion.y; z += motion.z; 

This works for several revolutions, but for many it leads to incorrect results.

So the question is:

How can I change my code so that it successfully calculates the x, y, and z components of my motion vector based on my desired direction (which key is pressed), given my yaw, step, and roll

I am fine using raw trig (as I try to do), a solution involving matrices or almost anything.

EDIT:

Please do not respond simply by referring to the Wikipedia article on Euler Angle. I read it and I don’t have a strong enough background in mathematics to understand how to apply it to my situation.

EDIT # 2:

I use only Euler angles to maintain my orientation between camera reorientations. For real manipulations with the camera, I use rotational matrices. If necessary, I can remove the angles of the Eulers and just use the matrix. All that matters is that I can convert from my orientation to a vector.

EDIT No. 3:

A solution was found by multiplying my vector forward by my rotation matrix, as described in the comment:

 //b = back //f = forward //r = right //l = left //u = up //d = down private Vector3f motion; protected void calcMotion() { //1 for positive motion along the axis, -1 for negative motion, 0 for no motion motion.x = r&&!l ? -1 : l ? 1 : 0; motion.y = u&&!d ? 1 : d ? -1 : 0; motion.z = f&&!b ? 1 : b ? -1 : 0; if (motion.length() == 0) { return; } motion.normalise(); //transform.getRotation() returns a Matrix3f containing the current orientation Matrix3f.transform(transform.getRotation(), motion, motion); } 

Still a problem with that .

+4
source share
2 answers

I don’t think you will find the answer to this clean trigger. Anyway, it is not elegant.

Euler's angle (Pitch / Yaw / Roll) is not suitable for this job. A problem with Gimble-lock will be a problem, as well as an ambiguity in the order of operations.

I suggest keeping the current rotational state of your objects in a matrix or quaternion. Use only Euler angles for relatively small deltas.

+3
source

You can use the homogeneous transformation matrix method, which is widely used to calculate the end position after all turns.

0
source

Source: https://habr.com/ru/post/1502489/


All Articles