首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ThreeJS原位相机短旋转

ThreeJS原位相机短旋转
EN

Stack Overflow用户
提问于 2016-09-30 07:57:55
回答 1查看 521关注 0票数 2

我有一个轨道照相机轨道是一个地球仪。有几个标志在地球上,用户可以点击,相机将移动到这一点。

用TweenMax来制作这样的动画-

代码语言:javascript
复制
 TweenMax.to(currentPos, 3, {
     theta:targetPos.theta, 
     phi:targetPos.phi, 
     radius:targetPos.radius, 
     ease:Circ.easeIn, 
     onComplete:btnZoomComplete,
     onUpdateParams:["{self}"], 
     onComplete:SataliteTweenComplete, 
     onUpdate: function(tween) {
       controls.setThetaPhi(tween.target.theta, tween.target.phi, tween.target.radius);
     }
});

这是伟大的工作,但没有考虑到最短的路线到那里。因此,它经常会“绕着地球”转。

ThreeJS似乎测量了一个非常奇怪的单位系统的角度: 0,1.57 (相当于90度),3.14 (eq 180 is ),然后3.14之后是跳到-3.14,-1.57 (eq到270 is),然后回到0.所以这让我开始思考如何解决这个问题。

例如,假设摄像机是2.6,它需要超过-2.61,此时相机将动画化CCW (2.6到-2.16),在那里,它需要动画CW,它将从2.6移动到3.14,然后从-2.61。

如果能在这方面提供任何帮助,我们将不胜感激。

我想有两个问题,如何确定该走哪条路,但是如何真正地从2.6 -> 3.14中进行动画化,跳到-3.14无缝地-> -2.61

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-10-01 11:13:36

所以“奇怪的单位-系统”就是弧度,在-180°到180°和-90°到90°范围内测量θ/phi值是很常见的(比如纬度/经度,同样的事情)。转换很简单:

代码语言:javascript
复制
angleDegrees = radians / Math.PI * 180;
radians = angleDegrees / 180 * Math.PI;

现在,tweening将只是从一个值插入到另一个值,而不知道这些值代表什么。因此,当涉及到旋转时,它根本不知道如何处理最短路径。然而,您可以这样做,然后开始吐温。

假设我们从2.6-2.6动画(或149°到-149°)。

代码语言:javascript
复制
var from = 2.6, to = -2.6;

动画的方向和角距离可以计算为

代码语言:javascript
复制
var distance = to - from; 
// === -5.2

这里的负值意味着逆时针方向,而5.2 (~298°)是相机运行的“距离”。现在请记住,任何角度正负360°(2 * Math.PI)基本上都会使你在同一位置着陆。因此,让我们尝试:

代码语言:javascript
复制
var distance = (to + 2 * Math.PI) - from; 
// === 1.083185307179586 (~62°)

所以,如果你从你在2.6的位置旋转到-2.6 + 2 * Math.PI (或者,从149°到-149°+ 360°= 211°),你会得到一个顺时针方向的动画,路径更短。

为了确保所有值都保持在允许的范围内,我们稍微修改onUpdate-函数,以正确地包装:

代码语言:javascript
复制
controls.setThetaPhi(
    tween.target.theta % Math.PI, 
    tween.target.phi % Math.PI, 
    tween.target.radius);

您可能还希望在动画开始之前使用实际值更新currentPos值,然后再进行以下计算。

剩下要做的就是在一般情况下解决这个问题,所以找出什么时候做顺时针旋转和逆时针旋转。为了看另一条路是否更短,我们只需要看看距离是否大于180°:

代码语言:javascript
复制
if (Math.abs(to - from) > Math.PI) {
  if (to > 0) { // if to is positive we remove a full-circle, add it otherwise
    to = to - 2 * Math.PI;
  } else {
    to = to + 2 * Math.PI;
  }
}
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39786475

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档