Sztuka polega na tym, aby pamiętać, że kąty (przynajmniej w przestrzeni euklidesowej) są okresowe o 2 * pi. Jeśli różnica między bieżącym kątem a kątem docelowym jest zbyt duża (tzn. Kursor przekroczył granicę), po prostu dostosuj aktualny kąt, odpowiednio dodając lub odejmując 2 * pi.
W takim przypadku możesz spróbować wykonać następujące czynności: (Nigdy wcześniej nie programowałem w JavaScript, więc wybacz mój styl kodowania).
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;
EDYCJA : W tej implementacji zbyt szybkie przesuwanie kursora wokół środka stawu powoduje jego szarpnięcie. Jest to zamierzone zachowanie, ponieważ prędkość kątowa złącza jest zawsze proporcjonalna do dtheta. Jeśli takie zachowanie jest niepożądane, problem można łatwo rozwiązać, nakładając kołpak na przyspieszenie kątowe stawu.
Aby to zrobić, musimy śledzić prędkość połączenia i nałożyć maksymalne przyspieszenie:
joint = {
// snip
velocity: 0,
maxAccel: 0.01
},
Następnie dla naszej wygody wprowadzimy funkcję obcinania:
function clip(x, min, max) {
return x < min ? min : x > max ? max : x
}
Teraz nasz kod ruchu wygląda tak. Najpierw obliczamy dthetajak poprzednio, dostosowując joint.anglew razie potrzeby:
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;
Następnie, zamiast natychmiastowego przesunięcia stawu, obliczamy prędkość docelową i używamy jej clipdo wymuszenia jej w dopuszczalnym zakresie.
var targetVel = ( joint.targetAngle - joint.angle ) * joint.easing;
joint.velocity = clip(targetVel,
joint.velocity - joint.maxAccel,
joint.velocity + joint.maxAccel);
joint.angle += joint.velocity;
Zapewnia to płynny ruch, nawet przy zmianie kierunku, podczas wykonywania obliczeń tylko w jednym wymiarze. Ponadto umożliwia niezależną regulację prędkości i przyspieszenia złącza. Zobacz demo tutaj: http://codepen.io/anon/pen/HGnDF/