Die überprüfung, ob zwei kubische Bézier-Kurven kreuzen

Für ein persönliches Projekt, ich brauche, um herauszufinden, ob zwei kubische Bézier-Kurven sich schneiden. Ich brauche nicht zu wissen, wo: ich brauche nur zu wissen, wenn Sie tun. Allerdings würde ich brauchen, um es zu tun schnell.

Ich habe Aufräumvorgang den Platz, und ich fand mehrere Ressourcen. Meist gibt es diese Frage hier, die hatte eine viel versprechende Antwort.

So, nachdem ich dachte, was ist ein Sylvester matrix, was ist ein Determinante, was ist ein daraus resultierende und warum es sinnvoll ist, ich dachte, ich dachte, wie die Lösung funktioniert. Doch die Realität stellt sich voneinander zu unterscheiden, und es funktioniert nicht so gut.


Herumspielen

Ich habe mein Funktionsplotter zum zeichnen von zwei Bézier-splines (das nennen wir B0 - und B1), die sich überschneiden. Deren Koordinaten lauten wie folgt (P0, P1, P2, P3):

(1, 1) (2, 4) (3, 4) (4, 3)
(3, 5) (3, 6) (0, 1) (3, 1)

Das Ergebnis ist die folgende, B0 wird durch die "horizontale" Kurve und B1 der andere:

Die überprüfung, ob zwei kubische Bézier-Kurven kreuzen

Folgenden Richtungen von der vorgenannten Frage die top-Antwort gestimmt, ich habe subtrahiert B0 B1. Sie verließ mich mit zwei Gleichungen (die X-und die Y-Achse), die, laut meinem Rechner sind:

x = 9t^3 - 9t^2 - 3t + 2
y = 9t^3 - 9t^2 - 6t + 4

Die Sylvester-Matrix

Und ich gebaut haben die folgenden Sylvester matrix:

9  -9  -3   2   0   0
0   9  -9  -3   2   0
0   0   9  -9  -3   2
9  -9  -6   4   0   0
0   9  -9  -6   4   0
0   0   9  -9  -6   4

Danach, habe ich eine C++ - Funktion zur Berechnung von Determinanten von Matrizen mit Laplace-expansion:

template<int size>
float determinant(float* matrix)
{
    float total = 0;
    float sign = 1;
    float temporaryMatrix[(size - 1) * (size - 1)];
    for (int i = 0; i < size; i++)
    {
        if (matrix[i] != 0)
        {
            for (int j = 1; j < size; j++)
            {
                float* targetOffset = temporaryMatrix + (j - 1) * (size - 1);
                float* sourceOffset = matrix + j * size;
                int firstCopySize = i * sizeof *matrix;
                int secondCopySize = (size - i - 1) * sizeof *matrix;
                memcpy(targetOffset, sourceOffset, firstCopySize);
                memcpy(targetOffset + i, sourceOffset + i + 1, secondCopySize);
            }
            float subdeterminant = determinant<size - 1>(temporaryMatrix);
            total += matrix[i] * subdeterminant * sign;
        }
        sign *= -1;
    }
    return total;
}

template<>
float determinant<1>(float* matrix)
{
    return matrix[0];
}

Scheint es ziemlich gut zu funktionieren, die sich auf relativ kleine Matrizen (2x2, 3x3 und 4x4), also würde ich erwarten, dass es funktioniert auf 6x6-Matrizen zu. Ich wusste nicht, führen umfangreiche tests jedoch und gibt es eine Möglichkeit, dass es kaputt ist.


Das Problem

Wenn ich das richtig verstanden, die Antwort aus der anderen Frage, die Determinante muss 0 sein. da die Kurven überschneiden. Allerdings, Fütterung mein Programm die Sylvester-matrix, die ich, wie oben bereits erwähnt, ist es -2916.

Ist es ein Fehler an meinem Ende oder an Ihrem Ende? Was ist der richtige Weg, um herauszufinden, ob zwei kubische Bézier-Kurven schneiden?

  • Bitte nicht berechnen Determinanten, wenn Sie nicht haben, um. Wenn Sie prüfen wollen, für eine Singularität, die Berechnung des niedrigsten und höchsten singulären Wert. Und wenn man die Determinante aus irgendeinem Grund, verwenden Sie nicht die Laplace-Expansion! Es hat exponentielle Zeitkomplexität. Sie können es auf O(n^3)!
  • Stecken Sie die Sylvester-Matrix in die matrix Rechner unter bluebit.gr/matrix-Rechner gab -2916 für die Determinante. Sie müssen möglicherweise zu beheben Ihre bestimmende Funktion.
  • Lutz Ja, ich fand, dass etwa 5 Minuten nach meinem post, und ich meine Feste Determinante Funktion.
  • Ich werde gerne legen Sie es einmal jemand erklärt, einen anderen Weg zu finden, Bézier-Kurven, Kreuzungen.
  • Wie haben Sie daraus die Gleichungen "x = 9t^3 - 9Z^2 - 3t + 2; y = 9Z^3 - 9Z^2 - 6t + 4" von der Kontrollpunkte der Kurven?
  • Baker ich nicht, meine Rechner haben. Es überarbeitete die kubische Bézier-Gleichung wir wissen, in (-P0 + 3*P1 - 3*P2 + P4) * t^3 + 3*(P0 - 2*P1 + P2) * t^2 - 3*(P0 - P1) * t + P0; und die beiden Gleichungen, die ich gezeigt habe sind einfach die Funktionen X und Y der beiden Kurven subtrahiert. WolframAlpha bestätigt, Sie sind identisch.
  • Dies ist eine perfekte Algorithmus, aber es findet, wenn zwei parametrische Kurven schneiden sich auf die exakt gleichen parameter Wert (Es ist das, was @PaulBaker Antwort Punkte zu). Das eigentliche problem ("Do Kurven schneiden überhaupt ?") ist ein bi-variadic polynom, für das Sie finden möchten, die Wurzeln ein problem, für das ich weiß nicht, ob es eine analytische Lösung. Ich denke, dass sollte die Frage bearbeitet werden, um auch diese Bemerkung.

InformationsquelleAutor zneak | 2010-10-28
Schreibe einen Kommentar