繁体   English   中英

如何围绕特定轴旋转矢量

[英]How to rotate a vector around a particular axis

.X3D格式有一个有趣的旋转系统。 与包含围绕XYZ轴旋转值的大多数格式不同, .X3D给出了一个归一化的方向向量,然后给出了一个以弧度为单位的值,以围绕该轴旋转。

例子:

The axis to rotate around: 0.000000 0.465391 0.885105 
Rotation around that axis (in radians): 3.141593

我有从弧度到度的转换,但我需要从这些值中获得围绕XYZ的旋转值。

我们可以为基本矩阵变换构建一个序列以绕角度轴旋转。 设轴单位向量为w ,角度Theta 辅助值:

V = Sqrt(wx*wx + wz*wz)
W = Sqrt(wx*wx + wy*wy + wz*wz)  //1 for unit dir vector
Cos(Alpha) = wz/V
Sin(Alpha) = wx/V
Cos(Beta) = V/W
Sin(Beta) = wy/W

Transformation sequence:
Ry(-Alpha)   //rotation matrix about Y-axis by angle -Alpha
Rx(Beta)
Rz(Theta)
Rx(-Beta)
Ry(Alpha) 

请注意,因为 is 轴与 Y 平行,所以应该使用通常关于 Y 的旋转矩阵(考虑方向符号),因为 V 值为零。


有相当复杂的Rodrigues 旋转公式,用于计算对应于围绕单位向量 w 指定的固定轴旋转角度 Theta 的旋转矩阵。

这里的显式矩阵(奇怪的格式图片): 在此处输入图片说明

下面的 C++ 函数围绕提供的中心旋转一个点,并使用另一个向量(单位)作为轴来旋转。 下面的代码感谢Glenn Murray ,他提供了链接中提供的公式。 这是经过测试的,并且按预期完美运行。 注意:当角度为正且单位向量为{0,0,1}时,它向右旋转,基本上旋转在右侧,轴为{x-forward,y-right,z-up}

void RotateVectorAroundPointAndAxis(Vector3D YourPoint, Vector3D PreferedCenter, Vector3D UnitDirection, float Angle, Vector3D& ReturnVector)
{
    float SinVal = sin(Angle * 0.01745329251);
    float CosVal = cos(Angle * 0.01745329251);
    float OneMinSin = 1.0f - SinVal;
    float OneMinCos = 1.0f - CosVal;   

    UnitDirection = GetUnitVector(UnitDirection, { 0,0,0 });// This Function Gets unit Vector From InputVector - DesiredCenter

    float Temp = (UnitDirection.x * YourPoint.x) + (UnitDirection.y * YourPoint.y) + (UnitDirection.z * YourPoint.z);
    ReturnVector.x = (PreferedCenter.x * (UnitDirection.y * UnitDirection.y)) - (UnitDirection.x * (((-PreferedCenter.y * UnitDirection.y) + (-PreferedCenter.z * UnitDirection.z)) - Temp));
    ReturnVector.y = (PreferedCenter.y * (UnitDirection.x * UnitDirection.x)) - (UnitDirection.y * (((-PreferedCenter.x * UnitDirection.x) + (-PreferedCenter.z * UnitDirection.z)) - Temp));
    ReturnVector.z = (PreferedCenter.z * (UnitDirection.x * UnitDirection.x)) - (UnitDirection.z * (((-PreferedCenter.x * UnitDirection.x) + (-PreferedCenter.y * UnitDirection.y)) - Temp));

    ReturnVector.x = (ReturnVector.x * OneMinCos) + (YourPoint.x * CosVal);
    ReturnVector.y = (ReturnVector.y * OneMinCos) + (YourPoint.y * CosVal);
    ReturnVector.z = (ReturnVector.z * OneMinCos) + (YourPoint.z * CosVal);

    ReturnVector.x += (-(PreferedCenter.z * UnitDirection.y) + (PreferedCenter.y * UnitDirection.z) - (UnitDirection.z * YourPoint.y) + (UnitDirection.y * YourPoint.z)) * SinVal;    
    ReturnVector.y += ( (PreferedCenter.z * UnitDirection.x) - (PreferedCenter.x * UnitDirection.z) + (UnitDirection.z * YourPoint.x) - (UnitDirection.x * YourPoint.z)) * SinVal;
    ReturnVector.z += (-(PreferedCenter.y * UnitDirection.x) + (PreferedCenter.x * UnitDirection.y) - (UnitDirection.y * YourPoint.x) + (UnitDirection.x * YourPoint.y)) * SinVal;    
}

暂无
暂无

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

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