一位朋友給了我一些代碼,它創建了一個從一個向量旋轉到另一個向量的矩陣。對于將事物相互指向非常有用。
出現的一個問題是,矩陣通常會在其旋轉中進行奇怪的翻轉。IE 我最終會得到一個正確旋轉的結果——但在 Z 方向上是顛倒的,或者類似的東西。
有沒有辦法在此代碼中添加一個向上向量,以強制矩陣盡可能避免圍繞向上方向的軸旋轉?
這是代碼:
Matrix& Matrix::VectorToVector(Vector theV1, Vector theV2)
{
theV1.Normalize();
theV2.Normalize();
float aDot=theV1.Dot(theV2);
if (gMath.Abs(aDot)>=1.0f-gMath.mMachineEpsilon)
{
if (aDot<0)
{
Vector aPerp=theV1.Perp(); // We don't care which perp, we just need a perp
RotateAroundAxis3D(aPerp,180);
}
}
else
{
Vector aAxis;
float aAngle=0;
aAxis=gMath.Cross(theV1,theV2);
aAngle=gMath.Deg((float)acos(gMath.Dot(theV1,theV2)));
RotateAroundAxis3D(aAxis,aAngle);
}
return *this;
}
編輯:添加了 RotateAroundAxis3D 函式的代碼...
Matrix& Matrix::RotateAroundAxis3D(Vector theVector, float theAngle)
{
//
// Multiply the angle by -1 to put it into Raptis Space.
//
theAngle=180-theAngle;
theVector.Normalize();
Matrix aMat;
float aSin=gMath.Sin(theAngle);
float aCos=gMath.Cos(theAngle);
aMat.m00=(1.0f - aCos) * theVector.mX * theVector.mX aCos;
aMat.m10=(1.0f - aCos) * theVector.mX * theVector.mY - aSin * theVector.mZ;
aMat.m20=(1.0f - aCos) * theVector.mX * theVector.mZ aSin * theVector.mY;
aMat.m01=(1.0f - aCos) * theVector.mY * theVector.mX aSin * theVector.mZ;
aMat.m11=(1.0f - aCos) * theVector.mY * theVector.mY aCos;
aMat.m21=(1.0f - aCos) * theVector.mY * theVector.mZ - aSin * theVector.mX;
aMat.m02=(1.0f - aCos) * theVector.mZ * theVector.mX - aSin * theVector.mY;
aMat.m12=(1.0f - aCos) * theVector.mZ * theVector.mY aSin * theVector.mX;
aMat.m22=(1.0f - aCos) * theVector.mZ * theVector.mZ aCos;
return Multiply(&aMat);
}
uj5u.com熱心網友回復:
我假設功能:
Matrix& Matrix::VectorToVector(Vector theV1, Vector theV2)
應該旋轉成this這樣。如果是這種情況,那么在我看來,這種情況 不應該做任何事情,但是您將圍繞未對齊的垂直向量旋轉 180 度。這是完全錯誤的,我會在這種情況下保留矩陣,而不做任何更改,所以:theV1theV2if (gMath.Abs(aDot)>=1.0f-gMath.mMachineEpsilon)theV1
Matrix& Matrix::VectorToVector(Vector theV1, Vector theV2)
{
theV1.Normalize();
theV2.Normalize();
float aDot=theV1.Dot(theV2);
if (gMath.Abs(aDot)<1.0f-gMath.mMachineEpsilon)
{
Vector aAxis;
float aAngle=0;
aAxis=gMath.Cross(theV1,theV2);
aAngle=gMath.Deg((float)acos(gMath.Dot(theV1,theV2)));
RotateAroundAxis3D(aAxis,aAngle);
}
return *this;
}
如果問題仍然存在,那么原因可能就在RotateAroundAxis3D(aAxis,aAngle);但沒有看到它的實施很難說。如果它使用四元數或歐拉角,這可能是原因。如果是這種情況,看看這個:
- 創建一個只有 2 個已知點的立方體
該函式vec3 rotate(float ang,vec3 axis,vec3 p)旋轉向量,您可以通過旋轉其 3 個基向量和原點將其更改為旋轉矩陣。
順便說一句,還有另一種選擇可以進行這種對齊,請參閱:
- 疊加和對齊 3D 三角形的問題
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/431631.html
下一篇:如何讓程式理解輸入
