การเคลื่อนไหวโค้งระหว่างสองจุด


15

เทคนิคที่ดีในการทำให้วัตถุเคลื่อนที่ระหว่างจุดไปยังจุดใดในการเคลื่อนไหวโค้งที่ดีคืออะไร?

ตำแหน่งสุดท้ายอาจเคลื่อนไหวเช่นวิถีวิถีของขีปนาวุธกลับบ้าน

คำตอบ:


11

สมมติว่าคุณต้องการให้สิ่งนี้เป็นแบบทีละเฟรม (ซึ่งเป้าหมายสามารถเคลื่อนที่ได้) และไม่ใช่เส้นทางที่คำนวณไว้ล่วงหน้านี่เป็นเรื่องง่ายอย่างเหลือเชื่อ:

ทุกเฟรมเปรียบเทียบความเร็ว - เวกเตอร์ของขีปนาวุธกับเวกเตอร์( เป้าหมายตำแหน่ง - ขีปนาวุธตำแหน่ง) ; นั่นคือเวกเตอร์ชี้จากขีปนาวุธไปยังเป้าหมาย ทุกเฟรมถ้าเวกเตอร์สองตัวไม่มีทิศทางเดียวกันให้หมุน veloity-vector ไปทางเวกเตอร์อื่น ๆ เล็กน้อยดังนั้นทุกเฟรมที่มิสไซล์จะเข้าใกล้เป้าหมายมากขึ้น

คุณสามารถกำหนดได้ว่าจะหมุนตามเข็มนาฬิกาหรือทวนเข็มนาฬิกาโดยดูที่เครื่องหมายของกากบาทระหว่างเวกเตอร์สองตัว


[แก้ไข] รหัส XNA-ish (ฉันไม่มี XNA เพื่อทดสอบสิ่งนี้):

//Once a frame:

//Get vector spanning from missile to target
Vector2 vectorToTarget = target.Position - missile.Position;

//Convert to Vector3 to do cross-product
Vector3 vectorToTarget3 = new Vector3(vectorToTarget, 0);
Vector3 missileVelocity3 = new Vector3(missile.Velocity, 0);

//Rotate clockwise/counter-clockwise is determined by sign of cross-product
int crossProductSign = Vector3.Cross(missileVelocity3, vectorToTarget3).Z;

//Positive cross-product means rotate counter-clockwise, negative is clockwise
double rotationAngle = 0;
if(crossProductSign > 0)
    rotationAngle = -0.05;
else if(crossProductSign < 0)
    rotationAngle = 0.05;

//I'm not sure how to do rotation in XNA, but the internets tell me it's something like this:
missile.velocity = Vector2.Transform(missile.velocity, Matrix.CreateRotationZ(rotationAngle))

โปรดทราบว่าเนื่องจากrotationAngleมีเพียงสามค่าที่เป็นไปได้ค่าที่เป็นไปได้ทั้งหมดMatrix.CreateRotationZ(rotationAngle)จึงถูกแคชดังนั้นคุณจึงไม่ต้องเรียกมันว่าทุกเฟรม


คุณสามารถให้รหัสหลอกบางอย่างกับฉันใหม่ทั้งหมดนี้ ขณะนี้ฉันกำลังทำงานในมิติที่ 2 เพื่อที่จะลบภาวะแทรกซ้อนบางอย่าง
anonymouse

@anonymouse: ลองดูสิ
BlueRaja - Danny Pflughoeft

15

มีสองเทคนิคที่เป็นไปได้:

เทคนิคแรกคือทำการจำลองด้วยเฟรม นี่เป็นสิ่งที่ดีถ้าคุณกำลังทำอะไรบางอย่างเหมือนจรวดนำกลับในการเล่นเกมซึ่งไม่จำเป็นต้องยิงเป้าของคุณอย่างแน่นอน

ในกรณีนี้คุณต้องการติดตามตำแหน่งและความเร็วของวัตถุ แต่ละเฟรมจะมองทิศทางไปยังเป้าหมายและทิศทางการเคลื่อนไหวปัจจุบันและปรับความเร็วให้เหมาะสม

หากคุณยึดความเร็วในทันทีขีปนาวุธของคุณจะเข้าเป้าเสมอ แต่ถ้าคุณปรับความเร็วด้วยจำนวนเล็กน้อยในแต่ละเฟรมขีปนาวุธของคุณจะโค้งไปยังเป้าหมาย - และหากมันโค้งช้าพอเป้าหมายก็สามารถหลบได้

เทคนิคที่สองคือการใช้วิธีการพารามิเตอร์ สิ่งนี้มีประโยชน์สำหรับการเคลื่อนไหวสิ่งต่าง ๆ ที่คุณต้องการเข้าถึงกลุ่มเป้าหมายของคุณอย่างแม่นยำและคาดการณ์ได้ ในกรณีนี้คุณมักจะใช้ "เวลา" เป็นพารามิเตอร์ของคุณและใส่ลงในฟังก์ชั่นบางชนิด

ชุดฟังก์ชั่นที่มีประโยชน์อย่างยิ่งคือสมการการเคลื่อนที่ที่คุณเรียนรู้ในวิชาฟิสิกส์ระดับมัธยม โดยการใช้สิ่งเหล่านี้กับทั้งสองแกนคุณสามารถรับวิถีกระสุน ด้วยคณิตศาสตร์เล็กน้อยคุณสามารถกำหนดพารามิเตอร์เริ่มต้นที่จะเข้าถึงกลุ่มเป้าหมาย - แม้เป็นกลุ่มที่เคลื่อนไหวได้ถ้ามันสามารถคาดเดาได้

XNA ยังมีฟังก์ชั่นการแก้ไขและการเคลื่อนไหวโค้งจำนวนมาก ลองดูที่เป็นเอกสารVector2 และ MathHelperเหล่านี้มีฟังก์ชั่นการแก้ไขบางอย่างที่คุณสามารถใช้และรวมเข้าด้วยกันเพื่อทำสิ่งที่น่าสนใจ ตัวอย่างเช่นการยิงขีปนาวุธ: Lerp(สอดแทรกเชิงเส้น) ตำแหน่งของขีปนาวุธของคุณจากจุดเริ่มต้นไปยังตำแหน่งเป้าหมายและยังลอบวางตำแหน่งเป้าหมายจากเป้าหมายเริ่มต้นไปยังตำแหน่งที่แท้จริง (เปลี่ยน) ของวัตถุเป้าหมาย สิ่งนี้จะให้เอฟเฟกต์ "ล็อค" ที่ดี

(นอกจากนี้ยังมีฟังก์ชั่นบางอย่างสำหรับการสร้างส่วนโค้งเช่น: CatmulRom, Hermite. เหล่านี้อาจใช้งานได้ยากกับเป้าหมายที่เคลื่อนที่ได้)

หากคุณดูที่ "ผ่อนคลาย" (ในบริบทของภาพเคลื่อนไหว) คุณสามารถรับฟังก์ชั่นการแก้ไขที่น่าสนใจซึ่งสามารถให้เอฟเฟกต์ที่น่าสนใจเช่นการเร่งความเร็ว

ตอนนี้ - คุณอาจบอกว่าเทคนิคนี้ให้ผลลัพธ์แปลก ๆ ตามที่คุณต้องการ อย่างไรก็ตามในทางปฏิบัติตราบใดที่กระสุนปืนของคุณเคลื่อนที่เร็วกว่าเป้าหมายของคุณก็มักจะดูดี หากเป็นปัญหาคุณควรใช้เทคนิคเฟรมแทน


3

คุณอาจต้องการที่จะมองขึ้นคลื่นไซน์หรืออาจจะเป็นเส้นโค้งเบซิเยร์ ฉันไม่รู้ว่าคลื่นไซน์นั้นเป็นเรื่องปกติหรือไม่ แต่ฉันไม่สามารถเห็นได้ว่าทำไมมันถึงแย่


การใช้เส้นโค้ง Bezier กับB-Splinesช่วยให้สามารถแสดงเส้นโค้งใด ๆ ได้อย่างแม่นยำ หากคุณต้องการความแม่นยำSpline ของ Cubic Hermitนั้นแม่นยำกว่าเล็กน้อย ระลึกไว้เสมอว่าบางครั้งความไม่ถูกต้องจะทำให้คุณรู้สึกถึงความเป็นธรรมชาติ
doppelgreener

+1 สำหรับ Bezier curves สำหรับการใช้งานที่อธิบายไว้อาจเป็นวิธีที่ง่ายที่สุดและสามารถควบคุมได้มากที่สุด
ggambett

1

คุณสามารถดูพฤติกรรมของพวงมาลัยได้ตามที่กำหนดโดย Craig Reynolds: http://red3d.com/cwr/steer/

มักใช้ใน AI เพื่อให้ NPC เคลื่อนที่ไปยังเป้าหมายของพวกเขา

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.