İş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 dtheta
ayarlayarak 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 clip
onu 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/