Bunun için henüz tam denklemler üzerinde çalışmadım, ama başımıza problemin etrafını sarmaya yardımcı olacak bazı görseller var. Bazı geometriye kaynar:
( Kenney ile araba simgeleri )
Herhangi bir başlangıç noktası ve yönlendirmeden, minimum dönüş yarıçapımızla biri solda, diğeri sağda olmak üzere iki daire çizebiliriz. Bunlar, yolumuza mümkün olan en sıkı başlangıçtaki noktaları açıklar.
İstediğimiz son konum ve yön için de aynısını yapabiliriz. Bu daireler yolumuzun mümkün olan en sıkı sonunu tanımlar.
Şimdi sorun, başlangıç çemberlerinden birini bitiş çemberlerinden birine birleştiren ve her birini tanjant boyunca öpen bir yol bulmada azalıyor.
(Bu, soruda bahsedilmeyen aradaki engeller etrafında yol bulmamız gerekmediğini varsayıyor. Stormwind'in cevabı, bu tür problemler için navigasyon grafik bilgilerini nasıl kullanabileceğimize geliyor. geçmek için aşağıdaki yöntemi planın her bir bölümüne uygulayabiliriz.)
Basitlik için düz çizgiler kullanırsak, şöyle bir şey alırız:
Bu bize sınırlayıcı davayı verir. Bu yöntemle bir yol bulduktan sonra, iki dairenin öpüştüğü noktaya kadar daha az doğrudan ama daha düzgün bir yol elde etmek için başlangıç veya bitiş dairelerinden birini veya her ikisini yapay olarak şişirebilirsiniz.
Bu yolları hesaplamak
Vakaları bir dönüş yönü için çalışalım - yolumuza sağa dönerek başladığımızı varsayalım.
Sağa dönüş dairemizin merkezi:
startRightCenter = carStart.position + carStart.right * minRadius
Yolumuzun düz bölümünün açısını diyelim (pozitif x ekseninden ölçülür) pathAngle
Biz bir vektör çizerseniz rightCenter
biz dönüş çapı (ki biz pathAngle dönük olmalıdır işaret) terk noktaya, vektör daha sonra bu ...
startOffset = minRadius * (-cos(pathAngle), sin(pathAngle))
Bu, daireyi terk ettiğimiz noktanın ...
departure = startRightCenter + startOffset
Bir dönüş çemberine tekrar girdiğimiz nokta, sola mı yoksa sağa mı dönmeyi hedeflediğimize bağlıdır:
// To end with a right turn:
reentry = endRightCenter + startOffset
// To end with a left turn: (crossover)
reentry = endLeftCenter - startOffset
Biz işimizi doğru yaptık Şimdi, eğer, çizgi birleştirme departure
için reentry
dik olması gerektiğini startOffset
:
dot(reentry - departure, startOffset) = 0
Ve bu denklemi çözmek bize bunun doğru olduğu açı (ları) verecektir. (Burada çoğul kullanıyorum çünkü teknik olarak böyle iki açı var, ancak bunlardan biri tersine sürmeyi içeriyor, bu genellikle istediğimiz şey değil)
Örnek olarak sağa dönüşü sağa dönüş davasına koyalım:
dot(endRightCenter + startOffset - startRightCenter - startOffset, startOffset) = 0
dot(endRightCenter - startRightCenter, startOffset) = 0
pathAngle = atan2(endRightCenter - startRightCenter)
Geçiş davası daha karmaşıktır - henüz tüm matematiği henüz çalışmadığım. Kalan ayrıntıları incelerken sizin için yararlı olması durumunda, cevabı şimdilik olmadan göndereceğim.
Düzenleme: Minimum dönüş yarıçapı içindeki hedef
Görünüşe göre, bu yöntem, varış noktası minimum dönüş mesafemizden daha yakın olsa bile genellikle kutudan çıkar çıkmaz çalışır. Yeniden giriş çevrelerinden birinin en azından bir kısmı dönüş yarıçapının dışına çıkıyor ve biraz tuzlu kraker benzeri bir şey elde etmemize izin vermediğimiz sürece uygun bir yol bulmamıza izin veriyor ...
Eğer yolu bu şekilde beğenmezsek (ya da mümkün değilse - her vakayı ayrıntılı olarak kontrol etmedim - belki imkansız olanlar var), uygun olana kadar her zaman doğrudan ileri veya geri gidebiliriz Yukarıda gösterildiği gibi bir başlangıç ve bitiş çemberi arasındaki öpüşme kontağı.