如何围绕特定轴旋转矢量

时间:2017-04-26 01:33:15

标签: c# math rotation

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

示例:

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

我有从弧度到度数的转换,但我需要这些值的XYZ周围的旋转值。

2 个答案:

答案 0 :(得分:0)

我们可以构建基本矩阵变换的序列,以围绕角度轴旋转。设轴单位向量为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' rotation formula用于计算旋转矩阵,该旋转矩阵对应于围绕由单位矢量w指定的固定轴的角度θ的旋转。

显式矩阵here(奇怪的格式化图片): enter image description here

答案 1 :(得分:0)

下面的 C++ 函数围绕提供的中心旋转一个点,并使用另一个向量(单位)作为轴来旋转。 下面的代码感谢 Glenn Murray 提供了 Link 中提供的公式。这是经过测试的,并且按预期完美运行。 注意:当角度为正且单位向量为{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;    
}
相关问题