Bei einem Satz von 2D-Punkten (in kartesischer Form) muss ich die Ellipse mit dem kleinsten Bereich finden, so dass jeder Punkt auf oder in der Ellipse liegt .Wie man eine Begrenzungsellipse um einen Satz von 2D-Punkten anordnet
Ich habe found the solution in Form von Pseudocode auf dieser Website, aber mein Versuch, die Lösung in C++ zu implementieren, war nicht erfolgreich.
Das folgende Bild zeigt in graphischer Form, was die Lösung für mein Problem wie folgt aussieht:
In meinem Versuch, ich die Eigen Bibliothek für die verschiedenen Operationen auf Matrizen verwendet.
//The tolerance for error in fitting the ellipse
double tolerance = 0.2;
int n = 10; // number of points
int d = 2; // dimension
MatrixXd p = MatrixXd::Random(d,n); //Fill matrix with random points
MatrixXd q = p;
q.conservativeResize(p.rows() + 1, p.cols());
for(size_t i = 0; i < q.cols(); i++)
{
q(q.rows() - 1, i) = 1;
}
int count = 1;
double err = 1;
const double init_u = 1.0/(double) n;
MatrixXd u = MatrixXd::Constant(n, 1, init_u);
while(err > tolerance)
{
MatrixXd Q_tr = q.transpose();
cout << "1 " << endl;
MatrixXd X = q * u.asDiagonal() * Q_tr;
cout << "1a " << endl;
MatrixXd M = (Q_tr * X.inverse() * q).asDiagonal();
cout << "1b " << endl;
int j_x, j_y;
double maximum = M.maxCoeff(&j_x, &j_y);
double step_size = (maximum - d - 1)/((d + 1) * (maximum + 1));
MatrixXd new_u = (1 - step_size) * u;
new_u(j_x, 0) += step_size;
cout << "2 " << endl;
//Find err
MatrixXd u_diff = new_u - u;
for(size_t i = 0; i < u_diff.rows(); i++)
{
for(size_t j = 0; j < u_diff.cols(); j++)
u_diff(i, j) *= u_diff(i, j); // Square each element of the matrix
}
err = sqrt(u_diff.sum());
count++;
u = new_u;
}
cout << "3 " << endl;
MatrixXd U = u.asDiagonal();
MatrixXd A = (1.0/(double) d) * (p * U * p.transpose() - (p * u) * (p * u).transpose()).inverse();
MatrixXd c = p * u;
Der Fehler tritt in der folgenden Zeile:
MatrixXd M = (Q_tr * X.inverse() * q).asDiagonal();
und lautet wie folgt:
run: /usr/include/eigen3/Eigen/src/Core/DenseBase.h:261: void Eigen::DenseBase<Derived>::resize(Eigen::Index, Eigen::Index) [with Derived = Eigen::Diagonal<Eigen::Matrix<double, -1, -1>, 0>; Eigen::Index = long int]: Assertion `rows == this->rows() && cols == this->cols() && "DenseBase::resize() does not actually allow to resize."' failed.
Aborted (core dumped)
Kann jemand bitte darauf hinweisen, warum dieser Fehler auftritt, oder noch besser, geben mir einen Tipp, wie man mit C++ eine Ellipse an eine Menge von Punkten anpasst?
Dies vollständig gelöst das Problem und der Algorithmus findet die Ellipse. Sieht so aus, als ob das Problem von meinem fehlenden Verständnis der linearen Algebra und nicht von C++ herrührt. Vielen Dank! – Dziugas