Я пытаюсь построить плоскость из трех точек в 3D.
Я хочу использовать проективную геометрию для достижения этой цели.
Насколько я знаю, можно «просто» решить следующее, чтобы найти самолет:
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
Я знаю, что мне нужно иметь ограничения. Поэтому я хочу установить x(3) = 1
,
Может кто-нибудь указать мне правильный метод для использования?
Пока у меня есть следующий код:
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());
Матрица 3х4, умноженная на вектор из 4 строк, даст вам вектор из 3 строк. Таким образом, вы должны решить для Vector3f::Zero()
, Кроме того, для матриц фиксированного размера вам нужно вычислить полные U и V. Последняя строка выглядит так:
Vector4f Plane = A.jacobiSvd(ComputeFullU | ComputeFullV).solve(Vector3f::Zero());
Eidt
Поскольку эта система уравнений не полностью определена, она может дать вам тривиальное решение (0,0,0,0). Вы можете решить это, ограничив длину результирующего вектора, расширив матрицу до 4×4, решив для (0,0,0,1) и масштабируя результат на 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);
Это даст вам желаемое решение (-1, -1, -1, 1).
Других решений пока нет …