利用四元树来计算一个坐标点绕任意轴旋转后,新坐标点的推导过程

 利用四元树来计算一个坐标点绕任意轴旋转后,新坐标点的推导过程(参考《(中文版)3D数学基础图形与游戏开发.pdf》):

 

 

参考源代码:

void Quaternion::setToRotateAboutAxis(const Vector3 &axis, float theta)

{

// The axis of rotation must be normalized

assert(fabs(vectorMag(axis) – 1.0f) < .01f);

// Compute the half angle and its sin

float thetaOver2 = theta * .5f;

float sinThetaOver2 = sin(thetaOver2);

// Set the values

w = cos(thetaOver2);

x = axis.x * sinThetaOver2;

y = axis.y * sinThetaOver2;

z = axis.z * sinThetaOver2;

}

 

最终的R(n, θ)矩阵为:

――――――

OSG中将四元树转换为矩阵(Matrix_implementation.cpp):

#define QX  q._v[0]

#define QY  q._v[1]

#define QZ  q._v[2]

#define QW  q._v[3]

void Matrix_implementation::setRotate(const Quat& q)

{

double length2 = q.length2();

。。。。。。

rlength2 = 2.0/length2;

 

x2 = rlength2*QX;

        y2 = rlength2*QY;

        z2 = rlength2*QZ;

       

        xx = QX * x2;

        xy = QX * y2;

        xz = QX * z2;        

yy = QY * y2;

        yz = QY * z2;

        zz = QZ * z2;

       

        wx = QW * x2;

        wy = QW * y2;

        wz = QW * z2;

_mat[0][0] = 1.0 - (yy + zz);

        _mat[1][0] = xy - wz;

        _mat[2][0] = xz + wy;       

       

        _mat[0][1] = xy + wz;

        _mat[1][1] = 1.0 - (xx + zz);

        _mat[2][1] = yz - wx;

        

        _mat[0][2] = xz - wy;

        _mat[1][2] = yz + wx;

        _mat[2][2] = 1.0 - (xx + yy);

}

――――――

3.从矩阵转换到四元树:

OSG中将矩阵转换为四元树(Matrix_implementation.cpp):

#define QX  q._v[0]

#define QY  q._v[1]

#define QZ  q._v[2]

#define QW  q._v[3]

Quat Matrix_implementation::getRotate() const

{

    Quat q;

    value_type s;

    value_type tq[4];

    int    i, j;

    // Use tq to store the largest trace

    tq[0] = 1 + _mat[0][0]+_mat[1][1]+_mat[2][2];

    tq[1] = 1 + _mat[0][0]-_mat[1][1]-_mat[2][2];

    tq[2] = 1 - _mat[0][0]+_mat[1][1]-_mat[2][2];

    tq[3] = 1 - _mat[0][0]-_mat[1][1]+_mat[2][2];

 

    // 找4个中最大的

    j = 0;

    for(i=1;i<4;i++) j = (tq[i]>tq[j])? i : j;

 

    // check the diagonal

    if (j==0)

    {

        /* perform instant calculation */

        QW = tq[0];

        QX = _mat[1][2]-_mat[2][1];

        QY = _mat[2][0]-_mat[0][2];

        QZ = _mat[0][1]-_mat[1][0];

    }

    else if (j==1)

    {

        QW = _mat[1][2]-_mat[2][1];

        QX = tq[1];

        QY = _mat[0][1]+_mat[1][0];

        QZ = _mat[2][0]+_mat[0][2];

    }

    else if (j==2)

    {

        QW = _mat[2][0]-_mat[0][2];

        QX = _mat[0][1]+_mat[1][0];

        QY = tq[2];

        QZ = _mat[1][2]+_mat[2][1];

    }

    else /* if (j==3) */

    {

        QW = _mat[0][1]-_mat[1][0];

        QX = _mat[2][0]+_mat[0][2];

        QY = _mat[1][2]+_mat[2][1];

        QZ = tq[3];

    }

 

    s = sqrt(0.25/tq[j]);

    QW *= s;

    QX *= s;

    QY *= s;

    QZ *= s;

 

    return q;

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在MATLAB中实现三维坐标任意旋转需要使用旋转矩阵来进行计算。以下是一个简单的步骤: 1. 定义旋转旋转角度:首先需要确定旋转向量,这个向量应该是一个单位向量,并且需要确定旋转的角度。 2. 构建旋转矩阵:根据给定的旋转旋转角度,可以用 Rodrigues' rotation formula 计算旋转矩阵。例如,对于绕向量 axis = [x, y, z] 旋转 angle 度的情况,旋转矩阵可以用下式给出: ``` cos_angle = cosd(angle); sin_angle = sind(angle); rotation_matrix = [cos_angle + axis(1)^2 * (1 - cos_angle), axis(1) * axis(2) * (1 - cos_angle) - axis(3) * sin_angle, axis(1) * axis(3) * (1 - cos_angle) + axis(2) * sin_angle; axis(2) * axis(1) * (1 - cos_angle) + axis(3) * sin_angle, cos_angle + axis(2)^2 * (1 - cos_angle), axis(2) * axis(3) * (1 - cos_angle) - axis(1) * sin_angle; axis(3) * axis(1) * (1 - cos_angle) - axis(2) * sin_angle, axis(3) * axis(2) * (1 - cos_angle) + axis(1) * sin_angle, cos_angle + axis(3)^2 * (1 - cos_angle)]; ``` 3. 对三维坐标进行旋转利用计算得到的旋转矩阵,可以将每个三维坐标通过矩阵乘法进行旋转。假设三维坐标为 point = [x, y, z],则旋转后的坐标可以通过下式给出: ``` new_point = rotation_matrix * transpose(point); ``` 其中,transpose(point) 将三维坐标 point 转置为列向量。 使用以上步骤,就可以在MATLAB中实现对三维坐标任意旋转了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值