我一直在开发一个基本的游戏引擎,只是为了学习这个过程而且我的旋转功能遇到了问题。
除了物体收缩并且看起来反转之外,它工作正常。
这是jsfiddle,说明了我的观点。
我认为问题在于旋转代码本身,但我并不积极。
function Rotation(vec, rot){
if(Math.acos((vec.x + vec.y + vec.z -1)/2) === 0) { return vec; }
var qVec = new Quaternion(vec.x, vec.y, vec.z, 0);
qVec = Quaternions.multiply(qVec, rot);
qVec = Quaternions.multiply(qVec, rot.conjugate());
return new Vector3(qVec.x, qVec.y, qVec.z);
}
答案 0 :(得分:1)
夫妻俩:
首先,旋转四元数未标准化,因此它的反转与其共轭不相同。四元数的旋转定义为:
q
是您要旋转的矢量,p
是您正在旋转的矢量,而p'
是最终旋转的矢量。
所以这是使用q的逆来定义的,其定义为conjugate(q) / magnitude(q)^2
。在q被归一化的情况下,magnitude(q)^2 == 1
,所以它只是乘以共轭。
另请注意此处的操作顺序。 Quat乘法是非交换,因此它们的顺序很重要。
您可以通过规范旋转四元数并修复操作顺序来解决此问题:
var qVec = new Quaternion(vec.x, vec.y, vec.z, 0);
qVec = Quaternions.multiply(rot.normalize(), qVec);
qVec = Quaternions.multiply(qVec, rot.conjugate());
return new Vector3(qVec.x, qVec.y, qVec.z);
其次,您希望将旋转四元组定义为要旋转的平面的法线。在这种情况下,您希望围绕x-y平面旋转。 z轴垂直于该平面,因此我们希望沿z轴定义旋转矢量:
function update(){
for(var i = 0; i < gameObjects.length; i++){
gameObjects[i].rotation = euler(new Vector3(0, 0, frames/100));
}
}
通过这些更改,我能够正确地旋转盒子。
(就扩大/缩小的原因而言,我并非100%肯定。仍然试图解决这个问题。)