假设i)旋转分别对应于全局原点,而不是对象本身,以及ii)您想要应用增量(如果我们无法获取这些,请参见下文):
对于每个点:
1、求点相对于轴的距离。
2、求点相对于轴的当前角度。
3.使用基本的二维cos/sin
polar projection
,因为排除的轴是
unit vector
.
function rotateY( points, deltaAngle ) {
const _points = points;
if ( ! Array.isArray( points ) ) points = [ points ];
for ( let i = 0; i < points.length; i ++ ) {
const newAngle = Math.atan2( points[ i ].z, points[ i ].x ) + deltaAngle;
const distance = ( points[ i ].x ** 2 + points[ i ].z ** 2 ) ** ( 1 / 2 );
points[ i ].x = distance * Math.cos( newAngle );
points[ i ].z = distance * Math.sin( newAngle );
}
return _points;
}
该算法适用于X和Z旋转,只要第一个轴用于
Math.atan2
与使用
Math.sin
.
注意:我使用了
exponentiation operator
. 除非你使用
Babel
/类似或不关心IE/老用户。
如果无法采用假设ii),我们只需要存储点的原始角度,并具有
newAngle
定义为原始角度加上新角度。
新角度
distance
并在设置时重新添加
x
和
z
. 如果轴本身不分别平行于全局轴,则需要切换到使用
quaternion
为了避免
gimbal lock
. 我建议复制或至少看一看
three.js's implementation
.