İşin püf noktası, (en azından Öklid uzayında) açıların 2 x pi ile periyodik olduğunu hatırlamaktır. Geçerli açı ile hedef açı arasındaki fark çok büyükse (örneğin imleç sınırı aştıysa), geçerli açıyı uygun şekilde 2 * pi ekleyerek veya çıkararak ayarlayın.
Bu durumda, aşağıdakileri deneyebilirsiniz: (Daha önce Javascript’te daha önce hiç programlamadım, bu yüzden kodlama stilimi affedin.)
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 : Bu uygulamada, imleci eklemin merkezi çevresinde çok hızlı hareket ettirmek sarsıntıya neden olur. Amaçlanan davranış budur, çünkü eklemin açısal hızı daima ile orantılıdır dtheta. Bu davranış istenmiyorsa, derzinin açısal ivmesi üzerine bir başlık yerleştirilerek sorun kolayca çözülebilir.
Bunu yapmak için, eklemin hızını takip etmemiz ve maksimum hızlanma uygulamamız gerekir:
joint = {
// snip
velocity: 0,
maxAccel: 0.01
},
Sonra, rahatlığımız için, kırpma işlevini tanıtacağız:
function clip(x, min, max) {
return x < min ? min : x > max ? max : x
}
Şimdi, hareket kodumuz böyle gözüküyor. Öncelikle, gerektiği gibi dthetaayarlayarak joint.angle, önceki gibi hesaplıyoruz :
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;
Sonra, derzleri derhal hareket ettirmek yerine, bir hedef hız hesaplıyoruz ve cliponu kabul edilebilir aralığımız içinde zorlamak için kullanıyoruz .
var targetVel = ( joint.targetAngle - joint.angle ) * joint.easing;
joint.velocity = clip(targetVel,
joint.velocity - joint.maxAccel,
joint.velocity + joint.maxAccel);
joint.angle += joint.velocity;
Bu, sadece bir boyutta hesaplamalar yaparken yön değiştirirken bile düzgün hareket sağlar. Ayrıca, eklemin hız ve ivmesinin bağımsız olarak ayarlanmasını sağlar. Buraya bakınız demo: http://codepen.io/anon/pen/HGnDF/