three.js getWorldPosition没有返回预期结果

时间:2015-07-03 09:40:41

标签: javascript 3d three.js typescript

请参阅我在

创建的要点

https://gist.github.com/sparkbuzz/f1f8d0d8bbc7757b679f

它包含一个名为OrbitControls的TypeScript类。作为了解3D和three.js的尝试,到目前为止,我在创建轨道样式控件方面取得了成功,并且从MrDoob's JS OrbitControls.

获取了指导和解释

我的实现略有不同,但简而言之,我正在使用 mousedown mousemove mouseup 事件来导航相机世界起源。当 mousedown 被触发时,我使用以下代码抓住相机的初始位置:

this.subjectPositionStart = this.subject.getWorldPosition();
mousemove 期间使用

来计算需要添加到相机初始位置的角度,就像 mousedown 被触发时一样。

mousemove 期间, theta phi 角度是根据鼠标在HTML画布上移动并用于重新定位的距离来计算的。相机:

this.subject.position.x = rho * Math.cos(theta) * Math.sin(phi);
this.subject.position.y = rho * Math.sin(theta) * Math.sin(phi);
this.subject.position.z = rho * Math.cos(phi);

然而,在下一个 mousedown 上一切正常,有时,当相机绕z轴的位置旋转角度超过90°或低于-90°时,相机位置捕捉到一个与预期相反的位置。

所以我看到的是相机翻转,镜像它的位置,度数是正确的,但只是镜像。

当我没有超过90°时,下一个 mousedown 工作正常并且导航按预期运行,并且从 getWorldPosition()正确检索相机位置,但是我怀疑我正在错误地使用此功能,或者可能完全使用错误的技术来确定相机相对于原点的位置角度。

问题肯定与 mousedown 处理程序有关,因为只有 mousemove 触发,超过90°角度没有问题,导航工作正常。 / p>

关于什么可能出错的任何想法?

编辑:

我认为我calculating baseTheta的方式不正确:

var baseTheta:number = Math.asin(this.subjectPositionStart.y / rho / Math.sin(basePhi));

如果我使用:

var baseTheta:number = Math.acos(this.subjectPositionStart.x / rho / Math.sin(basePhi));

我遇到了同样的问题,但它在180°和360°之间翻转,我认为这是一个线索......

2 个答案:

答案 0 :(得分:1)

事实证明 baseTheta basePhi 没有被正确计算,而问题实际上出现在我问的另一个问题中。

Calculate θ and ø angles between origin and x,y,z coordinate

我在Paul.S的回答中更改了以下代码:

var basePhi:number = Math.acos(this.subjectPositionStart.z / rho);
var baseTheta:number = Math.asin(this.subjectPositionStart.y / rho / Math.sin(basePhi));

var basePhi:number = Math.acos(this.subjectPositionStart.z / rho);
var baseTheta:number = Math.atan2(this.subjectPositionStart.y, this.subjectPositionStart.x);

问题解决了。没有更多的翻转。

答案 1 :(得分:0)

你的问题可能与Three.js试图让相机朝上的方式有关

检查出来:rotating-camera-around-the-x-axis-three-js

Orbit controls source中,对于一个人如何旋转有一些限制。将这些添加到您的代码可能会解决您的问题。

        // restrict theta to be between desired limits
        theta = Math.max( this.minAzimuthAngle, Math.min( this.maxAzimuthAngle, theta ) );

        // restrict phi to be between desired limits
        phi = Math.max( this.minPolarAngle, Math.min( this.maxPolarAngle, phi ) );

        // restrict phi to be betwee EPS and PI-EPS
        phi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );