旋转大理石有些问题
我已尝试使用Matrix.CreateFromYawPitchRoll
和Matrix.CreateRotation
,但有一些问题,我认为这是由于 Gimbal lock 效果。
所以,我尝试使用四元数,但没有改变 当仅在轴上移动时它可以正常工作,但是当在两个不同的轴上发生旋转时,大理石仍然在错误的轴上旋转。
这是我的代码:
// declarations
Vector3 Position = Vector3.Zero;
Vector3 Rotation = Vector3.Zero;
Quaternion qRotation = Quaternion.Identity;
AbsoluteBoneTransforms = new Matrix[Model.Bones.Count];
Model.CopyAbsoluteBoneTransformsTo(AbsoluteBoneTransforms);
在Update
方法中:
Position += speed;
Rotation = speed * MathHelper.ToRadians(-1.5f);
Quaternion rot = Quaternion.CreateFromAxisAngle(Vector3.Right, Rotation.Z) *
Quaternion.CreateFromAxisAngle(Vector3.Backward, Rotation.X);
qRotation *= rot;
在Draw
方法中:
effect.World = AbsoluteBoneTransforms[mesh.ParentBone.Index] *
Matrix.CreateFromQuaternion(qRotation) * Matrix.CreateTranslation(Position);
怎么了?在多个轴上使用Quaternion.CreateFromAxisAngle
是不对的?
修改
我尝试直接计算大理石的旋转轴,而不是使用多个轴的组合:
angle += speed.Length() * angularVelocity;
qRotation = Quaternion.CreateFromAxisAngle(Vector3.Cross(speed, Vector3.Up), angle);
qRotation.Normalize();
angle
是一个跟踪当前运动的浮动
这个解决方案似乎没有创建万向节锁,但大理石旋转不正确,似乎旋转速度不恒定,但随着时间的推移变得越来越慢,我无法理解为什么
如果我“连接”四元数,我会使用
获得每一帧qRotation *= Quaternion.CreateFromAxisAngle(Vector3.Cross(speed, Vector3.Up), angle)
Gimbal lock 效果仍然可见。
答案 0 :(得分:2)
以下是我解决这个问题的方法:
我假设speed
是一个表示球滚动方向的矢量,其大小代表它在该方向上行进的速度。
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));
然后你可以将它连接到你的qRotation。此外,您可能需要在连接后规范化四元数。
更新:这个问题/线程的正确答案是颠倒了四元数连接的顺序。对于XNA,矩阵从左到右组合,四元数从右到左组合。