简体   繁体   中英

How to rotate a vector around a particular axis

The .X3D format has an interesting rotation system. Unlike most formats containing rotation values around the X , Y and Z axis, .X3D gives a normalized direction vector and then gives a value in radians for rotation around that axis.

Example:

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

I have the conversion from radians to degrees, but I need the rotation values around XYZ from these values.

We can build a sequence for elementary matrix transformations to rotate about angle-axis. Let axis unit vector is w , angle Theta . Auxiliary values:

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) 

Note that for is axis is parallel to Y , one should use usual just rotation matrix about Y (accounting for direction sign), because V value is zero.


There is rather complex Rodrigues' rotation formula for computing the rotation matrix corresponding to a rotation by an angle Theta about a fixed axis specified by the unit vector w.

Explicit matrix here (weird formatted picture): 在此处输入图片说明

This Below C++ Function Rotates a Point Around A Provided Center and Uses Another Vector(Unit) as Axis to rotate Around. This Code Below Was Made Thanks to Glenn Murray who provided the Formula Provided in Link . This is Tested and is Working Perfectly As intended. Note: When Angle Is Positive And Unit Vector is {0,0,1} It Rotates To the Right Side, Basically Rotation Is On the Right Side, Axes are {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;    
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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