Хитрость заключается в том, чтобы помнить, что углы (по крайней мере, в евклидовом пространстве) периодичны на 2 * пи. Если разница между текущим углом и целевым углом слишком велика (т. Е. Курсор пересек границу), просто отрегулируйте текущий угол, добавив или вычтя 2 * пи соответственно.
В этом случае вы можете попробовать следующее: (Я никогда раньше не программировал в 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/