2017-03-15 5 views
1

Ich versuche, eine Ebene aus drei Punkten in 3D zu konstruieren. Ich möchte projektive Geometrie verwenden, um dies zu erreichen.Projektive Geometrie - Finden Ebene in 3D mit Eigen

Soweit ich weiß, kann man „einfach“ lösen die im Anschluss an eine Ebene zu finden:

A * x = 0 ,where 
A is a 3x4 Matrix - each row being one of the points (x,y,z,1) 
x is the plane I want to find 

Ich weiß, dass ich eine constrain haben müssen. Daher möchte ich x(3) = 1 setzen. Kann mir bitte jemand auf die richtige Methode hinweisen?

Bisher habe ich den folgenden Code:

Eigen::Vector4f p1(0,0,1,1); 
Eigen::Vector4f p2(1,0,0,1); 
Eigen::Vector4f p3(0,1,0,1); 

Eigen::Matrix<float,3,4> A; 
A << p1.transpose(), p2.transpose(), p3.transpose(); 

// Throws compile error 
// Eigen::Vector4f Plane = A.jacobiSvd(ComputeThinU | ComputeThinV).solve(Vector4f::Zero()); 

//throws runtime error (row-number do not match) 
// Eigen::Vector4f Plane = A.fullPivHouseholderQr().solce(Eigen::Vector4f::Zero()); 
+0

Ich würde für eine Nicht-Matrix-Methode gehen, siehe https://en.wikipedia.org/wiki/Plane_(geometry)#Method_3. – Shaana

+0

Die Idee ist, projektive Geometrie zu verwenden, um eine einfache Möglichkeit zu haben, zu testen, ob andere Punkte zu dieser Ebene gehören, indem einfach 'Plane.transpose() * otherPoint' – NewTech

Antwort

1

Eine 3x4 Matrix mit einem Vektor 4 Zeile multipliziert werden Ihnen einen 3 Zeilenvektor geben. Also muss man nach einem Vector3f::Zero() lösen. Auch für feste Größe Matrizen benötigen Sie die volle U und V. Die letzte Zeile wie folgt aussehen zu berechnen:

Vector4f Plane = A.jacobiSvd(ComputeFullU | ComputeFullV).solve(Vector3f::Zero()); 

Eidt Da dieses Gleichungssystem nicht vollständig definiert, es könnten Ihnen die triviale Lösung von (0,0,0,0). Sie können das lösen, indem die Länge des resultierenden Vektors beschränke durch die Matrix zu einem 4x4-Erweiterung, die Lösung für (0,0,0,1) und Skalierung des Ergebnisses durch x (3):

Eigen::Vector4f p1(0,0,1,1); 
Eigen::Vector4f p2(1,0,0,1); 
Eigen::Vector4f p3(0,1,0,1); 
Eigen::Vector4f p4(1,1,1,1); 

Eigen::Matrix<float,4,4> A; 
A << p1.transpose(), p2.transpose(), p3.transpose(), p4.transpose(); 

// Throws compile error 
Eigen::Vector4f Plane = A.jacobiSvd(Eigen::ComputeFullU | Eigen::ComputeFullV).solve(Vector4f::Unit(3)); 
Plane /= Plane(3); 

Dieser Wille geben Sie die gewünschte Lösung von (-1, -1, -1, 1).

+0

Thanks berechnet wird. Jetzt kompiliert der Code, aber stoppt an der folgenden Zeile: 'Eigen_IMPLIES (M_ComputeThinU || M_ComputeThinV, MatrixType :: ColsAtCompileTime == Dynamisch) && "JacobiSVD: dünne U und V sind nur verfügbar, wenn Ihre Matrix eine dynamische Zahl von hat Spalten. ")' innerhalb der "JacobiSVD.h" – NewTech

+0

@NewTech Ich aktualisierte meine Antwort. Das Problem ist, dass "ComputeThinU" und "ComputeThinV" nicht für Matrizen mit fester Größe wie "Matrix " verfügbar sind. – maddin45

+0

Ah. Ok jetzt läuft der Code einwandfrei. Aber geben nur die Trivallösung von (0,0,0,0). Ich würde erwarten, (-1, -1, -1, 1) zu bekommen. Gibt es eine Methode, um eine Einschränkung festzulegen? – NewTech