Il trucco è ricordare che gli angoli (almeno nello spazio euclideo) sono periodici di 2 * pi. Se la differenza tra l'angolo corrente e l'angolo target è troppo grande (ovvero il cursore ha oltrepassato il limite), basta regolare l'angolo corrente aggiungendo o sottraendo 2 * pi di conseguenza.
In questo caso, puoi provare quanto segue: (Non ho mai programmato in Javascript prima, quindi perdona il mio stile di codifica.)
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;
EDIT : in questa implementazione, spostare il cursore troppo rapidamente attorno al centro dell'articolazione provoca uno strappo. Questo è il comportamento previsto, poiché la velocità angolare dell'articolazione è sempre proporzionale dtheta
. Se questo comportamento non è desiderato, il problema può essere facilmente risolto posizionando un cappuccio sull'accelerazione angolare dell'articolazione.
Per fare ciò, dovremo tenere traccia della velocità del giunto e imporre una massima accelerazione:
joint = {
// snip
velocity: 0,
maxAccel: 0.01
},
Quindi, per nostra comodità, introdurremo una funzione di ritaglio:
function clip(x, min, max) {
return x < min ? min : x > max ? max : x
}
Ora, il nostro codice di movimento è simile al seguente. Innanzitutto, calcoliamo dtheta
come prima, adattando joint.angle
se necessario:
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;
Quindi, invece di muovere immediatamente l'articolazione, calcoliamo una velocità target e la usiamo clip
per forzarla all'interno del nostro intervallo accettabile.
var targetVel = ( joint.targetAngle - joint.angle ) * joint.easing;
joint.velocity = clip(targetVel,
joint.velocity - joint.maxAccel,
joint.velocity + joint.maxAccel);
joint.angle += joint.velocity;
Ciò produce un movimento fluido, anche quando si cambia direzione, mentre si eseguono calcoli in una sola dimensione. Inoltre, consente di regolare indipendentemente la velocità e l'accelerazione dell'articolazione. Guarda la demo qui: http://codepen.io/anon/pen/HGnDF/