首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >确定给定角度下绕轴的旋转矩阵

确定给定角度下绕轴的旋转矩阵
EN

Stack Overflow用户
提问于 2020-06-12 23:53:11
回答 1查看 365关注 0票数 0

我一直在尝试理解矩阵和向量,并实现了罗德里格的旋转公式,以确定给定角度下绕轴的旋转矩阵。我有一个函数Transform,它调用函数Rotate。

代码语言:javascript
运行
复制
        // initial values of eye ={0,0,7}
        //initial values of up={0,1,0}
        void Transform(float degrees, vec3& eye, vec3& up) {
            vec3 axis = glm::cross(glm::normalize(eye), glm::normalize(up));
            glm::normalize(axis);
            mat3 resultRotate = rotate(degrees, axis);
            eye = eye * resultRotate;
            glm::normalize(eye);
            up = up * resultRotate;`enter code here`
            glm::normalize(up);
            }
        mat3 rotate(const float degrees, const vec3& axis) {
        //Implement Rodrigue's axis-angle rotation formula
        float radDegree = glm::radians(degrees);
        float cosValue = cosf(radDegree);
        float minusCos = 1 - cosValue;
        float sinValue = sinf(radDegree);
        float cartesianX = axis.x;
        float cartesianY = axis.y;
        float cartesianZ = axis.z;
        mat3 myFinalResult = mat3(cosValue +(cartesianX*cartesianX*minusCos), ((cartesianX*cartesianY*minusCos)-(cartesianZ*sinValue)),((cartesianX*cartesianZ*minusCos)+(cartesianY*sinValue)),
        ((cartesianX*cartesianY*minusCos)+(cartesianZ*sinValue)), (cosValue+(cartesianY*cartesianY*minusCos)), ((cartesianY*cartesianZ*minusCos) - (cartesianX*sinValue)),
        ((cartesianX*cartesianZ*minusCos)-(cartesianY*sinValue)),     ((cartesianY*cartesianZ*minusCos) + (cartesianX*sinValue)), ((cartesianZ*cartesianZ*minusCos) + cosValue));
         return myFinalResult;
        }

所有的值、结果旋转矩阵和改变后的矢量对于+旋转角度都是预期的,但是对于负角是错误的,并且从那时起,在所有矢量被重新初始化之前具有级联效应。有没有人能帮我解决这个问题?我不能使用像glm::rotate这样的内置函数。

EN

回答 1

Stack Overflow用户

发布于 2020-06-13 16:50:38

我不使用Rodrigues_rotation_formula,因为它需要在运行时计算方程系统,并且在更高的维度上会变得非常复杂。

相反,我使用的是axis aligned incremental rotations4x4 homogenous transform matrices,它们非常容易移植到像4D rotors这样的更高维度。

现在有了局部和全局旋转。局部旋转将围绕您的矩阵坐标系旋转,局部轴和全局轴将围绕世界(或主坐标系)旋转。

你想要的是围绕一些point,axisangle创建一个转换矩阵。要做到这一点,只要:

  1. create a transform matrix A

它有一个轴与旋转轴对齐,原点是旋转中心。为了构造这样的矩阵,你需要两个垂直的向量,这两个向量很容易通过product.

  • rotate A angle围绕其局部轴与旋转轴对齐的交叉获得。

通过简单地将A乘以轴对齐的增量旋转R

在rotation A之前A*R;

  • revert A的原始变换

通过简单地将A的倒数与结果相乘

A*R*Inverse(A);

  • apply this on M you want to M(在矩阵上旋转此文件,您想要旋转此文件)

也可以通过简单地将其乘以M来实现:

M*=A*R*Inverse(A);

就是这样。你可以在这里找到3D OBB approximation

代码语言:javascript
运行
复制
template <class T> _mat4<T> rotate(_mat4<T> &m,T ang,_vec3<T> p0,_vec3<T> dp)
    {
    int i;
    T c=cos(ang),s=sin(ang);
    _vec3<T> x,y,z;
    _mat4<T> a,_a,r=mat4(
         1, 0, 0, 0,
         0, c, s, 0,
         0,-s, c, 0,
         0, 0, 0, 1);
    // basis vectors
    x=normalize(dp);    // axis of rotation
    y=_vec3<T>(1,0,0);  // any vector non parallel to x
    if (fabs(dot(x,y))>0.75) y=_vec3<T>(0,1,0);
    z=cross(x,y);       // z is perpendicular to x,y
    y=cross(z,x);       // y is perpendicular to x,z
    y=normalize(y);
    z=normalize(z);
    // feed the matrix
    for (i=0;i<3;i++)
        {
        a[0][i]= x[i];
        a[1][i]= y[i];
        a[2][i]= z[i];
        a[3][i]=p0[i];
        a[i][3]=0;
        } a[3][3]=1;
    _a=inverse(a);
    r=m*a*r*_a;
    return r;
    };

它就是这么做的。其中m是要转换的原始矩阵(并返回旋转后的矩阵),ang[rad]中的有符号角度,p0是旋转中心,dp是旋转方向矢量的轴。

这种方法没有任何奇点,也没有负角度旋转的问题……

如果你想在glm或任何其他GLSL中使用它,只需将模板更改为您所使用的float,vec3,mat4,而不是T,_vec3<T>,mat4<T>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62347917

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档