假设您有描述3D模型旋转的四元数。
我想做的是,给定一个对象(使用rotationQuaternion,侧向量...),我希望将其与目标点对齐。
对于宇宙飞船,我希望驾驶舱指向一个目标。
下面是我的一些代码。它不是我想要的,我不知道为什么.
if (_target._ray.Position != _obj._ray.Position)
{
Vector3 vec = Vector3.Normalize(_target._ray.Position - _obj._ray.Position);
float angle = (float)Math.Acos(Vector3.Dot(vec, _obj._ray.Direction));
Vector3 cross = Vector3.Cross(vec, _obj._ray.Direction);
if (cross == Vector3.Zero)
cross = _obj._side;
_obj._rotationQuaternion *= Quaternion.CreateFromAxisAngle(cross,angle);
}
// Updates direction, up, side vectors and model Matrix
_obj.UpdateMatrix();一段时间后,rotationQuaternion在X、Y、Z和W处几乎为零
有什么帮助吗?谢谢;-)
发布于 2012-11-08 00:36:55
你的代码有点时髦。
if (_target._ray.Position != _obj._ray.Position)
{这可能是正确的,也可能是错误的。显然,您已经覆盖了equals比较器。正确的做法是确保两条(单位长度)光线之间的点积接近于1。如果这两条光线具有相同的原点,则可能具有相同的“位置”,这意味着它们是相同的。
Vector3 vec = Vector3.Normalize(_target._ray.Position - _obj._ray.Position);这似乎是特别错误的。除非减号运算符以一种奇怪的方式被覆盖,否则这种减法没有意义。
下面是我推荐的伪代码:
normalize3(targetRay);
normalize3(objectRay);
angleDif = acos(dotProduct(targetRay,objectRay));
if (angleDif!=0) {
orthoRay = crossProduct(objectRay,targetRay);
normalize3(orthoRay);
deltaQ = quaternionFromAxisAngle(orthoRay,angleDif);
rotationQuaternion = deltaQ*rotationQuaternion;
normalize4(rotationQuaternion);
}这里有两件事需要注意:
发布于 2012-11-07 19:55:04
这是我用来获取锁定目标旋转的四元数的快捷方式:
Matrix rot = Matrix.CreateLookAt(_arrow.Position, _cube.Position, Vector3.Down);
_arrow.Rotation = Quaternion.CreateFromRotationMatrix(rot);在这个例子中,我渲染了一个箭头和一个立方体,其中立方体在圆圈中移动,并且在上面的代码中,箭头始终指向立方体。(虽然我想象有一些边缘情况,当立方体恰好高于或低于立方体时)。

一旦获得这个四元数(从宇宙飞船到目标),就可以使用Quaternion.Lerp()在当前船舶旋转和对齐的船舶旋转之间进行插值。这将给你的旋转一个平滑的过渡(不仅仅是捕捉到目标)。
顺便说一句,你的旋转可能会减少到零,因为你在赋值的时候使用了*=。
发布于 2012-11-08 04:36:50
天哪!成功了!
Vector3 targetRay = Vector3.Normalize(_target._ray.Position - _obj._ray.Position);
Vector3 objectRay = Vector3.Normalize(_obj._ray.Direction);
float angle = (float)Math.Acos(Vector3.Dot(targetRay, objectRay));
if (angle!=0)
{
Vector3 ortho = Vector3.Normalize(Vector3.Cross(objectRay, targetRay));
_obj._rotationQuaternion = Quaternion.CreateFromAxisAngle(ortho, angle) * _obj._rotationQuaternion;
_obj._rotationQuaternion.Normalize();
}
_obj.UpdateMatrix();非常感谢JCooper!
niko我喜欢Lerp的想法;-)
https://stackoverflow.com/questions/13258413
复制相似问题