2012-07-12 22 views
5

Bezier eğrilerini uzay gemilerimin bir istasyonda kenetlendiklerinde seyahat edecekleri yollar olarak kullanıyorum.Kübik Bezier Eğrisi: Maksimum Gradyan ve Çarpışma Önleme?

public class BezierMovement{ 
    public BezierMovement(){ 
     // start docking straight away in this test version 
     initDocking(); 
    } 

    private Vector3 p0; 
    private Vector3 p1; 
    private Vector3 p2; 
    private Vector3 p3; 

    private double tInc = 0.001d; 
    private double t = tInc; 

    protected void initDocking(){ 

     // get current location 
     Vector3 location = getCurrentLocation(); 

     // get docking point 
     Vector3 dockingPoint = getDockingPoint(); 

     // ship's normalised direction vector 
     Vector3 direction = getDirection(); 

     // docking point's normalised direction vector 
     Vector3 dockingDirection = getDockingDirection(); 

     // scalars to multiply normalised vectors by 
     // The higher the number, the "curvier" the curve 
     float curveFactorShip = 10000.0f; 
     float curveFactorDock = 2000.0f; 

     p0 = new Vector3(location.x,location.y,location.z); 

     p1 = new Vector3(location.x + (direction.x * curveFactorShip), 
         location.y + (direction.y * curveFactorShip), 
         location.z + (direction.z * curveFactorShip)); 

     p2 = new Vector3(dockingPoint.x + (dockingDirection.x * curveFactorDock), 
         dockingPoint.y + (dockingDirection.y * curveFactorDock), 
         dockingPoint.z + (dockingDirection.z * curveFactorDock)); 

     p3 = new Vector3(dockingPoint.x, dockingPoint.y, dockingPoint.z); 


    } 

    public void incrementPosition() { 

     bezier(p0, p1, p2, p3, t, getCurrentLocation()); 

     // make ship go back and forth along curve for testing    
     t += tInc; 

     if(t>=1){ 
      tInc = 0-tInc; 
     } else if(t<0){ 
      tInc = 0-tInc; 
     } 

    } 

    protected void bezier(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, double t, Vector3 outputVector){ 

     double a = (1-t)*(1-t)*(1-t); 
     double b = 3*((1-t)*(1-t))*t; 
     double c = 3*(1-t)*(t*t); 
     double d = t*t*t; 

     outputVector.x = a*p0.x + b*p1.x + c*p2.x + d*p3.x; 
     outputVector.y = a*p0.y + b*p1.y + c*p2.y + d*p3.y; 
     outputVector.z = a*p0.z + b*p1.z + c*p2.z + d*p3.z; 

    } 
} 

eğri başlangıç ​​noktası uzay konumdur ve bitiş noktası yerleştirme bölmesine girişidir (kırmızı noktalar: Ben gemi kübik Bezier eğri boyunca t zamanında olması gereken yerde hesaplamak için basit bir algoritma var diyagram üzerinde). Uzay gemisi, yönüne göre normalleştirilmiş bir vektöre sahiptir ve yerleştirme bölmesi, geminin, geldiğinde yerleştirme yuvasına düz olarak hizalanacağı şekilde (şema üzerindeki sarı çizgiler) hareket etmesi gerektiğini gösteren bir başka normalleştirilmiş vektöre sahiptir.

Yeşil çizgi, uzay gemisinin olası bir yolu ve mor dairenin uzay aracının yarıçapıdır. Son olarak, kara kutu istasyonun sınırlayıcı kutusu.

enter image description here

Ben iki sorun var:

uzay sadece ikinci
  • istasyonu aracılığıyla uçamaz uzay başına r radyan çevirmek mümkün olması gerekiyordu

    Bunun şu anlama geldiğini varsayalım:

    a). Geminin çok sıkı bir şekilde dönmesi gereken bir yol sağlayacak "eğri faktörlerini" (kontrol noktası uzunlukları) bulmak

    b). İstasyonla çarpışmanın önlenemeyeceği uzay gemisi konumunu/yönünü bulma (ve bu durumdan dışarıya rehberlik edecek bir yol yaratma, böylece a bölümü ile başlayabilir))

    Ancak, bunlarla birlikte Bir çözüm bulamadığım için çok şansım olmadı. Vektörler, kutular, noktalar ve küreler arasındaki kesişimleri saptamak için kodum var ama henüz bezier eğrileri değil. Ayrıca iki nokta arasındaki mesafeyi bulmama izin veren işlevlerim var.

    Herhangi bir yardım çoğu 5 ya da 6 derece polinomu çözme içerir

    sayesinde James

  • cevap

    3

    bir Kübik Bezier Curve kesin Kavşaklar bulunuyor mutluluk duyacağız. Daha uygun çözümler ya sayısal yöntemler kullanıyor ya da Bezier Eğrisini alt bölümlere ayırıyor.

    protected void subdivide(
         Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3, 
         Vector3 q0, Vector3 q1, Vector3 q2, Vector3 q3, 
         Vector3 q4, Vector3 q5, Vector3 q6) { 
    
        q0.x = p0.x; q0.y = p0.y; q0.z = p0.z; 
        q6.x = p3.x; q6.y = p3.y; q6.z = p3.z; 
    
        q1.x = (p0.x + p1.x) * 0.5; 
        q1.y = (p0.y + p1.y) * 0.5; 
        q1.z = (p0.z + p1.z) * 0.5; 
    
        q5.x = (p2.x + p3.x) * 0.5; 
        q5.y = (p2.y + p3.y) * 0.5; 
        q5.z = (p2.z + p3.z) * 0.5; 
    
        double x3 = (p1.x + p2.x) * 0.5; 
        double y3 = (p1.y + p2.y) * 0.5; 
        double z3 = (p1.z + p2.z) * 0.5; 
    
        q2.x = (q1.x + x3) * 0.5; 
        q2.y = (q1.y + y3) * 0.5; 
        q2.z = (q1.z + z3) * 0.5; 
    
        q4.x = (x3 + q1.x) * 0.5; 
        q4.y = (y3 + q1.y) * 0.5; 
        q4.z = (z3 + q1.z) * 0.5; 
    
        q3.x = (q2.x + q4.x) * 0.5; 
        q3.y = (q2.y + q4.y) * 0.5; 
        q3.z = (q2.z + q4.z) * 0.5; 
    } 
    

    q1 .. q3 birinci bölme olur. q3 .. q6 ikinci segment olur.

    Eğriyi 2-5 kez alt bölümlere ayırın ve kontrol noktalarını bir çoklu çizgi olarak kullanın.


    curvature

    her segmentin bitiş noktalarında hesaplanabilir:

    protected double curvatureAtStart(Vector3 p0, Vector3 p1, Vector3 p2, Vector3 p3) { 
        double dx1 = p1.x - p0.x; 
        double dy1 = p1.y - p0.y; 
        double dz1 = p1.z - p0.z; 
    
        double A = dx1 * dx1 + dy1 * dy1 + dz1 * dz1; 
    
        double dx2 = p0.x - 2*p1.x + p2.x; 
        double dy2 = p0.y - 2*p1.y + p2.y; 
        double dz2 = p0.z - 2*p1.z + p2.z; 
    
        double B = dx1 * dx2 + dy1 * dy2 + dz1 * dz2; 
    
        double Rx = (dx2 - dx1*B/A)/A*2/3; 
        double Ry = (dy2 - dy1*B/A)/A*2/3; 
        double Rz = (dz2 - dz1*B/A)/A*2/3; 
    
        return Math.sqrt(Rx * Rx + Ry * Ry + Rz * Rz); 
    } 
    

    , sorun 1 çözme eğn birkaç kez bölmek ve en eğrilik hesaplamak için her segmentin uç noktası. Bu sadece bir yaklaşım olacaktır, ancak bu bölgede daha iyi bir yaklaşım elde etmek için yüksek eğrilikli segmentleri seçici olarak alt bölümlere ayırabilirsiniz.


    üç eğrileri alt gruplara olabilir, Problem 2 çözmek için: her iki uç noktası hızın sıfır ile

    • bir (C0). Bu düz bir çizgi üretecektir. Birinci uç noktasında hız sıfır ve diğerinde (C1) bir
    • 132510.
    • Biri birinci son noktada bir, diğerinde ise sıfır (C2).

    Tüm eğrileri aynı şekilde alt bölümlere ayırırsanız, son eğrinin denetim noktalarını hızlı bir şekilde değerlendirebilirsiniz. (Düz bir hat kesimi olarak değerlendirilir) bir kademeli kestiği, böylece bu, geçerli olan bir parametre aralıkları bulmak olabilir

    C[i] = C0[i] + (C1[i] - C0[i])*v1 + (C2[i] - C0[i])*v2 
    

    : Bu son noktalarında hızları ile parametrize karşılık gelen kontrol noktaları, harman istasyonu. (v1 ve v2, 1.0'ın üzerine çıkabilir).

    +0

    Teşekkürler! ve size geri dönmek için çok uzun sürdüğüm için üzgünüm. Soruyu doğru bir şekilde işaret ettim, ancak sonunda farklı bir yönteme gittim, bir de “yan nokta” kullandım, eğer istasyon yoldaysa, ilk önce geminin yanaşma noktasına kadar devam etmeden önce gemilere gidecektir. –