El truco es recordar que los ángulos (al menos en el espacio euclidiano) son periódicos por 2 * pi. Si la diferencia entre el ángulo actual y el ángulo objetivo es demasiado grande (es decir, el cursor ha cruzado el límite), simplemente ajuste el ángulo actual sumando o restando 2 * pi en consecuencia.
En este caso, puede intentar lo siguiente: (Nunca he programado en Javascript antes, así que perdone mi estilo de codificación).
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;
EDITAR : en esta implementación, mover el cursor demasiado rápido alrededor del centro de la articulación hace que se mueva. Este es el comportamiento previsto, ya que la velocidad angular de la articulación es siempre proporcional adtheta
. Si este comportamiento no es deseado, el problema se puede solucionar fácilmente colocando una tapa en la aceleración angular de la articulación.
Para hacer esto, necesitaremos hacer un seguimiento de la velocidad de la articulación e imponer una aceleración máxima:
joint = {
// snip
velocity: 0,
maxAccel: 0.01
},
Luego, para nuestra conveniencia, presentaremos una función de recorte:
function clip(x, min, max) {
return x < min ? min : x > max ? max : x
}
Ahora, nuestro código de movimiento se ve así. Primero, calculamos dtheta
como antes, ajustando joint.angle
según sea necesario:
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;
Luego, en lugar de mover la articulación de inmediato, calculamos una velocidad objetivo y la usamos clip
para forzarla dentro de nuestro rango aceptable.
var targetVel = ( joint.targetAngle - joint.angle ) * joint.easing;
joint.velocity = clip(targetVel,
joint.velocity - joint.maxAccel,
joint.velocity + joint.maxAccel);
joint.angle += joint.velocity;
Esto produce un movimiento suave, incluso al cambiar de dirección, mientras se realizan cálculos en una sola dimensión. Además, permite que la velocidad y la aceleración de la articulación se ajusten independientemente. Ver demostración aquí: http://codepen.io/anon/pen/HGnDF/