2017-03-15 3 views
1

J'essaie de construire un plan sur trois points en 3D. Je veux utiliser la géométrie projective pour y parvenir.Géométrie projective - Trouver un plan en 3D en utilisant l'image propre

Pour autant que je sache, on peut « simplement » résoudre ce qui suit pour trouver un avion:

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 

Je sais que je dois avoir une contrainte. Par conséquent, je veux définir x(3) = 1. Quelqu'un peut-il me diriger vers la bonne méthode à utiliser?

Jusqu'à présent, j'ai le code suivant:

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

Je voudrais aller pour une méthode non-matrice, voir https://en.wikipedia.org/wiki/Plane_(geometry)#Method_3. – Shaana

+0

L'idée est d'utiliser la géométrie projective pour avoir un moyen facile de tester si d'autres points appartiennent à ce plan en calculant simplement 'Plane.transpose() * otherPoint' – NewTech

Répondre

1

Une matrice 3x4 multipliée par un vecteur 4 de la ligne vous donnera un vecteur 3 rangs. Ainsi, vous devez résoudre pour un Vector3f::Zero(). En outre, pour les matrices de taille fixe, vous devez calculer la pleine U et V. La dernière ligne ressemble à ceci:

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

Eidt Puisque ce système d'équations est pas complètement définie, il peut vous donner la solution triviale de (0,0,0,0). Vous pouvez résoudre ce en limitant la longueur du vecteur résultant en élargissant la matrice à un 4x4, la résolution de (0,0,0,1) et mise à l'échelle le résultat par 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); 

Cette volonté vous donne la solution désirée de (-1, -1, -1, 1).

+0

Merci. Maintenant le code compile mais s'arrête à la ligne suivante: 'eigen_assert (EIGEN_IMPLIES (m_computeThinU || m_computeThinV, MatrixType :: ColsAtCompileTime == Dynamique) && " JacobiSVD: U et V minces ne sont disponibles que si votre matrice a un nombre dynamique de colonnes. ")' à l'intérieur du "JacobiSVD.h" – NewTech

+0

@NewTech J'ai mis à jour ma réponse. Le problème est que "ComputeThinU" et "ComputeThinV" ne sont pas disponibles pour les matrices de taille fixe comme 'Matrix '. – maddin45

+0

Ah. Ok maintenant le code fonctionne parfaitement. Mais seulement en donnant la solution trivale de (0,0,0,0). Je m'attendrais à obtenir (-1, -1, -1, 1). Existe-t-il une méthode pour définir une contrainte? – NewTech