三个JS轨道相机短旋转
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);
}
});
这很好用,但是没有考虑到达那里的最短路线。所以它经常可以去 'round the back' 全球。
ThreeJS 似乎在一个非常奇怪的单位系统中测量角度:
0、1.57(相当于 90 度)、3.14(eq 180dg),然后在 3.14 跳转到 -3.14、-1.57(相当于 270dg),然后回到 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
所以 "strange unit-system" 就是 radians 并且在 -180° 到 180° 和 -90° 到 90° 范围内测量 theta/phi 值是很常见的(想想latitude/longitude,同样的事情)。转换很简单:
angleDegrees = radians / Math.PI * 180;
radians = angleDegrees / 180 * Math.PI;
现在补间库只会从一个值插入到另一个值,而不知道这些值代表什么。因此,当涉及到旋转时,它根本不知道如何处理最短路径。但是,您可以在开始补间之前执行此操作。
假设我们从 2.6
到 -2.6
(或 149° 到 -149°)设置动画。
var from = 2.6, to = -2.6;
动画的方向和angular距离可以计算为
var distance = to - from;
// === -5.2
此处的负值表示逆时针方向,5.2
(~298°)是相机将移动的"distance"。现在请记住,任何正负 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;
}
}
我有一个轨道相机,轨道是一个地球。地球上有几个标记,用户可以点击,相机将移动到那个点。
像这样使用 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);
}
});
这很好用,但是没有考虑到达那里的最短路线。所以它经常可以去 'round the back' 全球。
ThreeJS 似乎在一个非常奇怪的单位系统中测量角度: 0、1.57(相当于 90 度)、3.14(eq 180dg),然后在 3.14 跳转到 -3.14、-1.57(相当于 270dg),然后回到 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
所以 "strange unit-system" 就是 radians 并且在 -180° 到 180° 和 -90° 到 90° 范围内测量 theta/phi 值是很常见的(想想latitude/longitude,同样的事情)。转换很简单:
angleDegrees = radians / Math.PI * 180;
radians = angleDegrees / 180 * Math.PI;
现在补间库只会从一个值插入到另一个值,而不知道这些值代表什么。因此,当涉及到旋转时,它根本不知道如何处理最短路径。但是,您可以在开始补间之前执行此操作。
假设我们从 2.6
到 -2.6
(或 149° 到 -149°)设置动画。
var from = 2.6, to = -2.6;
动画的方向和angular距离可以计算为
var distance = to - from;
// === -5.2
此处的负值表示逆时针方向,5.2
(~298°)是相机将移动的"distance"。现在请记住,任何正负 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;
}
}