Search code examples
c++openglglm-mathcoordinate-transformationatan2

atan2f() doesn't work


I try to change the orientation of my objects towards the center with atan2f but it's give me the wrong value. Am I wrong somewhere ?

glm::vec3 center = glm::vec3(0.4f, 0.4f, 0.0f);
for(int i = 0; i < num; i++){
  float rel = i / (float) num;
  float angle = rel * M_PI * 2;
  glm::vec3 position = glm::vec3(cos(angle), glm::sin(angle), position.z);

  position.x *= radius; position.y *= radius;
  position.x += center; position.y += center;
  glm::mat4 trans = glm::translate(glm::mat4(1.0f), position);

  float newAngle = atan2f(position.y - center.y, position.x - center.x);

  glm::mat4 rotation = glm::rotation(glm::mat4(1.0f), newAngle, glm::vec3(0, 0, 1));

  numModel.at(i) = trans * rotation;
}

Solution

  • If you want to rotate an object around the center of the world you have to set up a rotation matrix first:

    float angle = ...;
    glm::vec3 rotAxis( ... );
    glm::mat4 rotMat = glm::rotation( glm::mat4(1.0f), angle, rotAxis );
    

    Note the glm::rotation function calculates the sine and the cosine of the angle and sets the appropriate fields inside the matrix.

    2nd you have to setup your objects position matrix, this is the matrix which describes the initial position of the object:

    glm::vec3 position( radius, 0.0f, 0.0f );
    glm::mat4 transMat = glm::translate( glm::mat4(1.0f), position );
    

    To rotate the object around the center of the world you have to multiply the rotation matrix rotMat by the model matrix transMat, because the rotation matrix defines the reference system, for placing the object.

    glm::mat4 modelMat = rotMat * transMat;
    

    If you want to rotate an object around its own origin you have first to place your object in the world and then you have to rotate it:

    glm::mat4 modelMat = transMat * rotMat;
    

    See also the answer to the question OpenGL transforming objects with multiple rotations of Different axis

    In your case, where you want that the object is directed to the center of the world, you first have to translate the object to its place. 2nd you have to calculate the angle between the X-axis of the world and the direction from the object to the center. Finally you have to turn the object in the opposite direction.

     glm::vec3 position( ... );
     glm::vec3 center( ... );
     glm::mat4 transMat = glm::translate( glm::mat4(1.0f), position );
    
     float angle = atan2f(center.y - position.y, center.x - position.x);
    
     glm::vec3 rotAxis( 0.0f, 0.0f, 1.0f );
     glm::mat4 rotMat = glm::rotation( glm::mat4(1.0f), -angle, rotAxis );
    
     glm::mat4 modelMat = transMat * rotMat;