# Moving an object at an angle based on quaternion rotation matrix (c++)

I have been trying to figure this out for a while now, and can't seem to get a working method. I am building a space ship movement with the following movement keys:

P = accelerate (move forward)

A = yaw left

D = yaw right

W = pitch down

S = pitch up

The following the code I have to perform the movements for keys A,D,W and S. They all work as expected. I just can't figure out how to move forward at the angle the space ship is.

void Player::yawRight(float deltaTime)
{
this->yaw -= this->rotationAngle * deltaTime;

if (this->yaw < 0.0f) {
this->yaw = 360.0f;
}

cout << "yawRight: " + to_string(this->yaw) << endl;

this->yawQuat = glm::angleAxis(glm::radians(this->yaw), glm::vec3(0, 1, 0));
this->pitchQuat = glm::angleAxis(glm::radians(this->pitch), glm::vec3(0, 0, 1));
this->rollQuat = glm::angleAxis(glm::radians(this->roll), glm::vec3(0, 0, 1));

glm::mat4 rotationMatrix = glm::toMat4(glm::normalize(this->yawQuat * this->pitchQuat * this->rollQuat));

this->model = glm::mat4(1.0f);
this->model = glm::translate(this->model, this->position) * rotationMatrix;
}

void Player::yawLeft(float deltaTime)
{
this->yaw += this->rotationAngle * deltaTime;

if (this->yaw > 360.0f) {
this->yaw = 0.0f;
}

cout << "yawLeft: " + to_string(this->yaw) << endl;

this->yawQuat = glm::angleAxis(glm::radians(this->yaw), glm::vec3(0, 1, 0));
this->pitchQuat = glm::angleAxis(glm::radians(this->pitch), glm::vec3(0, 0, 1));
this->rollQuat = glm::angleAxis(glm::radians(this->roll), glm::vec3(0, 0, 1));

glm::mat4 rotationMatrix = glm::toMat4(glm::normalize(this->yawQuat * this->pitchQuat * this->rollQuat));

this->model = glm::mat4(1.0f);
this->model = glm::translate(this->model, this->position) * rotationMatrix;
}

void Player::pitchDown(float deltaTime)
{
this->pitch += this->rotationAngle * deltaTime;

if (this->pitch > 360.0f) {
this->pitch = 0.0f;
}

cout << "pitchDown: " + to_string(this->pitch) << endl;

this->yawQuat = glm::angleAxis(glm::radians(this->yaw), glm::vec3(0, 1, 0));
this->pitchQuat = glm::angleAxis(glm::radians(this->pitch), glm::vec3(0, 0, 1));
this->rollQuat = glm::angleAxis(glm::radians(this->roll), glm::vec3(0, 0, 1));

glm::mat4 rotationMatrix = glm::toMat4(glm::normalize(this->yawQuat * this->pitchQuat * this->rollQuat));

this->model = glm::mat4(1.0f);
this->model = glm::translate(this->model, this->position) * rotationMatrix;
}

void Player::pitchUp(float deltaTime)
{
this->pitch -= this->rotationAngle * deltaTime;

if (this->pitch < 0.0f) {
this->pitch = 360.0f;
}

cout << "pitchDown: " + to_string(this->pitch) << endl;

this->yawQuat = glm::angleAxis(glm::radians(this->yaw), glm::vec3(0, 1, 0));
this->pitchQuat = glm::angleAxis(glm::radians(this->pitch), glm::vec3(0, 0, 1));
this->rollQuat = glm::angleAxis(glm::radians(this->roll), glm::vec3(0, 0, 1));

glm::mat4 rotationMatrix = glm::toMat4(glm::normalize(this->yawQuat * this->pitchQuat * this->rollQuat));

this->model = glm::mat4(1.0f);
this->model = glm::translate(this->model, this->position) * rotationMatrix;
}

void Player::accelerate(float deltaTime)
{

glm::vec3 front = glm::vec3(x,y,z);
front = glm::normalize(front);
glm::vec3 right = glm::normalize(glm::cross(front, glm::vec3(0, 1, 0)));

glm::mat4 rotationMatrix = glm::toMat4(glm::normalize(this->yawQuat * this->pitchQuat * this->rollQuat));

this->position += front * 0.01f;

this->model = glm::mat4(1.0f);
this->model = glm::translate(this->model, this->position) * rotationMatrix;
}

void Player::accelerate(float deltaTime)
{
// get the forward vector

glm::vec3 front = glm::vec3(x,y,z);
front = glm::normalize(front);

glm::mat4 rotationMatrix = glm::toMat4(glm::normalize(this->yawQuat * this->pitchQuat * this->rollQuat));

// update the position
// this is incorrect
this->position += front * 0.01f;

this->model = glm::mat4(1.0f);
this->model = glm::translate(this->model, this->position) * rotationMatrix;
}


Note: the actual code is crappy as it has a lot of reptition, I will fix that.

For the accelerate() method I get the forwad vector from the yaw and pitch, but it doesn't move in the right direction. Can someone provide me a guide or an explanation as to how I can make the ship move forward in the orientation it current is in? Thanks!

• Can you show us some example cases, indicating the direction you expect the object to move, versus the direction it actually moves? By comparing the relationship between the right & wrong output, we can often deduce a pattern to the symptoms that helps track down the root cause. Dec 4, 2018 at 12:42

I'm not sure if this question is actually about quaternions or about orienting an object in 3D space via Euler angles. It seems your main concern is object orientation, so that is what I'll focus on in this answer.

For the sake of this answer:
x-axis rotation: pitch
y-axis rotation: yaw
z-axis rotation: roll

//orient the game object in 3D space and move it (pseudo-code)
void MoveGameObject(float xMove, float yMove)
{
//add the move amount for this frame to the rotation angles
gYaw += xMove;
gPitch += yMove;

//make sure: 90 > pitch > -90
if(gPitch < -90.0f)
{
gPitch = -90.0f;
}
else if(gPitch > 90.0f)
{
gPitch = 90.0f;
}

float yawRad = gYaw * (3.14 / 180.0f);
float pitchRad = gPitch * (3.14 / 180.0f);

//convert orientation to spherical coordinates
Vector3 tar;
tar.normalize();

//move forward
if(direction == FORWARD)
{
position += tar * speed;
}
//move back
if(direction == BACK)
{
position -= tar * speed;
}
//move left
if (direction == LEFT)
{
Vector3 leftVector = tar;
leftVector = leftVec.crossproduct(0, 1, 0);
leftVector.normalize();
position -= leftVector * speed;
}
//move right
if(direction == RIGHT)
{
Vector3 rightVector = tar;
rightVector = rightVector.crossproduct(0, 1, 0);
rightVector.normalize();
position += rightVector * speed;
}
}


This code will move your object in the correct direction based on its orientation.
An excellent tutorial on this sort of thing.

• You probably don't need to normalize tar - it's unit length by construction, to within floating point precision. ;) Dec 4, 2018 at 14:04

The most common problem for beginners, is the multiplication order of the rotational matrices, and determine what coordinate system is used left/right handed, and whether axis-Y is up or forward etc. You'll need to know exact understanding what being used, and what your math will result into.

• This looks more like a comment, and doesn't appear to offer a solution for how to move an object along its local forward vector after rotating it. Can you edit your answer to elaborate? Dec 4, 2018 at 12:40