Bí quyết là hãy nhớ rằng các góc (ít nhất là trong không gian Euclide) được định kỳ bằng 2 * pi. Nếu chênh lệch giữa góc hiện tại và góc mục tiêu quá lớn (tức là con trỏ đã vượt qua ranh giới), chỉ cần điều chỉnh góc hiện tại bằng cách thêm hoặc trừ 2 * pi tương ứng.
Trong trường hợp này, bạn có thể thử các cách sau: (Tôi chưa bao giờ lập trình bằng Javascript trước đây, vì vậy hãy tha thứ cho phong cách mã hóa của tôi.)
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 : Trong quá trình thực hiện này, việc di chuyển con trỏ quá nhanh xung quanh tâm khớp khiến nó bị giật. Đây là hành vi dự định, vì vận tốc góc của khớp luôn tỷ lệ thuận với dtheta
. Nếu hành vi này là không mong muốn, vấn đề có thể dễ dàng được khắc phục bằng cách đặt một nắp trên gia tốc góc của khớp.
Để làm điều này, chúng ta sẽ cần theo dõi vận tốc của khớp và tăng tốc tối đa:
joint = {
// snip
velocity: 0,
maxAccel: 0.01
},
Sau đó, để thuận tiện, chúng tôi sẽ giới thiệu chức năng cắt:
function clip(x, min, max) {
return x < min ? min : x > max ? max : x
}
Bây giờ, mã chuyển động của chúng tôi trông như thế này. Đầu tiên, chúng tôi tính toán dtheta
như trước, điều chỉnh joint.angle
khi cần thiết:
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;
Sau đó, thay vì di chuyển khớp ngay lập tức, chúng tôi tính toán vận tốc mục tiêu và sử dụng clip
để buộc nó trong phạm vi chấp nhận được.
var targetVel = ( joint.targetAngle - joint.angle ) * joint.easing;
joint.velocity = clip(targetVel,
joint.velocity - joint.maxAccel,
joint.velocity + joint.maxAccel);
joint.angle += joint.velocity;
Điều này tạo ra chuyển động trơn tru, ngay cả khi chuyển hướng, trong khi thực hiện các phép tính chỉ trong một chiều. Hơn nữa, nó cho phép vận tốc và gia tốc của khớp được điều chỉnh độc lập. Xem bản demo tại đây: http://codepen.io/anon/pen/HGnDF/