Geminiz için fiziksel olarak doğru hareketiniz olduğunu varsayacağım, aksi takdirde bu analiz yapılmayacaktır. Bu sorunu doğru bir şekilde çözmek için verimlilikten daha güçlü bir şeye ihtiyacınız var.
Her itici, geminin hareketi üzerinde iki etki yaratacaktır: doğrusal ve açısal. Bunlar bağımsız olarak düşünülebilir. İtici f
bir yönde bir kuvvet üretirse dir
ve kütle merkezinden bir vektörle r
(geometrik merkez veya hareketli grafiğin merkezi değil!) Dengelenirse, doğrusal bileşen üzerindeki etki:
t = f * dir // f is a scalar, dir is unit length
Açısal hız üzerindeki etki tork tarafından verilir:
tau = f * <dir.x, dir.y, 0> CROSS <r.x, r.y, 0> // cross product
t
bir kuvvet vektörüdür (yani doğrusal itme). tau
kütle atalet momenti ile bölündüğünde açısal ivme verecek olan imzalı bir skalerdir. Çok önemlidir dir
ve r
aynı her ikisi de yani hem yerel koordinatlarda veya her ikisi, dünya koordinatlarında, uzay koordinat.
Geminin toplam doğrusal ivmesi, t
her itici için geminin kütlesine bölünmesiyle elde edilen toplamın toplamıdır . Benzer şekilde, açısal ivme sadece torkların toplam kütle atalet momentine (yani başka bir skaler) bölünmesidir. Toplam tork sıfırsa, gemi dönmeyecektir. Benzer şekilde, toplam itme sıfır olduğunda hareket etmeyecektir. Geri çağırma torku skalerdir, ancak itme ( t
's toplamı ) bir 2D vektörüdür.
Bu serginin amacı artık problemimizi Doğrusal Program olarak yazabilmemizdir . Önce gemimizin hareket etmeden dönmesini istiyoruz . Her itici için bir değişkenimiz var, $ x_1, x_2, ... $, iticinin sağlayacağı itme miktarı. Bir kısıtlama kümesi:
0 <= x_i < fmax_i //for each i
fmax
bu itici için maksimum kuvvet nerede (bu, daha güçlü veya daha zayıf olanlara sahip olmamızı sağlar). Sonra, her iki eşitliğin de dedik:
0 = Sum_i x_i * dir_i.x
0 = Sum_i x_i * dir_i.y
Bu, toplam itmenin sıfır olduğunu söyleyerek doğrusal bir ivme uygulamadığımız kısıtlamayı kodlar (itme bir vektördür, bu yüzden her parçanın sıfır olduğunu söyleriz).
Şimdi gemimizin dönmesini istiyoruz. Muhtemelen bunu mümkün olduğunca çabuk yapmak istiyoruz, bu yüzden şunları yapmak istiyoruz:
max (Sum_i x_i * c_i)
where c_i = <dir_i.x, dir_i.y, 0> CROSS <r_i.x, r_i.y, 0>
İçin Çözme x_i
toplamıdır yukarıda üst düzeye çıkarırken, yukarıda eşitsizlikleri ve Eşitlikler tatmin ederken 's, bize istenen itme verecektir. Çoğu programlama dilinde LP kütüphanesi bulunur. Sadece yukarıdaki sorunu içine koyun ve cevabınızı üretecektir.
Benzer bir problem dönmeden hareket etmemizi sağlayacaktır. Diyelim ki sorunumuzu pozitif x yönünde hareket etmek istediğimiz bir koordinat sistemine yeniden yazıyoruz. Sonra kısıtlamalar:
0 <= x_i < fmax_i //for each i
max Sum_i x_i * dir_i.x
0 = Sum_i x_i * dir_i.y
0 = (Sum_i x_i * c_i)
where c_i = <dir_i.x, dir_i.y, 0> CROSS <r_i.x, r_i.y, 0> // as before
İticilerin yalnızca tek bir yönde itme kuvveti üretebileceği kısıtlamasıyla, elde edebileceğiniz dönme türlerinin ve doğrusal hızların sınırları olacaktır. Bu çözüm olarak ortaya çıkacaktır 0 = x_1 = x_2 = ... = x_n
, bu da hiçbir yere ulaşamayacağınız anlamına gelir. Bunu hafifletmek için, her iki tarafa 45 derecelik bir itici yerleştirilen her oyuncu için bir çift küçük, zayıf (% 5 veya% 10) iticiler eklemenizi öneririm. Bu, çözüme daha fazla esneklik kazandıracaktır, çünkü bunlar ana iticilerin zayıf ikincil etkilerine karşı koymak için kullanılabilir.
Son olarak, belki 100 iticiye kadar, LP'ye çözüm çerçeve başına yapılacak kadar hızlıdır. Bununla birlikte, çözüm konuma veya mevcut duruma bağlı olmadığından, şekil değiştiğinde her makul denetleyici giriş kombinasyonu için çözümü önceden hesaplayabilirsiniz (bu, eylemsizlik momentini veya geminin kütlesini değiştiren itici olmayanlar eklemeyi içerir, çünkü iticiler kütle merkezine göre farklı bir konumdadır!). Bu 24 olasılıktır (yani 8 yön kez {sola dönüş, dönüş yok, sağa dönüş}).