Хитрость заключается в том, чтобы помнить, что углы (по крайней мере, в евклидовом пространстве) периодичны на 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/