Frage

Ich habe eine Reihe von Datenpunkten im 3D-Raum, die scheinbar alle fallen auf eine bestimmte Ebene. Ich benutze PCA die Ebene Parameter zu berechnen. Die dritte Komponente des PCA gibt mir den Normalvektor der Ebene (schwächste Komponente).

Was ich als nächstes tun möchte, ist, alle Punkte zu transformieren auf die Ebene und schauen Sie es in 2D.

war meine Idee folgendes zu tun:

  • Finden Sie einen Mittelpunkt (Durchschnitt Punkt) auf der Ebene
  • es von allen Datenpunkten subtrahieren sie zu ordnen um den Ursprung
  • Drehen Sie den normalen so dass es (0,0, -1)
  • Wenden Sie diese Drehung auf alle Datenpunkte
  • Verwendung Orthogonalprojektion (grundsätzlich überspringen z-Achse)

Jetzt bin ich auf der Suche nach dem richtigen Rotationsbetrieb stecken. Ich habe versucht, mit acos oder atan arbeiten und zwei Drehmatrizen einrichten. Scheint beide Methoden (mit acos, atan verwenden) geben Sie mir das falsche Ergebnis. Vielleicht können Sie mir helfen hier!

Matlab-Code folgt:

b = atan(n(1) / n(2));
rotb = [cos(b) -sin(b) 0; sin(b) cos(b) 0; 0 0 1];
n2 = n * rotb;
a = atan(n(1) / n(3));
rota = [cos(a) 0 sin(a); 0 1 0; -sin(a) 0 cos(a)];
n3 = n2 * rotaows:

Ich erwarte, dass n2 y-Komponente von Null haben. Sie jedoch, dass nicht bereits für den Vektor (-0,6367, 0,7697, 0,0467).

War es hilfreich?

Lösung

Wenn Sie eine Ebene haben, haben Sie einen normalen Vektor und einen Ursprung. Ich würde keine „Rotationen“ überhaupt nicht. Sie sind nur ein paar Vektor-Operationen von Ihrer Antwort entfernt.

  • Lassen Sie sich Ihr Flugzeug normaler Vektor ruft die neue z-Achse.
  • Sie können die neue y-Achse erzeugen, indem sie die alte x-Achse mit der neuen z-Achse kreuzt (Ihr Flugzeug ist normal).
  • Generieren der neuen X-Achse durch die neue mit dem neuen Z-Y kreuzen.
  • Machen Sie alle Ihre neuen Achsenvektoren in Einheitsvektoren (Länge 1).
  • Für jeden Punkt, den Sie haben, erstellen Sie einen Vektor, der bis zu dem Punkt (Vektor Subtraktion von Punkt - plane_origin) von Ihrem Ursprung ist. Nur Punkt mit dem neuen x und y neuen Einheitsvektoren und Sie bekommen ein Paar (x, y) Sie zeichnen können!

Wenn Sie Funktionen Kreuz- und Skalarprodukt haben schon, das ist nur ein paar Zeilen Code. Ich weiß, dass es funktioniert, weil die meisten der 3D-Videospiele Ich schrieb diese Weise gearbeitet.

Tricks:

  • Achten Sie auf welche Richtungen Ihre Vektoren zeigen. Wenn sie die falsche Art und Weise zeigen, die sich ergebende Vektor negieren oder die Reihenfolge des Kreuzprodukts ändern.
  • Sie haben Probleme, wenn Ihr Flugzeug ist normal ist genau das gleiche wie das Original x-Achse.

Andere Tipps

Wie wäre:

Zerlege den Normalvektor in einen Vektor in der XY-Ebene und ein Z-Vektor. Dann wenden eine Drehung um die Z-Achse des XY-Vektor mit einer von der Achse aufreihen. Dann finden Sie das Punktprodukt des den normalen mit der Z-Achse und drehen, entlang welcher jemals von X, Y Sie reihen sich mit.

Die Idee ist, den Normalvektor mit Z bis Zeile, und tut, dass Ihr Flugzeug ist nun die XY-Ebene.

Obwohl es auch andere interessante Antworten waren, ist dies die Lösung, die wir während Antworten warten herausgefunden:

function roti = magic_cosini(n)
    b = acos(n(2) / sqrt(n(1)*n(1) + n(2)*n(2)));
    bwinkel = b * 360 / 2 / pi;
    if (n(1) >= 0)
        rotb = [cos(-b) -sin(-b) 0; sin(-b) cos(-b) 0; 0 0 1];
    else
        rotb = [cos(-b) sin(-b) 0; -sin(-b) cos(-b) 0; 0 0 1];
    end
    n2 = n * rotb;
    a = acos(n2(3) / sqrt(n2(2)*n2(2) + n2(3)*n2(3)));
    awinkel = a * 360 / 2 / pi;
    rota = [1 0 0; 0 cos(-a) -sin(-a); 0 sin(-a) cos(-a)];
    roti = rotb * rota;

(Es ist eine hoffentlich richtige Doppelrotationsmatrix Rückkehr)

Der Fehler wir vorher hatten und fest hier war esp. beschäftigen sich mit dem Vorzeichen der X-Komponente, die nicht in den Kosinus Berechnungen bedeckt war. Das hat uns in der falschen Richtung drehen einmal (rotierend mit 180 ° - Winkel).

Ich hoffe, dass ich auch Zeit finden Nosredna-Lösung zu versuchen! Es ist immer gut Trigonometrie zu vermeiden.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top