ThreeJS oribital camera short rotation

喜夏-厌秋 提交于 2019-12-06 06:07:51

So that "strange unit-system" is just radians and it's quite common to measure theta/phi values in a range from -180° to 180° and -90° to 90° (think latitude/longitude, same thing). The conversion is simple:

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

Now the tweening-library will just interpolate from one value to the other and doesn't know what these values represent. So it simply can't know how to handle the shortest path when it comes to rotations. However, you can do this before starting the tween.

Say we animate from 2.6 to -2.6 (or 149° to -149°).

var from = 2.6, to = -2.6;

The direction and angular distance for the animation can be calculated as

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

A negative value here means counterclockwise, and 5.2 (~298°) is the "distance" the camera will travel. Now keep in mind that any angle plus or minus 360° (2 * Math.PI) will essentially land you at the same position. So lets try:

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

So, if you rotate from your position at 2.6 to -2.6 + 2 * Math.PI (or, from 149° to -149° + 360° = 211°), you will get a clockwise animation with a shorter path.

To make sure that all values stay in their allowed range, we change the onUpdate-function a little bit to wrap around properly:

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

You will probably also want to update the currentPos value with the actual values before the animation starts and below computation happens.

What's left to do is solving this for the general case, so to find out when to do the clockwise and counterclockwise rotation. To see if the other way around would be shorter, we just need to see if the distance would be greater than 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;
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!