Search code examples
c++rotationglm-math

How to rotate an object around a point with GLM OpenGL C++?


I'm trying to do something like this, but for some reason my cube still rotates around the origin. What am I doing wrong?

glm::mat4 identity = glm::mat4(1.0f); // construct identity matrix

glm::mat4 trans;
glm::mat4 rot;
glm::mat4 transBack;
glm::mat4 M;

glm::vec4 br = glm::vec4(currentPositionX - 0.4, 0.0f, currentPositionZ + 1.2, 1.0f);

//get the matrix transformation to translate
trans = glm::translate(identity, glm::vec3(+0.4, 0.0f, -1.2));

identity = glm::mat4(1.0f); // construct identity matrix
//get the matrix transformation to rotate
rot = glm::rotate(identity, glm::radians(rotation), glm::vec3(0.0, 1.0, 0.0));  // rotate with car ROT -

identity = glm::mat4(1.0f); // construct identity matrix
//get the matrix transformation to translate
transBack = glm::translate(identity, glm::vec3(-0.4, 0.0f, +1.2));

M = transBack * rot * trans;

// A' = M . A , A being a point 
br = M * br;

Solution

  • Formula to rotate a point around (x,y,z) is:

    T(x,y,z) * R * T(-x,-y,-z)   // operations are combined from right to left
    

    you have to move the point P(x,y,z) to center of locale coordinate system, apply rotate and translate back to world space.

    auto rotAroundPoint(float rad, const glm::vec3& point, const glm::vec3& axis)
    {
    auto t1 = glm::translate(glm::mat4(1),-point);
    auto r = glm::rotate(glm::mat4(1),rad,axis);
    auto t2 = glm::translate(glm::mat4(1),point);
    return t2 * r * t1;
    }
    
    int main() {
    glm::vec4 geom(0,0,0,1); // one point of cube geometry
    glm::vec3 o(6,0,6); // origin of rotation
    glm::vec3 cp(5,0,5); // current position of cube
    for (float deg : {0.f,90.f,180.f,270.f}) {
        auto res = rotAroundPoint(glm::radians(deg),o,glm::vec3(0,1,0)) * 
            glm::translate(glm::mat4(1),cp) * geom;
        std::cout << glm::to_string(res) << std::endl;
    }
    /*
          ------------------> x
          |
          |
          |            cp(5,5)         (7,5)
          |                    o(6,6)
          |            (5,7)           (7,7)
          |
          z
    */
    

    godbolt demo