Kuncinya adalah untuk mengingat bahwa sudut (setidaknya dalam ruang Euclidean) adalah periodik dengan 2 * pi. Jika perbedaan antara sudut saat ini dan sudut target terlalu besar (mis. Kursor telah melewati batas), sesuaikan sudut arus dengan menambahkan atau mengurangi 2 * pi.
Dalam hal ini, Anda dapat mencoba yang berikut ini: (Saya belum pernah memprogram dalam Javascript sebelumnya, jadi maafkan gaya koding saya.)
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 : Dalam implementasi ini, memindahkan kursor terlalu cepat di sekitar pusat sambungan menyebabkannya menyentak. Ini adalah perilaku yang dimaksudkan, karena kecepatan sudut sendi selalu sebanding dengan dtheta
. Jika perilaku ini tidak diinginkan, masalah dapat dengan mudah diperbaiki dengan menempatkan tutup pada percepatan sudut sambungan.
Untuk melakukan ini, kita harus melacak kecepatan sambungan dan memaksakan akselerasi maksimum:
joint = {
// snip
velocity: 0,
maxAccel: 0.01
},
Kemudian, untuk kenyamanan kami, kami akan memperkenalkan fungsi kliping:
function clip(x, min, max) {
return x < min ? min : x > max ? max : x
}
Sekarang, kode gerakan kami terlihat seperti ini. Pertama, kami menghitung dtheta
seperti sebelumnya, menyesuaikan joint.angle
seperlunya:
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;
Kemudian, alih-alih menggerakkan sambungan segera, kami menghitung kecepatan target dan menggunakannya clip
untuk memaksanya dalam rentang yang dapat kami terima.
var targetVel = ( joint.targetAngle - joint.angle ) * joint.easing;
joint.velocity = clip(targetVel,
joint.velocity - joint.maxAccel,
joint.velocity + joint.maxAccel);
joint.angle += joint.velocity;
Ini menghasilkan gerakan yang halus, bahkan saat berganti arah, saat melakukan perhitungan hanya dalam satu dimensi. Selain itu, memungkinkan kecepatan dan percepatan sambungan disesuaikan secara independen. Lihat demo di sini: http://codepen.io/anon/pen/HGnDF/