从原始帖子Three.JS Object following a spline path - rotation / tangent issues & constant speed issue开始跟进,我仍然遇到问题,即对象在路径上的某些点翻转。
在这个小提琴上查看此事:http://jsfiddle.net/jayfield1979/T2t59/7/
function moveBox() {
if (counter <= 1) {
box.position.x = spline.getPointAt(counter).x;
box.position.y = spline.getPointAt(counter).y;
tangent = spline.getTangentAt(counter).normalize();
axis.cross(up, tangent).normalize();
var radians = Math.acos(up.dot(tangent));
box.quaternion.setFromAxisAngle(axis, radians);
counter += 0.005
} else {
counter = 0;
}
}
上面的代码是沿着定义的样条曲线路径移动我的对象(在这个例子中是一个椭圆)。 @WestLangley提到:“警告:如果两个向量是平行的,则交叉产品没有明确定义。”。
如您所见,从路径的形状来看,我将遇到许多平行向量。我能做些什么来阻止这种翻转吗?
答案 0 :(得分:3)
回答标题中的原因问题。它发生的原因是在曲线的某些点上,矢量up
(1,0,0)和切线是平行的。这意味着它们的叉积为零,四元数的构造失败。
你可以遵循WestLangley的建议。你真的希望向上方向是轨道所在平面的法线。
四元数旋转很难理解setFromAxisAngle
函数绕轴旋转给定角度。
如果轨道位于X-Y平面,那么我们将要绕Z轴旋转。要查找角度,请使用Math.atan2
查找切线的角度
var angle = Math.atan2(tangent.y,tangent.x);
把这个放在一起
var ZZ = new THREE.Vector3( 0, 0, 1 );
和
tangent = spline.getTangentAt(counter).normalize();
var angle = Math.atan2(tangent.y,tangent.x);
box.quaternion.setFromAxisAngle(ZZ, angle);
如果轨道离开X-Y平面,事情就会变得棘手。