假设您有四元数描述3D模型的旋转。
我想要做的是,给定一个Object(使用rotationQuaternion,side vector ...),我想将它与目标点对齐。
对于宇宙飞船,我希望驾驶舱指向目标。
这是我的一些代码......它不是我想要的,我不知道为什么......
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
处几乎为零有任何帮助吗? 谢谢; - )
答案 0 :(得分:2)
这是我用来获取锁定目标旋转的四元数的快捷方式:
Matrix rot = Matrix.CreateLookAt(_arrow.Position, _cube.Position, Vector3.Down);
_arrow.Rotation = Quaternion.CreateFromRotationMatrix(rot);
对于这个例子,我正在渲染一个箭头和一个立方体,其中立方体在一个圆圈中移动,并且使用上面的代码,箭头总是指向立方体。 (虽然我认为当立方体恰好在上方或下方时有一些边缘情况)。
一旦获得此四元数(从太空飞船到目标),您可以使用Quaternion.Lerp()
在当前船舶旋转和对齐的轮船之间进行插值。这将使您的旋转平滑过渡(而不仅仅是对齐目标)。
顺便说一句,可能是因为你在分配时使用*=
,你的轮换会减少到零。
答案 1 :(得分:2)
你的代码有点时髦。
if (_target._ray.Position != _obj._ray.Position)
{
这可能是也可能不正确。显然,你已经覆盖了等于比较器。在这里做的正确的事情是确保两条(单位长度)光线之间的点积接近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);
}
这里有两点需要注意:
答案 2 :(得分:0)
OMG!有效!!!
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的想法; - )