简体   繁体   English

如何围绕任意轴旋转一个点?

[英]How to rotate a point around an arbitrary axis?

I want to rotate a point in OpenGL around an arbitrary axis.我想围绕任意轴旋转 OpenGL 中的一个点。 I want to utilize that to rotate a sphere.我想利用它来旋转一个球体。

This is what I got so far:这是我到目前为止得到的:

float degreeBetweenTwoVec(glm::vec3 &a, glm::vec3 b)
{
    float prod = b.x * a.x + b.y * a.y + b.z * a.z;
    float mag_axis = sqrt((b.x * b.x) + (b.y * b.y) + (b.z * b.z));
    float mag_vec = sqrt((a.x * a.x) + (a.y * a.y) + (a.z * a.z));
    float degree = prod / (mag_axis * mag_vec);

    return acos(degree) * 180.0 / PI;;
}
void rotAroundZ(glm::vec3 &point, float degree) 
{
    glm::vec3 n_point;

    n_point.x = (point.x * cos(degree * PI / 180.0)) - (point.y * sin(degree * PI / 180.0));
    n_point.y = (point.x * sin(degree * PI / 180.0)) + (point.y * cos(degree * PI / 180.0));
    n_point.z = point.z;

    point.x = n_point.x;
    point.y = n_point.y;
    point.z = n_point.z;
}
void rotAroundY(glm::vec3& point, float degree)
{
    glm::vec3 n_point;

    n_point.x = (point.x * cos(degree * PI / 180.0)) + (point.z * sin(degree * PI / 180.0));
    n_point.y = point.y;
    n_point.z = ((point.x * -1.0f) * sin(degree * PI / 180.0)) + (point.z * cos(degree * PI / 180.0));;

    point.x = n_point.x;
    point.y = n_point.y;
    point.z = n_point.z;
}
void rotAroundA(glm::vec3& point, glm::vec3 &axis, float zdegree)
{
    float xdegree = degreeBetweenTwoVec(axis, glm::vec3{ 1.0f, 0.0f, 0.0f });
    float ydegree = degreeBetweenTwoVec(axis, glm::vec3{ 0.0f, 1.0f, 0.0f });

    rotAroundZ(point,  xdegree);
    rotAroundY(point,  ydegree);
    rotAroundZ(point,  zdegree);
    rotAroundY(point, -ydegree);
    rotAroundZ(point, -xdegree);
}
void rotAObject(Object& obj, glm::vec3 &axis, float degree)
{
    axis = glm::normalize(axis);
    translate(axis, glm::vec3{ axis.x, axis.y, axis.z });
    for (int i = 0; i < obj.vertices.size(); i++)
    {
        rotAroundA(obj.vertices[i], axis, degree);
    }
    rotAroundA(obj.mp, axis, degree);
    translate(axis, glm::vec3{ axis.x * -1.0f, axis.y * -1.0f, axis.z * -1.0f });
}

This works just fine if the given axis happens to be on one of the global axis.如果给定轴恰好位于全局轴之一上,则此方法工作得很好。 However, if it isn't and the given axis is basiclly rotating around something else.但是,如果不是,并且给定的轴基本上是围绕其他东西旋转。 There is some kind of axis it is rotating around but as soon as change the given axis, for example rotating it around the z axis it rotates around a completlly different axis than before.它正在围绕某种轴旋转,但是一旦改变给定的轴,例如围绕 z 轴旋转它,它就会围绕与以前完全不同的轴旋转。 It looks like for every position the given axis can take there is some other axis the object is actually rotating around.看起来对于每个 position 给定的轴可以采用 object 实际上在旋转的其他轴。

Any help is appreciated!任何帮助表示赞赏!

I recommend to use a rotation matrix.我建议使用旋转矩阵。 Use glm::rotate() , to set a rotation matrix by axis and angle .使用glm::rotate() ,通过轴和角度设置旋转矩阵
Convert the point to glm::vec4 and transform it by the rotation matrix:将点转换为glm::vec4并通过旋转矩阵对其进行变换:

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
glm::mat4 rot_mat = glm::rotate(glm::mat4(1.0f), glm::radians(degree), axis);
glm::vec3 n_point = glm::vec3(glm::vec4(point, 1.0f) * rot_mat);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM