gpt4 book ai didi

javascript - Three.js 四元数 slerp 在极点附近给出了糟糕的结果

转载 作者:行者123 更新时间:2023-12-02 23:38:56 27 4
gpt4 key购买 nike

视频示例:https://drive.google.com/file/d/18Ep4i1JMs7QvW9m-3U4oyQ4sM0CfIFzP/view

您在这里可以看到的是,我有一条光线击中鼠标下方的地球的世界位置。然后我使用 THREE.Group 到该位置进行 lookAt() 以获得具有正确旋转的四元数。鼠标下方始终出现的红点证明这个四元数没问题。接下来,从代表黄色大圆顶中心的四元数开始,我使用 rotateTowards (它在内部使用 slerp,我尝试直接使用 slerp 方法,但这给了我相同的结果)朝向鼠标位置的四元数(红点)并将该四元数设置为跟随鼠标的蓝点的旋转。理论上,当我的鼠标距离较远时,它应该始终“粘在”那个圆顶上。当我在靠近南半球的地方进行这些操作时,您可以看到它确实“粘住”了它。但在北极附近,情况就变得困惑了。它按照应有的方式计算较短的距离,甚至不在正确的大圆上。

相关代码:

// using hammerjs pan events I send an event to the blue sphere with the position on the sphere whats under the mouse, event.point is correct, the red sphere always under the mouse proves this.

this.helperGroup.lookAt(event.point); // To get the requested rotation
const p = this.helperGroup.quaternion.clone(); // helpergroup is just an empty group in (0, 0, 0) to get quaternions with lookAt more easily
// p is now a rotation towards the point under the mouse

const requestedDistance = dome.quaternion.angleTo(p); // dome is the center of the yellow dome in the video, allowedDistance is the arc-length of said dome in radians.
// The reason I rotate the parent of blueSphere because its parent is another group in (0, 0, 0) and the (relative) position of the blue sphere is (0, 0, 1), the planets radius is 1 too.
if (allowedDistance >= requestedDistance) {
blueSphere.parent.lookAt(event.point);
} else {
blueSphere.parent.quaternion.copy(
dome.quaternion.clone().rotateTowards(p, allowedAngle)
);
}

// this snippet is heavily modified for the sake of an example.

更新和不同的方法:

我最初使用这个 lookAt() 和基于旋转的布局来尽可能避免数学计算。但它却遭到了反击。所以现在我只需使用笛卡尔坐标、法向量和简单的基于轴的旋转就可以正确地完成它。 (事实证明,使用数学实际上比避免使用数学更简单)

const requestedDistance = blueSphere.angleTo(event.point);
let norm = dome.position.clone().cross(event.point).normalize();
if (allowedDistance >= requestedDistance) {
blueSphere.position.set(event.point); // Not using a group as parent anymore
} else {
blueSphere.position.set(dome.position.clone()
.applyAxisAngle(norm, allowedAngle);
}

最佳答案

极点附近的奇点是四元数 slerp 函数性质的一部分;除非使用不同的方法,否则这是无法避免的。 Jonathan Blow 的文章“Understanding Slerp, Then Not Using It”讨论了 slerp 函数及其问题,并建议 slerp 的替代方案(归一化 lerp 或 nlerp)是大多数时候首选的四元数插值器。

请注意,即使该文章中的 slerp C++ 代码也承认 slerp 函数中存在奇点。

关于javascript - Three.js 四元数 slerp 在极点附近给出了糟糕的结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56162239/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com