ฉันยังไม่ได้ทำงานกับสมการแบบเต็มรูปแบบสำหรับเรื่องนี้ แต่นี่เป็นภาพบางส่วนที่จะช่วยแก้ปัญหาของเรา มันเดือดลงไปถึงรูปทรงเรขาคณิต:
( ไอคอนรถยนต์ผ่าน Kenney )
จากจุดเริ่มต้นและทิศทางที่กำหนดเราสามารถวาดวงกลมสองวงด้วยรัศมีวงเลี้ยวต่ำสุดของเรา - หนึ่งทางด้านซ้ายหนึ่งวงกลมทางขวา สิ่งเหล่านี้อธิบายถึงจุดเริ่มต้นที่แคบที่สุดที่เป็นไปได้ในเส้นทางของเรา
เราสามารถทำเช่นเดียวกันสำหรับตำแหน่งและทิศทางที่ต้องการ แวดวงเหล่านี้อธิบายจุดสิ้นสุดที่เป็นไปได้ที่แน่นที่สุดสำหรับเส้นทางของเรา
ตอนนี้ปัญหาลดลงในการค้นหาเส้นทางที่เชื่อมต่อหนึ่งในแวดวงเริ่มต้นกับหนึ่งในแวดวงสุดท้ายโดยจูบแต่ละวงตามแทนเจนต์
(นี่เป็นการสมมติว่าเราไม่จำเป็นต้องค้นหาสิ่งกีดขวางในระหว่างนั้นซึ่งไม่ได้กล่าวถึงในคำถามคำตอบของ Stormwind จะเป็นวิธีที่เราสามารถใช้ข้อมูลกราฟนำทางสำหรับปัญหาประเภทนี้เมื่อเรามีลำดับของโหนด ในการผ่านเราสามารถใช้วิธีด้านล่างกับแต่ละส่วนของแผน)
ถ้าเพื่อความเรียบง่ายเราใช้เส้นตรงเราจะได้อะไรเช่นนี้:
สิ่งนี้ทำให้เรามีข้อ จำกัด เมื่อคุณพบเส้นทางด้วยวิธีนี้แล้วคุณสามารถขยายวงกลมเริ่มต้นและจุดสิ้นสุดอย่างใดอย่างหนึ่งหรือทั้งสองอย่างเพื่อให้ได้เส้นทางที่ตรงไปตรงมา แต่เรียบเนียนขึ้นจนถึงจุดที่วงกลมทั้งสองจูบ
การคำนวณเส้นทางเหล่านี้
ลองหาเคสสำหรับทิศทางการเลี้ยวเดียวบอกว่าเราเริ่มต้นเส้นทางของเราโดยเลี้ยวขวา
ศูนย์กลางของวงเลี้ยวขวาของเราคือ:
startRightCenter = carStart.position + carStart.right * minRadius
ลองเรียกมุมของส่วนทางตรงของเส้นทางของเรา (วัดจากแกน x บวก) pathAngle
หากเราวาดเวกเตอร์จากrightCenter
จุดที่เราออกจากวงเลี้ยว (ซึ่งในจุดที่เราต้องเผชิญกับ pathAngle) แสดงว่าเวกเตอร์นั้นคือ ...
startOffset = minRadius * (-cos(pathAngle), sin(pathAngle))
นั่นหมายความว่าจุดที่เราออกจากวงกลมต้อง ...
departure = startRightCenter + startOffset
จุดที่เราเข้าสู่วงเลี้ยวอีกครั้งขึ้นอยู่กับว่าเราตั้งใจจะจบด้วยเลี้ยวซ้ายหรือเลี้ยวขวา:
// To end with a right turn:
reentry = endRightCenter + startOffset
// To end with a left turn: (crossover)
reentry = endLeftCenter - startOffset
ตอนนี้ถ้าเราได้ทำถูกต้องงานของเราเส้นที่เชื่อมdeparture
ไปreentry
ควรจะตั้งฉากกับstartOffset
:
dot(reentry - departure, startOffset) = 0
และการแก้สมการนี้จะทำให้เราได้มุมที่นี่เป็นจริง (ฉันใช้พหูพจน์ที่นี่เพราะในทางเทคนิคมีสองมุมเช่นนี้ แต่หนึ่งในนั้นเกี่ยวข้องกับการขับขี่แบบย้อนกลับซึ่งมักจะไม่ใช่สิ่งที่เราต้องการ)
ลองแทนกรณีเลี้ยวขวาไปเลี้ยวขวาเป็นตัวอย่าง:
dot(endRightCenter + startOffset - startRightCenter - startOffset, startOffset) = 0
dot(endRightCenter - startRightCenter, startOffset) = 0
pathAngle = atan2(endRightCenter - startRightCenter)
กรณีครอสโอเวอร์นั้นซับซ้อนกว่า - เป็นกรณีที่ฉันยังไม่ได้คำนวณคณิตศาสตร์ทั้งหมด ฉันจะโพสต์คำตอบโดยไม่ต้องตอนนี้ในกรณีที่เป็นประโยชน์กับคุณในขณะที่ฉันทำงานรายละเอียดที่เหลือ
แก้ไข: ปลายทางภายในรัศมีวงเลี้ยวต่ำสุด
มันกลับกลายเป็นว่าวิธีการนี้มักจะทำงานนอกกรอบแม้ในขณะที่ปลายทางอยู่ใกล้กว่าระยะทางเลี้ยวต่ำสุดของเรา อย่างน้อยบางส่วนของหนึ่งในวงกลมที่กลับเข้ามาในรัศมีวงเลี้ยวทำให้เราพบเส้นทางที่มีชีวิตได้ตราบใดที่เราไม่สนใจว่ามันจะเป็นเหมือนเพรทเซล ...
หากเราไม่ชอบเส้นทางที่เราไปถึงทางนั้น (หรือถ้าไม่เป็นไปได้ - ฉันไม่ได้ตรวจสอบทุกกรณีอย่างละเอียด - บางทีอาจเป็นไปไม่ได้) เราสามารถขับตรงไปข้างหน้าหรือข้างหลังจนกว่าเราจะได้รับที่เหมาะสม จูบผู้ติดต่อระหว่างวงกลมเริ่มต้นและจุดสิ้นสุดดังที่แสดงไว้ด้านบน