2016-09-30 54 views
2

我有一個軌道相機,軌道是地球儀。用戶可以點擊地球上的幾個標記,相機將移動到該點。ThreeJS oribital camera short rotation

使用TweenMax像這樣的動畫 -

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); 
    } 
}); 

這個偉大的工程,然而這並沒有考慮到的最短路線到達那裏。所以它可以經常在全球範圍內「背靠背」。 3JS似乎在一個非常奇怪的單位系統中測量角度: 0,1.57(相當於90度),3.14(方程180dg),然後在3.14跳到-3.14,-1.57(方程270天)之後, ,然後回到0 ...所以這讓我想起如何解決它。

例如,假設攝像機處於2.6並且需要回到-2.61,此時攝像機會動畫CCW(2.6至-2.16),在視覺上需要動畫化CW,這會移動從2.6到3.14,-3.14然後到-2.61。

對此的任何幫助將非常感激。

我想有兩個問題,如何找出哪個方向走輪,但隨後如何真正從2.6跨越動畫 - > 3.14,跳轉到-3.14無縫 - > -2.61

回答

4

使「奇怪的單位系統「只是radians,在-180°到180°和-90°到90°的範圍內測量θ/ phi值是相當常見的(考慮緯度/經度,同樣的事情)。轉換很簡單:

angleDegrees = radians/Math.PI * 180; 
radians = angleDegrees/180 * Math.PI; 

現在補間庫只會從一個值插值到另一個,並且不知道這些值表示。所以在旋轉時,它根本無法知道如何處理最短路徑。但是,您可以在開始補間之前執行此操作。假設我們從2.6-2.6(或149°到-149°)生成動畫。

var from = 2.6, to = -2.6; 

動畫的方向和角距離可以計算爲

var distance = to - from; 
// === -5.2 

這裏負值意味着反時針,並5.2(〜298°)是「距離」相機將行進。現在請記住,任何角度加號或減號360°(2 * Math.PI)都會將您置於相同的位置。所以讓我們嘗試:

var distance = (to + 2 * Math.PI) - from; 
// === 1.083185307179586 (~62°) 

所以,如果你從你的位置2.6旋轉-2.6 + 2 * Math.PI(或從149°至-149°+ 360°= 211°),你會得到一個更短的順時針動畫路徑。

要確保所有的值留在允許的範圍內,我們改變的onUpdate功能一點點正確環繞:

controls.setThetaPhi(
    tween.target.theta % Math.PI, 
    tween.target.phi % Math.PI, 
    tween.target.radius); 

你可能也想更新currentPos值與實際動畫開始之前和計算之下的值發生。

剩下的事情就是解決這個問題的一般情況,以便找出何時做順時針和逆時針旋轉。要查看其他方式是否會更短,我們只需要查看距離是否大於180°:

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; 
    } 
}