6 #include <unsupported/Eigen/Polynomials>
22 double start,
double end,
24 double diffA = getAngleDifference(start, end, CCW);
25 double diffB = getAngleDifference(start, angle, CCW);
26 return diffB <= diffA;
34 return std::remainder(a, 2. *
M_PI);
46 auto angle = correctAngle(a2 - a1);
58 difference = end - start;
61 difference = start - end;
64 if (difference < 0.) {
65 difference = 2.0 *
M_PI - std::abs(difference);
78 std::vector<double> ans(0, 0.);
84 Eigen::PolynomialSolver<double, Eigen::Dynamic> solver;
85 Eigen::VectorXd coeff(3);
91 solver.compute(coeff);
93 solver.realRoots(ans);
103 std::vector<double> ans(0, 0.);
104 if (ce.size() != 3) {
108 Eigen::PolynomialSolver<double, Eigen::Dynamic> solver;
109 Eigen::VectorXd coeff(4);
116 solver.compute(coeff);
118 solver.realRoots(ans);
130 std::vector<double> ans(0, 0.);
131 Eigen::PolynomialSolver<double, Eigen::Dynamic> solver;
132 Eigen::VectorXd coeff(5);
134 if (ce.size() != 4) {
144 solver.compute(coeff);
146 solver.realRoots(ans);
153 std::vector<double> ans(0, 0.);
154 Eigen::PolynomialSolver<double, Eigen::Dynamic> solver;
155 Eigen::VectorXd coeff(7);
157 if (ce.size() != 7) {
169 solver.compute(coeff);
171 solver.realRoots(ans);
186 std::vector<double> roots(0, 0.);
188 if (ce.size() != 5) {
192 std::vector<double> ce2(4, 0.);
194 if (std::abs(ce[4]) < 1.0e-14) {
195 if (std::abs(ce[3]) < 1.0e-14) {
196 if (std::abs(ce[2]) < 1.0e-14) {
197 if (std::abs(ce[1]) > 1.0e-14) {
198 roots.push_back(-ce[0] / ce[1]);
205 ce2[0] = ce[1] / ce[2];
206 ce2[1] = ce[0] / ce[2];
211 ce2[0] = ce[2] / ce[3];
212 ce2[1] = ce[1] / ce[3];
213 ce2[2] = ce[0] / ce[3];
217 ce2[0] = ce[3] / ce[4];
218 ce2[1] = ce[2] / ce[4];
219 ce2[2] = ce[1] / ce[4];
220 ce2[3] = ce[0] / ce[4];
246 std::vector<lc::geo::Coordinate> ret(0);
252 std::vector< double> c1(0, 0.);
253 std::vector< std::vector<double> > m1(0, c1);
270 return simultaneousQuadraticSolverFull(m1);
284 std::vector<lc::geo::Coordinate> ret;
290 if (m[0].size() == 3 || m[1].size() == 3) {
291 return simultaneousQuadraticSolverMixed(m);
294 if (m[0].size() != 6 || m[1].size() != 6) {
343 std::vector<double> qy(5, 0.);
345 qy[4] = -c2 * g2 + b * c * g * h - a * c * h2 - b2 * g * i + 2.*a * c * g * i + a * b * h * i - a2 * i2;
347 qy[3] = -2.*c * e * g2 + c * d * g * h + b * e * g * h - a * e * h2 - 2.*b * d * g * i + 2.*a * e * g * i + a * d * h * i +
348 b * c * g * j - 2.*a * c * h * j + a * b * i * j - b2 * g * k + 2.*a * c * g * k + a * b * h * k - 2.*a2 * i * k;
350 qy[2] = (-e2 * g2 + d * e * g * h - d2 * g * i + c * d * g * j + b * e * g * j - 2.*a * e * h * j + a * d * i * j - a * c * j2 -
351 2.*b * d * g * k + 2.*a * e * g * k + a * d * h * k + a * b * j * k - a2 * k2 - b2 * g * l + 2.*a * c * g * l + a * b * h * l - 2.*a2 * i * l)
352 - (2.*c * f * g2 - b * f * g * h + a * f * h2 - 2.*a * f * g * i);
354 qy[1] = (d * e * g * j - a * e * j2 - d2 * g * k + a * d * j * k - 2.*b * d * g * l + 2.*a * e * g * l + a * d * h * l + a * b * j * l - 2.*a2 * k * l)
355 - (2.*e * f * g2 - d * f * g * h - b * f * g * j + 2.*a * f * h * j - 2.*a * f * g * k);
357 qy[0] = -d2 * g * l + a * d * j * l - a2 * l2
358 - (f2 * g2 - d * f * g * j + a * f * j2 - 2.*a * f * g * l);
360 auto&& roots = quarticSolverFull(qy);
362 if (roots.size() == 0) {
366 std::vector<double> ce(0, 0.);
368 for (
size_t i0 = 0; i0 < roots.size(); i0++) {
374 ce[1] = b * roots[i0] + d;
375 ce[2] = c * roots[i0] * roots[i0] + e * roots[i0] + f;
377 if (std::abs(ce[0]) < 1e-75 && std::abs(ce[1]) < 1e-75) {
379 ce[1] = h * roots[i0] + j;
380 ce[2] = i * roots[i0] * roots[i0] + k * roots[i0] + f;
383 if (std::abs(ce[0]) < 1e-75 && std::abs(ce[1]) < 1e-75) {
387 if (std::abs(a) > 1e-75) {
388 std::vector<double> ce2(2, 0.);
389 ce2[0] = ce[1] / ce[0];
390 ce2[1] = ce[2] / ce[0];
391 auto&& xRoots = quadraticSolver(ce2);
393 for (
size_t j0 = 0; j0 < xRoots.size(); j0++) {
396 if (simultaneousQuadraticVerify(m, vp)) {
406 if (simultaneousQuadraticVerify(m, vp)) {
415 std::vector<lc::geo::Coordinate> ret;
419 if (p1->size() == 3) {
423 if (p1->size() == 3) {
427 M << m[0][0], m[0][1],
429 V << -m[0][2], -m[1][2];
430 Eigen::Vector2d sn = M.colPivHouseholderQr().solve(V);
435 const double& a = p0->at(0);
436 const double& b = p0->at(1);
437 const double& c = p0->at(2);
438 const double& d = p1->at(0);
439 const double& e = p1->at(1);
440 const double& f = p1->at(2);
441 const double& g = p1->at(3);
442 const double& h = p1->at(4);
443 const double& i = p1->at(5);
447 std::vector<double> ce(3, 0.);
448 const double&& a2 = a * a;
449 const double&& b2 = b * b;
450 const double&& c2 = c * c;
451 ce[0] = -f * a2 + a * b * e - b2 * d;
452 ce[1] = a * b * g - a2 * h - (2 * b * c * d - a * c * e);
453 ce[2] = a * c * g - c2 * d - a2 * i;
454 std::vector<double> roots(0, 0.);
456 if (std::abs(ce[0]) < 1e-75) {
457 if (std::abs(ce[1]) > 1e-75) {
458 roots.push_back(- ce[2] / ce[1]);
461 std::vector<double> ce2(2, 0.);
462 ce2[0] = ce[1] / ce[0];
463 ce2[1] = ce[2] / ce[0];
464 roots = quadraticSolver(ce2);
467 if (roots.size() == 0) {
471 for (
size_t i = 0; i < roots.size(); i++) {
472 ret.push_back(
geo::Coordinate(-(b * roots.at(i) + c) / a, roots.at(i)));
485 const double& x = v.
x();
486 const double& y = v.
y();
487 const double x2 = x * x;
488 const double y2 = y * y;
506 double terms0[12] = { a * x2, b* x * y, c * y2, d * x, e * y, f, g * x2, h* x * y, i * y2, j * x, k * y, l};
507 double amax0 = std::abs(terms0[0]), amax1 = std::abs(terms0[6]);
508 double sum0 = 0., sum1 = 0.;
510 for (
int i = 0; i < 6; i++) {
511 if (amax0 < std::abs(terms0[i])) {
512 amax0 = std::abs(terms0[i]);
518 for (
int i = 6; i < 12; i++) {
519 if (amax1 < std::abs(terms0[i])) {
520 amax1 = std::abs(terms0[i]);
526 const double tols = 2.*sqrt(6.) * sqrt(DBL_EPSILON);
528 return (amax0 <= tols || std::abs(sum0) / amax0 < tols) && (amax1 <= tols || std::abs(sum1) / amax1 < tols);
static double getAngleDifferenceShort(double a1, double a2, bool CCW)
getAngleDifference, Angle difference between 2 angles
static std::vector< double > quadraticSolver(const std::vector< double > &ce)
quadraticSolver, Quadratic equations solver
static std::vector< double > cubicSolver(const std::vector< double > &ce)
static std::vector< lc::geo::Coordinate > simultaneousQuadraticSolverMixed(const std::vector< std::vector< double > > &m)
static std::vector< lc::geo::Coordinate > simultaneousQuadraticSolver(const std::vector< double > &m)
double x() const
Returns x of Coordinate.
static std::vector< double > sexticSolver(const std::vector< double > &ce)
double y() const
Returns y of Coordinate.
static bool simultaneousQuadraticVerify(const std::vector< std::vector< double > > &m, const geo::Coordinate &v)
static std::vector< double > quarticSolverFull(const std::vector< double > &ce)
static double getAngleDifference(double a1, double a2, bool CCW)
getAngleDifference, Angle difference between 2 angles
static std::vector< lc::geo::Coordinate > simultaneousQuadraticSolverFull(const std::vector< std::vector< double > > &m)
simultaneousQuadraticSolverFull
static double correctAngle(double a)
correctAngle, Corrects angle to be in -PI to PI
static bool isAngleBetween(double a, double start, double end, bool CCW)
isAngleBetween, checks if angle is between
static std::vector< double > quarticSolver(const std::vector< double > &ce)