0
$\begingroup$

What do I have now? I have a cube consisting of 6 planes. All these planes I generate in XY coordinates and then place them by matrix transformations.

введите сюда описание изображения

I need to rotate my cube along the global axis and move my planes along cube rotation;

I rotate the cube введите сюда описание изображения

Then I need to move one of the planes correctly. But the planes move along the global axis. The red line shows how the plane moves now. The green line shows how it should move. введите сюда описание изображения

How I create a cube. All vertices are in the range (0,0) - (2, 2);

    planeXY.setupMesh();
    planeXY.setOrigin({1, 1, 1});
    
    planeXY1.setupMesh();
    planeXY1.setOrigin({1, 1, 1});
    planeXY1.moveAlongGlobalAxis(QVector3D(0.0, 0.0, 2.0));
    
    planeZY.setupMesh();
    planeZY.setOrigin({1, 1, 1});
    planeZY.rotate(QVector3D(0.0f, -90.0f, 0.0f));
    planeZY.moveAlongGlobalAxis(QVector3D(-2.0, 0.0, 0.0));
    
    
    planeZY1.setupMesh();
    planeZY1.setOrigin({1, 1, 1});
    planeZY1.rotate(QVector3D(0.0f, -90.0f, 0.0f));
    
    planeXZ.setupMesh();
    planeXZ.setOrigin({1, 1, 1});
    planeXZ.rotate(QVector3D(90.0f, 0.0f, 0.0f));
    planeXZ.moveAlongGlobalAxis(QVector3D(0.0, -2.0, 0.0));
    
    planeXZ1.setupMesh();
    planeXZ1.setOrigin({1, 1, 1});
    planeXZ1.rotate(QVector3D(90.0f, 0.0f, 0.0f));

Mesh.cpp

void Mesh::moveAlongGlobalAxis(QVector3D coordinates)
{
    QMatrix4x4 identityMatrix;   
    identityMatrix.translate(coordinates);
    position += coordinates;
    this->translationMatrix = identityMatrix * translationMatrix;
}

void Mesh::moveAlongLocalAxis(QVector3D coordinates)
{   
    this->moveAlongGlobalAxis(coordinates); 
}

void Mesh::rotate(QVector3D rotation)
{
    QMatrix4x4 identityMatrix;
    
    identityMatrix.translate((-1) * this->position + this->origin);
    identityMatrix.rotate(rotation.x(), QVector3D(1.0, 0.0, 0.0));
    identityMatrix.rotate(rotation.y(), QVector3D(0.0, 1.0, 0.0));
    identityMatrix.rotate(rotation.z(), QVector3D(0.0, 0.0, 1.0));
    identityMatrix.translate(this->position - this->origin);
    this->rotationMatrix =  identityMatrix * this->rotationMatrix;
}


void Mesh::setOrigin(QVector3D origin)
{
    this->origin = origin;
}

const QMatrix4x4 Mesh::getModelMatrix() const
{
    
    return translationMatrix * rotationMatrix;
}

This function I want to implement:

void Mesh::moveAlongLocalAxis(QVector3D coordinates)
{   
    this->moveAlongGlobalAxis(coordinates); 
}

How I rotate my cube

else if(ev->key() == Qt::Key_R)
    {
        
        
        
        planeXY.rotate(QVector3D(20.0f, 0.0f, 0.0f));
        planeXY1.rotate(QVector3D(20.0f, 0.0f, 0.0f));
        planeZY.rotate(QVector3D(20.0f, 0.0f, 0.0f));
        planeZY1.rotate(QVector3D(20.0f, 0.0f, 0.0f));
        planeXZ.rotate(QVector3D(20.0f, 0.0f, 0.0f));
        planeXZ1.rotate(QVector3D(20.0f, 0.0f, 0.0f));
    
    }
$\endgroup$

1 Answer 1

1
$\begingroup$

Think about matrix multiplications as transforming data from one coordinate system to another. So initially, your cubes' local coordinate system is identical to the "global" coordinate system. Every translation in the "global" system along one of its coordinate axes is a single component in the translation vector.

Now you rotate your cube and its local coordinate system so that they are no longer aligned with the "global" one. By the transformation order you chose, the translations are applied in the "global" system. If you want to apply a translation that was defined in your cubes' local coordinate system, you have to transform the translation vector into the "global" one first. In your case, the green line is one of the axes in the local coordinate system. So locally, the translation vector along this axis has one coordinate different from 0. But in the "global" one, all components might differ from 0.

So how do we find this vector? Fortunately, it is pretty simple since you already know how to transform between both coordinate systems. You already did it with the cube. So just apply the rotations you used for your vertices. Unless I missed something in your code or made any other mistake, the function should look like this:

void Mesh::moveAlongLocalAxis(QVector3D coordinates)
{   
    // transform local translation to global coordinate system
    coordinates = this->rotationMatrix * coordinates
    this->moveAlongGlobalAxis(coordinates); 
}

Note that I oversimplified some things in the text above that was tailored to help you out with your specific problem. Coordinate systems and transformations are not particularly hard to understand, but it needs some time to adapt the correct mental model. You always have to keep in mind in which coordinate system you ended up after a set of transformations and how rotations and translations have to be applied to get you to the next one. I recommend this site to get a better understanding of the topic.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.