2017-11-22 6 views
0
내가 (내 자신의 3D 엔진에서) 자바 스크립트에서 Y 축에 를 회전하려고하고 나는이 기능을 시도

:3D 회전의 새로운 포인트 위치를 계산

function rotateY(amount) { 
    for (var i = 0; i < points.length; i++) { 
    points[i].z = Math.sin(amount) * points[i].x + Math.cos(amount) * points[i].z; 
    points[i].x = Math.cos(amount) * points[i].x - Math.sin(amount) * points[i].z; 
    } 
} 

그것은 회전을하지만, 때마다 그것이 회전 그것은 그것의 x와 z 규모 그래서 그것은 점점 얇아지고있다 .. 당신이 그것을 올바르게 (나는 절대적으로 cos() 및 sin() 이해하지 않는 방법을 도울 수 있습니까, 그냥 코드를 사용해야합니다 .. 감사합니다 Logged :)

답변

1

i) 회전은 객체 자체가 아니라 전역 원본에 해당하고 ii) 델타를 적용하려고한다고 가정합니다 (아래 참조).

각 점 :
1. 축에 대한 점의 거리를 찾습니다.
2. 축에 대한 점의 현재 각도를 찾습니다.
3. 제외 된 축이 unit vector이므로 기본 2-D cos/sin polar projection을 사용하십시오.

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; 

} 

알고리즘은 너무 오랫동안 Math.atan2에 사용되는 제 1 축이 Math.sin 사용 동일 축상 같이, X 및 Z의 회전과 동일하다.

참고 : exponentiation operator을 사용했습니다. Babel/비슷한 것을 사용하거나 IE/옛 사용자를 신경 쓰지 않는 한 프로덕션 환경에서는 이것을 사용하지 않을 것입니다. 가정 II)를 수행 할 수없는 경우


, 우리는 단순히 점의 원래 각도를 저장하고 newAngle 원래 각도를 더한 새로운 각도로 정의 갖고 싶어.

i)를 취할 수 없다는 가정이 복잡해지면. 객체의 축이 단순히 오프셋 된 경우 newAngledistance에서 해당 오프셋을 뺀 다음 xz을 설정할 때 다시 추가 할 수 있습니다. 축 자체가 전역 축과 각각 평행하지 않으면 quaternion을 사용하여 gimbal lock을 피하십시오. 나는 복사하거나 최소한 three.js's implementation을 바라 볼 것을 제안 할 것이다.

+0

하지만 한 가지 더 궁금한 점은 무엇입니까? 그 사이의 거리? – Jacob

+0

y 축에서. 포인트가 {x : 1, y : 6, z : 0}이라면 y 축으로부터의 거리가 1이됩니다. 축은 단위 벡터이므로 3 차원 글로벌 공간과 평면 {x : 1, y : 6, z : 0}이 위치함에 따라 y = 6으로 정의 된 해당 공간이 있습니다. 이 평면에서 {x : 1, z : 0}은 원점에서 1 단위 떨어져 있습니다. [그림이 있습니다.] (https://i.imgur.com/t6ATK04.png) – vox