Home > Software engineering >  Angles of a Point with X, Y, Z using GLM
Angles of a Point with X, Y, Z using GLM

Time:06-30

I have two points, one represents the cursor(a cube) and another one represents the position of the Camera.

Now to find out which face the camera is facing I have done something like this

    glm::vec3 direction = glm::normalize(cursorPos - cameraPos);
    float angle_x, angle_y, angle_z; 

    angle_x = glm::dot(direction, vec3(1.0f, 0.0f, 0.0f));   // in terms of cosine
    angle_x = glm::acos(angle_x);    // in terms of radians
    angle_x = glm::degrees(angle_x); // in terms of degrees

    angle_y = glm::dot(direction, vec3(0.0f, 1.0f, 0.0f));   // in terms of cosine
    angle_y = glm::acos(angle_y);    // in terms of radians
    angle_y = glm::degrees(angle_y); // in terms of degrees

    angle_z = glm::dot(direction, vec3(0.0f, 0.0f, 1.0f));   // in terms of cosine
    angle_z = glm::acos(angle_z);    // in terms of radians
    angle_z = glm::degrees(angle_z); // in terms of degrees

    bool x_45     = angle_x <= 45; 
    bool x_135    = angle_x > 135;

    bool y_45     = angle_y <= 45; 
    bool y_135    = angle_y > 135;

    bool z_45     = angle_z <= 45;
    bool z_135    = angle_z > 135;


    if (x_45)
    {
        std::cout << "facing left face\n"; 
    }
    else if (x_135)
    {
        std::cout << "facing right face\n";
    }
    else if (y_45)
    {
        std::cout << "facing up face\n";
    }
    else if (y_135)
    {
        std::cout << "facing down face\n";
    }
    else if (z_45)
    {
        std::cout << "facing front face\n";
    }
    else if (z_135)
    {
        std::cout << "facing back face\n";
    }    

Why do angles that are getting calculated only in the range (0, 180) with the axis?

It's leading to calculated angles as:

"Angle with x: 62.9398 Angle with y: 47.5 Angle with z: 125.464"

Which should only be possible if the calculated angle range is in (0, 360)?

What is happening right now( I assume) is that it's getting calculated without the consideration of another axis, as shown in the below image.

enter image description here

I am sure this is the most brute way to do this, if anyone has other solution please tell. --Maybe something like converting that normalized vector in its quaternion rotation represtation and getting euler angels out of it?

CodePudding user response:

You made this code hard to understand and maintain. Here is method which do not need large mind power.

Just 6 vectors defining directions and trying find one which is closest to direction:

Facing findOrientation(glm::vec3 direction)
{
    struct FacingNormalizations {
        Facing facing;
        glm::vec3 v;
    };

    constexpr std::array facings {
        FacingNormalizations { Facing::back, { 0, 0, 1 } },
        FacingNormalizations { Facing::right, { 1, 0, 0 } },
        FacingNormalizations { Facing::up, { 0, 1, 0 } },
        FacingNormalizations { Facing::front, { 0, 0, -1 } },
        FacingNormalizations { Facing::left, { -1, 0, 0 } },
        FacingNormalizations { Facing::down, { 0, -1, 0 } },
    };

    auto r = std::max_element(facings.begin(), facings.end(),
        [direction](const auto& a, const auto& b) {
            return dot(direction, a.v) < dot(direction, b.v);
        });

    return r->facing;
}

https://godbolt.org/z/nqjGbMK54

Note if you need to add some extra direction it is easy. If you like to make some direction more privileged, you should just make respective vector longer.

  • Related