트릭은 각도 (적어도 유클리드 공간에서)가 2 * pi만큼 주기적이라는 것을 기억하는 것입니다. 현재 각도와 목표 각도의 차이가 너무 큰 경우 (예 : 커서가 경계를 넘었을 경우) 2 * pi를 더하거나 빼서 현재 각도를 조정하십시오.
이 경우 다음을 시도해 볼 수 있습니다. (이전에 Javascript로 프로그래밍 한 적이 없으므로 코딩 스타일을 용서하십시오.)
var dtheta = joint.targetAngle - joint.angle;
if (dtheta > Math.PI) joint.angle += 2*Math.PI;
else if (dtheta < -Math.PI) joint.angle -= 2*Math.PI;
joint.angle += ( joint.targetAngle - joint.angle ) * joint.easing;
편집 :이 구현에서 커서를 관절 중심 주위로 너무 빨리 움직이면 커서가 찌그러집니다. 조인트의 각속도는 항상에 비례하기 때문에 의도 된 동작 dtheta
입니다. 이 동작이 바람직하지 않은 경우 조인트의 각가속도에 캡을 배치하여 문제를 쉽게 해결할 수 있습니다.
이를 위해서는 조인트의 속도를 추적하고 최대 가속을 적용해야합니다.
joint = {
// snip
velocity: 0,
maxAccel: 0.01
},
그런 다음 편의상 클리핑 기능을 소개합니다.
function clip(x, min, max) {
return x < min ? min : x > max ? max : x
}
이제 우리 운동 코드는 다음과 같습니다. 먼저 필요에 따라 dtheta
조정하여 이전과 같이 계산 joint.angle
합니다.
var dtheta = joint.targetAngle - joint.angle;
if (dtheta > Math.PI) joint.angle += 2*Math.PI;
else if (dtheta < -Math.PI) joint.angle -= 2*Math.PI;
그런 다음 조인트를 즉시 이동하는 대신 목표 속도를 계산하여 clip
허용 범위 내에서 강제로 사용 합니다.
var targetVel = ( joint.targetAngle - joint.angle ) * joint.easing;
joint.velocity = clip(targetVel,
joint.velocity - joint.maxAccel,
joint.velocity + joint.maxAccel);
joint.angle += joint.velocity;
이렇게하면 방향을 전환 할 때에도 한 차원에서만 계산을 수행하면서 부드러운 동작이 생성됩니다. 또한 조인트의 속도와 가속도를 독립적으로 조정할 수 있습니다. 데모보기 : http://codepen.io/anon/pen/HGnDF/