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

Posted

技术标签:

【中文标题】如何围绕任意轴旋转一个点?【英文标题】:How to rotate a point around an arbitrary axis? 【发布时间】:2020-06-07 00:35:35 【问题描述】:

我想在 OpenGL 中围绕任意轴旋转一个点。我想利用它来旋转一个球体。

这是我目前得到的:

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 );

如果给定的轴恰好在全局轴之一上,这很好用。但是,如果不是,并且给定的轴基本上是围绕其他东西旋转。它正在围绕某种轴旋转,但是一旦改变给定的轴,例如围绕 z 轴旋转它,它就会围绕与以前完全不同的轴旋转。看起来对于给定轴可以采取的每个位置,对象实际上都在围绕其他轴旋转。

感谢任何帮助!

【问题讨论】:

【参考方案1】:

我建议使用旋转矩阵。使用glm::rotate(),通过axis and angle 设置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);

【讨论】:

以上是关于如何围绕任意轴旋转一个点?的主要内容,如果未能解决你的问题,请参考以下文章

围绕给定轴旋转任意平面会导致结果不一致

将围绕任意轴的旋转解析为围绕 X、Y 和 Z 轴的旋转

使用OpenGL如何实现物体绕体外任意轴旋转?

如何制作用于围绕 z 轴旋转三角形的特征模型矩阵

如何围绕任意点旋转对象?

如何在 Pygame 中围绕偏离中心的枢轴旋转图像