C# 用四元数校正旋转
我对旋转大理石有一些问题。C# 用四元数校正旋转,c#,3d,xna,rotation,quaternions,C#,3d,Xna,Rotation,Quaternions,我对旋转大理石有一些问题。 我已经用Matrix.CreateFromYawPitchRoll和Matrix.CreateRotation尝试过了,但是出现了一些问题,我认为这是由于万向节锁效应造成的 因此,我尝试使用四元数,但没有任何改变。 当只在一个轴上移动时,效果很好,但当旋转发生在两个不同的轴上时,大理石仍然在错误的轴上旋转 这是我的密码: //声明 Vector3位置=Vector3.0; 矢量3旋转=矢量3.0; 四元数Q旋转=四元数标识; AbsoluteBonetTransfor
我已经用
Matrix.CreateFromYawPitchRoll
和Matrix.CreateRotation
尝试过了,但是出现了一些问题,我认为这是由于万向节锁效应造成的
因此,我尝试使用四元数,但没有任何改变。当只在一个轴上移动时,效果很好,但当旋转发生在两个不同的轴上时,大理石仍然在错误的轴上旋转 这是我的密码:
//声明
Vector3位置=Vector3.0;
矢量3旋转=矢量3.0;
四元数Q旋转=四元数标识;
AbsoluteBonetTransforms=新矩阵[Model.Bones.Count];
Model.copyAbsoluteBonetTransformsTo(AbsoluteBonetTransforms);
在更新方法中:
位置+=速度;
旋转=速度*旋转半径(-1.5f);
四元数旋转=四元数.CreateFromAxisAngle(Vector3.Right,Rotation.Z)*
四元数.CreateFromAxisAngle(Vector3.Backward,Rotation.X);
旋转*=旋转;
在绘制方法中:
effect.World=AbsoluteBonetTransforms[mesh.ParentBone.Index]*
矩阵.CreateFromQuaternion(Q旋转)*矩阵.CreateTranslation(位置);
怎么了?在多个轴上使用四元数.CreateFromAxisAngle
是否错误
编辑
我尝试直接计算大理石的旋转轴,而不是使用多个轴的组合:
angle += speed.Length() * angularVelocity;
qRotation = Quaternion.CreateFromAxisAngle(Vector3.Cross(speed, Vector3.Up), angle);
qRotation.Normalize();
角度
是跟踪当前运动的浮动。
这个解决方案似乎没有创建万向节锁,但大理石旋转是不正确的,似乎旋转速度不是恒定的,但随着时间的推移变得越来越快,越来越慢,我不明白为什么
如果我“连接”四元数,我会使用
qRotation *= Quaternion.CreateFromAxisAngle(Vector3.Cross(speed, Vector3.Up), angle)
万向节锁效果仍然可见。以下是我如何解决的:
我假设速度
是一个向量,表示球滚动的方向,其大小表示球在该方向的移动速率
Vector3 axis = Vector3.Cross(speed, Vector3.Up);
float angle = speed.Length();//factor by delta time if neccesary
Quaternion rotationThisFrame = Quaternion.CreateFromAxisAngle(axis, angle * (1/radiusOfBall));
然后您可以将其连接到您的旋转。此外,您可能需要在连接后规范化四元数
更新:此问题/线程的正确答案是颠倒四元数串联的顺序。对于XNA,矩阵从左到右组合,四元数从右到左组合。似乎没有什么真正的变化,如果旋转只发生在一个轴上,它的工作原理与以前一样,但是当涉及两个轴时,出现了一些错误。qRotation
似乎代表大理石的当前方向。对于该方向,您只需将自上一帧以来发生的旋转与四元数.CreateFrom…()
组合。因此,CreateFrom…
中使用的角度应该只表示自上一帧以来的角度运动。但是看起来你的角度(带+=)试图表示整体角度,这看起来不对angle
应该是自上一帧以来的旋转量。就像在我的示例中,对于angle
,我的意思是AngleChangesincellastFrame
。是的,但是如果我将qRotation
与上一帧相乘,并且我使用angle
自上一帧以来,没有任何变化,正如我在第一条评论中所写,万向节锁的效果仍然可见。我在我的问题中添加的解决方案是我发现的唯一一个可以避免它的方法,但它会导致旋转出现问题。我想我做不出来。对不起,如果我有点偏离正轨。我在玩它的时候才意识到/记住,四元数的连接顺序与矩阵在Xna中的顺序相反。因此,如果你要做一个矩阵,比如orientation=orientation*rotationToAdd
(或*=),你要做一个四元数,比如:orientation=rotationToAdd*orientation