เคล็ดลับคือการจำไว้ว่ามุม (อย่างน้อยในอวกาศยูคลิด) นั้นเป็นระยะ 2 * pi หากความแตกต่างระหว่างมุมปัจจุบันและมุมเป้าหมายมีขนาดใหญ่เกินไป (เช่นเคอร์เซอร์ข้ามเขตแดน) เพียงแค่ปรับมุมปัจจุบันโดยการเพิ่มหรือลบ 2 * pi ตามลำดับ
ในกรณีนี้คุณสามารถลองทำสิ่งต่อไปนี้: (ฉันไม่เคยตั้งโปรแกรมใน 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/