26 #include <Eigen/Dense> 40 double Px,
double Py,
double x1,
double y1,
double x2,
double y2,
41 double& out_x,
double& out_y)
43 if (x1 == x2 && y1 == y2)
52 double Ratio = ((Px - x1) * Dx + (Py - y1) * Dy) / (Dx * Dx + Dy * Dy);
67 out_x = x1 + (Ratio * Dx);
68 out_y = y1 + (Ratio * Dy);
78 double Px,
double Py,
double x1,
double y1,
double x2,
double y2,
79 double& out_x,
double& out_y)
81 if (x1 == x2 && y1 == y2)
90 double Ratio = ((Px - x1) * Dx + (Py - y1) * Dy) / (Dx * Dx + Dy * Dy);
92 out_x = x1 + (Ratio * Dx);
93 out_y = y1 + (Ratio * Dy);
101 double Px,
double Py,
double x1,
double y1,
double x2,
double y2)
103 if (x1 == x2 && y1 == y2)
111 double Ratio = ((Px - x1) * Dx + (Py - y1) * Dy) / (Dx * Dx + Dy * Dy);
113 return square(x1 + (Ratio * Dx) - Px) +
square(y1 + (Ratio * Dy) - Py);
121 const double x1,
const double y1,
const double x2,
const double y2,
122 const double x3,
const double y3,
const double x4,
const double y4,
123 double& ix,
double& iy)
125 double UpperX, UpperY, LowerX, LowerY, Ax, Bx, Cx, Ay, By, Cy, d, f, e,
144 if (UpperX < x4 || x3 < LowerX)
return false;
146 else if (UpperX < x3 || x4 < LowerX)
165 if (UpperY < y4 || y3 < LowerY)
return false;
167 else if (UpperY < y3 || y4 < LowerY)
172 d = (By * Cx) - (Bx * Cy);
173 f = (Ay * Bx) - (Ax * By);
177 if (d < 0 || d > f)
return false;
179 else if (d > 0 || d < f)
182 e = (Ax * Cy) - (Ay * Cx);
186 if (e < 0 || e > f)
return false;
188 else if (e > 0 || e < f)
191 Ratio = (Ax * -By) - (Ay * -Bx);
195 Ratio = ((Cy * -Bx) - (Cx * -By)) / Ratio;
196 ix = x1 + (Ratio * Ax);
197 iy = y1 + (Ratio * Ay);
201 if ((Ax * -Cy) == (-Cx * Ay))
219 const double x1,
const double y1,
const double x2,
const double y2,
220 const double x3,
const double y3,
const double x4,
const double y4,
221 float& ix,
float& iy)
234 double px,
double py,
unsigned int polyEdges,
const double* poly_xs,
235 const double* poly_ys)
240 if (polyEdges < 3)
return res;
244 for (i = 0; i < polyEdges; i++)
246 if ((poly_ys[i] <= py && py < poly_ys[j]) ||
247 (poly_ys[j] <= py && py < poly_ys[i]))
250 if (px - poly_xs[i] <
251 ((poly_xs[j] - poly_xs[i]) * (py - poly_ys[i]) /
252 (poly_ys[j] - poly_ys[i])))
265 double px,
double py,
unsigned int polyEdges,
const double* poly_xs,
266 const double* poly_ys)
269 double minDist = 1e20f;
277 for (i = 0; i < polyEdges; i++)
281 double closestX, closestY;
283 px, py, poly_xs[j], poly_ys[j], poly_xs[i], poly_ys[i], closestX,
286 minDist = min(d, minDist);
299 double p1_x,
double p1_y,
double p1_z,
double p2_x,
double p2_y,
300 double p2_z,
double p3_x,
double p3_y,
double p3_z,
double p4_x,
301 double p4_y,
double p4_z,
double& x,
double& y,
double& z,
double& dist)
303 const double EPS = 1e-30f;
305 double p13_x, p13_y, p13_z;
306 double p43_x, p43_y, p43_z;
307 double p21_x, p21_y, p21_z;
309 double d1343, d4321, d1321, d4343, d2121;
320 if (fabs(p43_x) < EPS && fabs(p43_y) < EPS && fabs(p43_z) < EPS)
326 if (fabs(p21_x) < EPS && fabs(p21_y) < EPS && fabs(p21_z) < EPS)
329 d1343 = p13_x * p43_x + p13_y * p43_y + p13_z * p43_z;
330 d4321 = p43_x * p21_x + p43_y * p21_y + p43_z * p21_z;
331 d1321 = p13_x * p21_x + p13_y * p21_y + p13_z * p21_z;
332 d4343 = p43_x * p43_x + p43_y * p43_y + p43_z * p43_z;
333 d2121 = p21_x * p21_x + p21_y * p21_y + p21_z * p21_z;
335 denom = d2121 * d4343 - d4321 * d4321;
336 if (fabs(denom) < EPS)
return false;
338 numer = d1343 * d4321 - d1321 * d4343;
340 double mua = numer / denom;
341 double mub = (d1343 + d4321 * mua) / d4343;
342 double pa_x, pa_y, pa_z;
343 double pb_x, pb_y, pb_z;
345 pa_x = p1_x + mua * p21_x;
346 pa_y = p1_y + mua * p21_y;
347 pa_z = p1_z + mua * p21_z;
349 pb_x = p3_x + mub * p43_x;
350 pb_y = p3_y + mub * p43_y;
351 pb_z = p3_z + mub * p43_z;
357 x = 0.5 * (pa_x + pb_x);
358 y = 0.5 * (pa_y + pb_y);
359 z = 0.5 * (pa_z + pb_z);
368 double R1_x_min,
double R1_x_max,
double R1_y_min,
double R1_y_max,
369 double R2_x_min,
double R2_x_max,
double R2_y_min,
double R2_y_max,
370 double R2_pose_x,
double R2_pose_y,
double R2_pose_phi)
375 double ccos = cos(R2_pose_phi);
376 double ssin = sin(R2_pose_phi);
378 xs[0] = R2_pose_x + ccos * R2_x_min - ssin * R2_y_min;
379 ys[0] = R2_pose_y + ssin * R2_x_min + ccos * R2_y_min;
381 xs[1] = R2_pose_x + ccos * R2_x_max - ssin * R2_y_min;
382 ys[1] = R2_pose_y + ssin * R2_x_max + ccos * R2_y_min;
384 xs[2] = R2_pose_x + ccos * R2_x_max - ssin * R2_y_max;
385 ys[2] = R2_pose_y + ssin * R2_x_max + ccos * R2_y_max;
387 xs[3] = R2_pose_x + ccos * R2_x_min - ssin * R2_y_max;
388 ys[3] = R2_pose_y + ssin * R2_x_min + ccos * R2_y_max;
392 if (R1_x_min <= xs[0] && xs[0] <= R1_x_max && R1_y_min <= ys[0] &&
395 if (R1_x_min <= xs[1] && xs[1] <= R1_x_max && R1_y_min <= ys[1] &&
398 if (R1_x_min <= xs[2] && xs[2] <= R1_x_max && R1_y_min <= ys[2] &&
401 if (R1_x_min <= xs[3] && xs[3] <= R1_x_max && R1_y_min <= ys[3] &&
420 for (
int idx = 0; idx < 4; idx++)
423 R1_x_min, R1_y_min, R1_x_max, R1_y_min, xs[idx], ys[idx],
424 xs[(idx + 1) % 4], ys[(idx + 1) % 4], ix, iy))
427 R1_x_max, R1_y_min, R1_x_max, R1_y_max, xs[idx], ys[idx],
428 xs[(idx + 1) % 4], ys[(idx + 1) % 4], ix, iy))
431 R1_x_max, R1_y_max, R1_x_min, R1_y_max, xs[idx], ys[idx],
432 xs[(idx + 1) % 4], ys[(idx + 1) % 4], ix, iy))
435 R1_x_min, R1_y_max, R1_x_min, R1_y_min, xs[idx], ys[idx],
436 xs[(idx + 1) % 4], ys[(idx + 1) % 4], ix, iy))
446 template <
class T2D,
class U2D,
class T3D,
class U3D>
461 proj1.generate2DObject(proj1_2D);
462 proj2.generate2DObject(proj2_2D);
465 if (
intersect(proj1_2D, proj2_2D, obj2D))
485 TPoint3D pMin = ((s11[0][i1] < s21[0][i1]) ? s21 : s11)[0];
486 TPoint3D pMax = ((s11[1][i1] < s21[1][i1]) ? s11 : s21)[1];
492 else if (pMax[i1] < pMin[i1])
508 TPoint2D pMin = ((s11[0][i1] < s21[0][i1]) ? s21 : s11)[0];
509 TPoint2D pMax = ((s11[1][i1] < s21[1][i1]) ? s11 : s21)[1];
515 else if (pMax[i1] < pMin[i1])
528 newPoint.
x = dummy.
x;
529 newPoint.
y = dummy.
y;
534 size_t N = poly.size();
536 for (
size_t i = 0; i < N; i++)
548 for (
size_t i = 0; i < 3; i++)
554 if (d < 0 || d > bestKnown)
return false;
582 TObject3D obj3D1, obj3D2, obj3Dp1, obj3Dp2;
686 for (
size_t i = 0; i < 3; i++)
707 size_t c1 = (i1 + 1) % 3, c2 = (i1 + 2) % 3;
757 const static size_t c1[] = {1, 2, 0};
758 const static size_t c2[] = {2, 0, 1};
760 for (
size_t i = 0; i < 3; i++)
770 for (
size_t k = 0; k < 3; k++) p[k] = r2.
pBase[k] + u * r2.
director[k];
848 double c = 0, n1 = 0, n2 = 0;
849 for (
size_t i = 0; i < 3; i++)
855 double s = sqrt(n1 * n2);
857 if (std::abs(s) < std::abs(c))
858 return (c / s < 0) ?
M_PI : 0;
865 double c = 0, n1 = 0, n2 = 0;
866 for (
size_t i = 0; i < 3; i++)
872 double s = sqrt(n1 * n2);
873 if (s <
geometryEpsilon)
throw std::logic_error(
"Invalid plane or line");
874 if (std::abs(s) < std::abs(c))
882 double c = 0, n1 = 0, n2 = 0;
883 for (
size_t i = 0; i < 3; i++)
889 double s = sqrt(n1 * n2);
891 if (std::abs(s) < std::abs(c))
892 return (c / s < 0) ?
M_PI : 0;
899 const double ang1 = std::atan2(-r1.
coefs[0], r1.
coefs[1]);
900 const double ang2 = std::atan2(-r2.
coefs[0], r2.
coefs[1]);
909 for (
size_t i = 0; i < 3; i++)
911 r.
pBase[i] = m(i, 3);
937 for (
size_t i = 0; i < 3; i++)
939 r.
pBase[i] = m(i, 3);
941 for (
size_t j = 0; j < 3; j++) r.
director[i] += m(i, j) * vector[j];
962 double c = cos(p.
phi);
963 double s = sin(p.
phi);
964 r.
coefs[0] = vector[0] * c + vector[1] * s;
965 r.
coefs[1] = -vector[0] * s + vector[1] * c;
971 size_t N = points.size();
972 if (N < 3)
return false;
974 const TPoint3D& orig = points[N - 1];
975 for (
size_t i = 0; i < N - 1; i++)
978 mat(i, 0) = p.
x - orig.
x;
979 mat(i, 1) = p.
y - orig.
y;
980 mat(i, 2) = p.
z - orig.
z;
992 size_t N = points.size();
993 if (N < 2)
return false;
995 const TPoint2D& orig = points[N - 1];
996 for (
size_t i = 0; i < N - 1; i++)
999 mat(i, 0) = p.
x - orig.
x;
1000 mat(i, 1) = p.
y - orig.
y;
1009 for (
size_t i = 1;; i++)
1016 catch (logic_error&)
1024 size_t N = points.size();
1025 if (N < 2)
return false;
1027 const TPoint3D& orig = points[N - 1];
1028 for (
size_t i = 0; i < N - 1; i++)
1031 mat(i, 0) = p.
x - orig.
x;
1032 mat(i, 1) = p.
y - orig.
y;
1033 mat(i, 2) = p.
z - orig.
z;
1042 for (
size_t i = 1;; i++)
try 1047 catch (logic_error&)
1058 for (
size_t i = 0; i < 3; i++)
1061 for (
size_t j = 0; j < 3; j++)
1072 for (
size_t i = 0; i < 3; i++)
1074 newPlane.
coefs[i] = 0;
1075 for (
size_t j = 0; j < 3; j++)
1076 newPlane.
coefs[i] += mat(i, j) * plane.
coefs[j];
1088 squareNorm<3, double>(newPlane.
coefs) /
1089 squareNorm<3, double>(plane.
coefs));
1096 size_t N = polygon.size();
1097 newPolygon.resize(N);
1098 for (
size_t i = 0; i < N; i++)
1099 project3D(polygon[i], newXYpose, newPolygon[i]);
1105 switch (
object.getType())
1118 object.getSegment(p);
1142 object.getPolygon(p);
1161 double c = cos(newXpose.
phi);
1162 double s = sin(newXpose.
phi);
1166 newLine.
coefs[1] * newXpose.
y);
1173 size_t N = line.size();
1175 for (
size_t i = 0; i < N; i++) newLine[i] = newXpose + line[i];
1224 if (!
intersect(p1, l2, obj))
return false;
1239 if (p1.size() < 3)
return false;
1242 poseNeg =
TPose2D(0, 0, 0) - pose;
1245 size_t N = projPoly.size();
1246 projPoly.push_back(projPoly[0]);
1247 double pre = projPoly[0].y;
1248 vector<TPoint2D> pnts;
1250 for (
size_t i = 1; i <= N; i++)
1252 double cur = projPoly[i].y;
1258 pnts[0] = projPoly[i - 1];
1259 pnts[1] = projPoly[i];
1263 pnts.push_back(projPoly[i]);
1267 double a = projPoly[i - 1].x;
1268 double c = projPoly[i].x;
1269 double x = a - pre * (c - a) / (cur - pre);
1270 pnts.emplace_back(x, 0);
1275 switch (pnts.size())
1294 throw std::logic_error(
"Polygon is not convex");
1320 delete data.segment;
1333 if (&r ==
this)
return *
this;
1335 switch (type = r.
type)
1380 if (&t ==
this)
return *
this;
1382 switch (type = t.
type)
1421 size_t N = poly.size();
1423 for (
size_t i = 0; i < N - 1; i++)
1453 std::vector<TSegmentWithLine> segs1,segs2;
1456 unsigned int hmInters=0;
1457 for (
size_t i=0;i<segs1.size();i++) {
1459 for (
size_t j=0;j<segs2.size();j++)
if (
intersect(s1,segs2[j],obj)) {
1460 intersections(i,j)=obj;
1464 for (
size_t i=0;i<intersections.
rows();i++) {
1465 for (
size_t j=0;j<intersections.
cols();j++) cout<<
fromObject(intersections(i,j));
1469 if (p1.contains(p2[0])) {
1472 }
else if (p2.contains(p1[0])) {
1475 }
else return false;
1497 if (!
intersect(p, s2, obj))
return false;
1515 return intersectInCommonPlane<TPolygon2D, TSegment2D>(p1, s2, p, obj);
1523 if (!
intersect(p, r2, obj))
return false;
1540 return intersectInCommonPlane<TPolygon2D, TLine2D>(p1, r2, p, obj);
1548 if (!
intersect(p, p2, obj))
return false;
1557 return intersectInCommonPlane<TPolygon2D, TLine2D>(p1, ln, p, obj);
1566 if (!
intersect(pl1, pl2, obj))
return false;
1569 return intersectInCommonPlane<TPolygon2D, TPolygon2D>(
1574 if (!intersectInCommonPlane<TPolygon2D, TLine2D>(p1, ln, pl1, obj1))
1576 if (!intersectInCommonPlane<TPolygon2D, TLine2D>(p2, ln, pl2, obj2))
1597 for (
size_t i = 0; i < 3; i++)
1598 if ((min1[i] > max2[i]) || (min2[i] > max1[i]))
return false;
1610 if (!p1.
getPlane(pl1))
return false;
1611 if (!p2.
getPlane(pl2))
return false;
1617 const std::vector<TPolygon3D>& polys, std::vector<TPlane>& planes)
1619 size_t N = polys.size();
1626 const std::vector<TPolygon3D>& v1, std::vector<TPoint3D>& minP,
1627 std::vector<TPoint3D>& maxP)
1631 size_t N = v1.size();
1635 for (
const auto& it : v1)
1644 const std::vector<TPolygon3D>& v1,
const std::vector<TPolygon3D>& v2,
1647 std::vector<TPlane> w1, w2;
1650 std::vector<TPoint3D> minBounds1, maxBounds1, minBounds2, maxBounds2;
1653 size_t M = v1.size(), N = v2.size();
1657 for (
size_t i = 0; i < M; i++)
1658 for (
size_t j = 0; j < N; j++)
1660 minBounds1[i], maxBounds1[i], minBounds2[j], maxBounds2[j]))
1662 else if (
intersectAux(v1[i], w1[i], v2[j], w2[j], obj))
1668 const std::vector<TPolygon3D>& v1,
const std::vector<TPolygon3D>& v2,
1669 std::vector<TObject3D>& objs)
1672 std::vector<TPlane> w1, w2;
1675 std::vector<TPoint3D> minBounds1, maxBounds1, minBounds2, maxBounds2;
1679 auto itP1 = w1.begin();
1680 auto itMin1 = minBounds1.begin();
1681 auto itMax1 = maxBounds1.begin();
1682 for (
auto it1 = v1.begin(); it1 != v1.end();
1683 ++it1, ++itP1, ++itMin1, ++itMax1)
1686 const TPlane& plane1 = *itP1;
1687 auto itP2 = w2.begin();
1688 const TPoint3D &min1 = *itMin1, max1 = *itMax1;
1689 auto itMin2 = minBounds2.begin();
1690 auto itMax2 = maxBounds2.begin();
1691 for (
auto it2 = v2.begin(); it2 != v2.end();
1692 ++it2, ++itP2, ++itMin2, ++itMax2)
1695 else if (
intersectAux(poly1, plane1, *it2, *itP2, obj))
1696 objs.push_back(obj);
1873 double dx = p2.
x - p1.
x;
1874 double dy = p2.
y - p1.
y;
1875 return sqrt(dx * dx + dy * dy);
1880 double dx = p2.
x - p1.
x;
1881 double dy = p2.
y - p1.
y;
1882 double dz = p2.
z - p1.
z;
1883 return sqrt(dx * dx + dy * dy + dz * dz);
1889 size_t N = poly.size();
1890 if (N < 1)
throw logic_error(
"Empty polygon");
1893 for (
size_t i = 1; i < N; i++)
1895 pMin.
x = min(pMin.
x, poly[i].x);
1896 pMin.
y = min(pMin.
y, poly[i].y);
1897 pMax.
x = max(pMax.
x, poly[i].x);
1898 pMax.
y = max(pMax.
y, poly[i].y);
1940 for (
size_t i = 0; i < 3; i++)
2004 size_t N = poly.size();
2005 if (N < 1)
throw logic_error(
"Empty polygon");
2008 for (
size_t i = 1; i < N; i++)
2010 pMin.
x = min(pMin.
x, poly[i].x);
2011 pMin.
y = min(pMin.
y, poly[i].y);
2012 pMin.
z = min(pMin.
z, poly[i].z);
2013 pMax.
x = max(pMax.
x, poly[i].x);
2014 pMax.
y = max(pMax.
y, poly[i].y);
2015 pMax.
z = max(pMax.
z, poly[i].z);
2024 for (
size_t i = 0; i < 3; i++)
2026 plane.
coefs[i] = m(i, axis);
2047 const TPose3D& pose,
const double (&normal)[3],
TPlane& plane)
2052 for (
size_t i = 0; i < 3; i++)
2055 for (
size_t j = 0; j < 3; j++) plane.
coefs[i] += normal[j] * m(i, j);
2066 const uint8_t coord1 = (coord + 1) % 3;
2067 const uint8_t coord2 = (coord + 2) % 3;
2070 for (
size_t i = 0; i < 3; i++) m(i, coord) = vec[i];
2072 double h = hypot(vec[1], vec[2]);
2080 m(1, coord1) = -vec[2] / h;
2081 m(2, coord1) = vec[1] / h;
2083 m(0, coord2) = m(1, coord) * m(2, coord1) - m(2, coord) * m(1, coord1);
2084 m(1, coord2) = m(2, coord) * m(0, coord1) - m(0, coord) * m(2, coord1);
2085 m(2, coord2) = m(0, coord) * m(1, coord1) - m(1, coord) * m(0, coord1);
2095 std::vector<double> eigenVals;
2100 line.
coefs[0] = -eigenVecs(1, 1);
2101 line.
coefs[1] = eigenVecs(0, 1);
2103 return std::sqrt(eigenVals[0] / eigenVals[1]);
2109 return (e1 < e2) ? ((e1 < e3) ? 0 : 2) : ((e2 < e3) ? 1 : 2);
2118 std::vector<double> eigenVal;
2122 const size_t selected = 2;
2123 for (
size_t i = 0; i < 3; i++)
2125 line.
pBase[i] = means[i];
2126 line.
director[i] = eigenVec(i, selected);
2128 size_t i1 = (selected + 1) % 3, i2 = (selected + 2) % 3;
2129 return std::sqrt((eigenVal[i1] + eigenVal[i2]) / eigenVal[selected]);
2134 vector<double> means;
2138 std::vector<double> eigenVal;
2142 for (
size_t i = 0; i < 3; ++i)
2146 const size_t selected = 0;
2148 for (
size_t i = 0; i < 3; i++)
2150 plane.
coefs[i] = eigenVec(i, selected);
2153 size_t i1 = (selected + 1) % 3, i2 = (selected + 2) % 3;
2154 return std::sqrt(eigenVal[selected] / (eigenVal[i1] + eigenVal[i2]));
2158 const std::vector<TSegment3D>& segms, std::vector<TPolygon3D>& polys)
2160 std::vector<TSegment3D> tmp;
2172 : seg1(s1), seg2(s2), seg1Point(s1p), seg2Point(s2p)
2179 const std::vector<TSegment3D>&
segs;
2184 size_t N = vertices.size();
2186 for (
const auto& vertice : vertices)
2187 res.push_back(segs[vertice.seg2][vertice.seg2Point ? 1 : 0]);
2193 if (v.size() > 0 && v[0].seg1 == i)
return true;
2194 for (
const auto& it : v)
2195 if (it.seg1 == i || it.seg2 == i)
return false;
2200 std::vector<std::vector<MatchingVertex>>& res, std::vector<bool>& used,
2201 size_t searching,
unsigned char mask, std::vector<MatchingVertex>& current)
2203 for (
size_t i = 0; i < mat.
cols(); i++)
2204 if (!used[i] && mat.
isNotNull(searching, i))
2206 unsigned char match = mat(searching, i) & mask;
2212 if (
true == (s1p = (!(match & 3)))) match >>= 2;
2214 if (current.size() >= 2 && current[0].seg1 == i)
2216 if (s2p != current[0].seg1Point)
2218 current.emplace_back(searching, i, s1p, s2p);
2219 for (
auto it = current.begin(); it != current.end();
2221 used[it->seg2] =
true;
2222 res.push_back(current);
2231 current.emplace_back(searching, i, s1p, s2p);
2233 mat, res, used, i, s2p ? 0x3 : 0xC, current))
2244 std::vector<std::vector<MatchingVertex>>& res, std::vector<bool>& used)
2246 vector<MatchingVertex> cur;
2247 for (
size_t i = 0; i < used.size(); i++)
2252 const std::vector<TSegment3D>& segms, std::vector<TPolygon3D>& polys,
2253 std::vector<TSegment3D>& remainder)
2255 std::vector<TSegment3D> tmp;
2256 tmp.reserve(segms.size());
2257 for (
const auto& segm : segms)
2259 tmp.push_back(segm);
2261 remainder.push_back(segm);
2262 size_t N = tmp.size();
2264 for (
size_t i = 0; i < N - 1; i++)
2265 for (
size_t j = i + 1; j < N; j++)
2288 std::vector<std::vector<MatchingVertex>>
results;
2289 std::vector<bool> usedSegments(N,
false);
2294 for (
size_t i = 0; i < N; i++)
2295 if (!usedSegments[i]) remainder.push_back(tmp[i]);
2299 const std::vector<TObject3D>& objs, std::vector<TPolygon3D>& polys)
2301 std::vector<TObject3D> tmp;
2302 std::vector<TSegment3D> sgms;
2303 TObject3D::getPolygons(objs, polys, tmp);
2304 TObject3D::getSegments(tmp, sgms);
2309 const std::vector<TObject3D>& objs, std::vector<TPolygon3D>& polys,
2310 std::vector<TObject3D>& remainder)
2312 std::vector<TObject3D> tmp;
2313 std::vector<TSegment3D> sgms, remainderSgms;
2314 TObject3D::getPolygons(objs, polys, tmp);
2315 TObject3D::getSegments(tmp, sgms, remainder);
2318 remainder.end(), remainderSgms.begin(), remainderSgms.end());
2322 const std::vector<TObject3D>& objs, std::vector<TPolygon3D>& polys,
2323 std::vector<TSegment3D>& remainder1, std::vector<TObject3D>& remainder2)
2325 std::vector<TObject3D> tmp;
2326 std::vector<TSegment3D> sgms;
2327 TObject3D::getPolygons(objs, polys, tmp);
2328 TObject3D::getSegments(tmp, sgms, remainder2);
2359 const TPolygon2D& poly, vector<TPolygon2D>& components)
2362 size_t N = poly.size();
2363 if (N <= 3)
return false;
2364 vector<TSegmentWithLine> segms(N);
2365 for (
size_t i = 0; i < N - 1; i++)
2370 for (
size_t i = 0; i < N; i++)
2372 size_t ii = (i + 2) % N, i_ = (i + N - 1) % N;
2373 for (
size_t j = ii; j != i_; j = (j + 1) % N)
2377 pnt, segms[i].segment
2378 [(
distance(pnt, segms[i].segment.point1) <
2379 distance(pnt, segms[i].segment.point2))
2384 for (
size_t k = 0; (k < N) && !cross; k++)
2394 if (cross)
continue;
2399 if (
sign(segms[i].line.evaluatePoint(poly[(i + N - 1) % N])) ==
2400 sign(segms[i].line.evaluatePoint(poly[(i + 2) % N])))
2405 p1.insert(p1.end(), poly.begin() + i + 1, poly.end());
2406 p1.insert(p1.end(), poly.begin(), poly.begin() + j + 1);
2408 p2.end(), poly.begin() + j + 1, poly.begin() + i + 1);
2413 p1.end(), poly.begin() + i + 1, poly.begin() + j + 1);
2414 p2.insert(p2.end(), poly.begin() + j + 1, poly.end());
2415 p2.insert(p2.end(), poly.begin(), poly.begin() + i + 1);
2423 vector<TPolygon2D> tempComps;
2426 components.end(), tempComps.begin(), tempComps.end());
2428 components.push_back(p1);
2431 components.end(), tempComps.begin(), tempComps.end());
2433 components.push_back(p2);
2454 const TPolygon3D& poly, vector<TPolygon3D>& components)
2457 if (!poly.
getPlane(p))
throw std::logic_error(
"Polygon is skew");
2464 vector<TPolygon2D> components2D;
2467 components.resize(components2D.size());
2469 components2D.begin(), components2D.end(), components.begin(),
2523 double ang1 = atan2(-l1.
coefs[0], l1.
coefs[1]);
2524 double ang2 = atan2(-l2.
coefs[0], l2.
coefs[1]);
2525 double ang = (ang1 + ang2) / 2;
2526 bis.
coefs[0] = -sin(ang);
2527 bis.
coefs[1] = cos(ang);
2552 const vector<TPolygonWithPlane>& vec,
const TPose3D& pose,
double& dist)
2560 for (
const auto& it : vec)
2570 double dx,
double dy,
double dz)
2574 if (std::abs(dx) < 1e-10 && std::abs(dy) < 1e-10 && std::abs(dz) < 1e-10)
2581 double n = sqrt(n_xy +
square(dz));
2588 if (fabs(dx) > 1e-4 || fabs(dy) > 1e-4)
2590 P(0, 1) = -dy / n_xy;
2591 P(1, 1) = dx / n_xy;
bool RectanglesIntersection(double R1_x_min, double R1_x_max, double R1_y_min, double R1_y_max, double R2_x_min, double R2_x_max, double R2_y_min, double R2_y_max, double R2_pose_x, double R2_pose_y, double R2_pose_phi)
Returns whether two rotated rectangles intersect.
void getCenter(TPoint2D &p) const
Segment's central point.
void project3D(const TPoint3D &point, const mrpt::math::TPose3D &newXYpose, TPoint3D &newPoint)
Uses the given pose 3D to project a point into a new base.
bool contains(const TPoint3D &point) const
Check whether a point is inside the segment.
bool intersectInCommonLine(const mrpt::math::TSegment3D &s1, const mrpt::math::TSegment3D &s2, const mrpt::math::TLine3D &lin, mrpt::math::TObject3D &obj)
void closestFromPointToLine(double Px, double Py, double x1, double y1, double x2, double y2, double &out_x, double &out_y)
Computes the closest point from a given point to a (infinite) line.
bool getPoint(TPoint2D &p) const
Gets the content as a point, returning false if the type is inadequate.
bool isNotNull(size_t nRow, size_t nCol) const
Checks whether an element of the matrix is not the default object.
TSegmentWithLine(const TPoint2D &p1, const TPoint2D &p2)
TPolygon3D operator()(const TPolygon2D &poly2D)
bool getPolygon(TPolygon2D &p) const
Gets the content as a polygon, returning false if the type is inadequate.
A compile-time fixed-size numeric matrix container.
bool splitInConvexComponents(const TPolygon2D &poly, std::vector< TPolygon2D > &components)
Splits a 2D polygon into convex components.
TPoint2D_< double > TPoint2D
Lightweight 2D point.
unsigned char getType() const
Gets content type.
void unsafeProjectPoint(const TPoint3D &point, const TPose3D &pose, TPoint2D &newPoint)
bool intersect(const TPolygonWithPlane &p1, const TLine3D &l2, double &d, double bestKnown)
void getPlanes(const std::vector< TPolygon3D > &polys, std::vector< TPlane > &planes)
bool firstOrNonPresent(size_t i, const std::vector< MatchingVertex > &v)
#define THROW_EXCEPTION(msg)
bool depthFirstSearch(const CSparseMatrixTemplate< unsigned char > &mat, std::vector< std::vector< MatchingVertex >> &res, std::vector< bool > &used, size_t searching, unsigned char mask, std::vector< MatchingVertex > ¤t)
static constexpr unsigned char GEOMETRIC_TYPE_POLYGON
Object type identifier for TPolygon2D or TPolygon3D.
bool traceRay(const std::vector< TPolygonWithPlane > &vec, const mrpt::math::TPose3D &pose, double &dist)
Fast ray tracing method using polygons' properties.
bool getSegment(TSegment3D &s) const
Gets the content as a segment, returning false if the type is not adequate.
FUnprojectPolygon2D(const TPose3D &p)
size_t getNonNullElements() const
Gets the amount of non-null elements inside the matrix.
void setEpsilon(double nE)
Changes the value of the geometric epsilon (default = 1e-5)
void assemblePolygons(const std::vector< TSegment3D > &segms, std::vector< TPolygon3D > &polys)
Tries to assemble a set of segments into a set of closed polygons.
void getSegmentBisector(const TSegment2D &sgm, TLine2D &bis)
Gets the bisector of a 2D segment.
char fromObject(const TObject2D &obj)
mrpt::math::TPose3D inversePose
Plane's inverse pose.
void createFromPoseAndVector(const mrpt::math::TPose3D &p, const double(&vector)[3], TLine3D &r)
Gets a 3D line corresponding to any arbitrary vector, in the base given by the pose.
Slightly heavyweight type to speed-up calculations with polygons in 3D.
This file implements several operations that operate element-wise on individual or pairs of container...
void fromHomogeneousMatrix(const mrpt::math::CMatrixDouble44 &HG)
bool minDistBetweenLines(double p1_x, double p1_y, double p1_z, double p2_x, double p2_y, double p2_z, double p3_x, double p3_y, double p3_z, double p4_x, double p4_y, double p4_z, double &x, double &y, double &z, double &dist)
Calculates the minimum distance between a pair of lines.
void createPlaneFromPoseXY(const mrpt::math::TPose3D &pose, TPlane &plane)
Given a pose, creates a plane orthogonal to its Z vector.
double closestSquareDistanceFromPointToLine(double Px, double Py, double x1, double y1, double x2, double y2)
Returns the square distance from a point to a line.
Standard type for storing any lightweight 2D type.
A wrapper of a TPolygon2D class, implementing CSerializable.
bool getLine(TLine2D &r) const
Gets the content as a line, returning false if the type is inadequate.
void getHomogeneousMatrix(mrpt::math::CMatrixDouble44 &HG) const
static constexpr unsigned char GEOMETRIC_TYPE_POINT
Object type identifier for TPoint2D or TPoint3D.
bool getPlane(TPlane &p) const
Gets the content as a plane, returning false if the type is not adequate.
TPoint3D pBase
Base point.
Standard object for storing any 3D lightweight object.
bool getSegment(TSegment2D &s) const
Gets the content as a segment, returning false if the type is inadequate.
TSegmentWithLine(const TSegment2D &s)
void getSegmentsWithLine(const TPolygon2D &poly, vector< TSegmentWithLine > &segs)
bool intersectInCommonPlane(const T3D &o1, const U3D &o2, const mrpt::math::TPlane &p, mrpt::math::TObject3D &obj)
void createPlaneFromPoseAndNormal(const mrpt::math::TPose3D &pose, const double(&normal)[3], TPlane &plane)
Given a pose and any vector, creates a plane orthogonal to that vector in the pose's coordinates...
void generate2DObject(TLine2D &l) const
Project into 2D space, discarding the Z coordinate.
bool contains(const TPoint2D &point) const
Check whether a point is inside (or within geometryEpsilon of a polygon edge).
size_t getIndexOfMin(const T &e1, const T &e2, const T &e3)
int rank(Scalar threshold=0) const
Finds the rank of the matrix via LU decomposition.
bool eig_symmetric(Derived &eVecs, std::vector< Scalar > &eVals, bool sorted=true) const
Read: eig()
void getAngleBisector(const TLine2D &l1, const TLine2D &l2, TLine2D &bis)
Gets the bisector of two lines or segments (implicit constructor will be used if necessary) ...
void unitarize()
Unitarize line's normal vector.
A sparse matrix container (with cells of any type), with iterators.
TTempIntersection(const TCommonRegion &common)
void createFromPoseY(const mrpt::math::TPose3D &p, TLine3D &r)
Gets a 3D line corresponding to the Y axis in a given pose.
void crossProduct3D(const T &v0, const U &v1, V &vOut)
Computes the cross product of two 3D vectors, returning a vector normal to both.
TPoint3D point1
origin point
bool conformAPlane(const std::vector< TPoint3D > &points)
Checks whether this polygon or set of points acceptably fits a plane.
const std::vector< TSegment3D > & segs
TTempIntersection & operator=(const TTempIntersection &t)
static constexpr unsigned char GEOMETRIC_TYPE_PLANE
Object type identifier for TPlane.
float d2f(const double d)
shortcut for static_cast<float>(double)
void getAsPose3D(mrpt::math::TPose3D &outPose) const
void removeRedundantVertices()
Erase every redundant vertex from the polygon, saving space.
bool getPolygon(TPolygon3D &p) const
Gets the content as a polygon, returning false if the type is not adequate.
This base provides a set of functions for maths stuff.
2D segment, consisting of two points.
bool isPoint() const
Checks whether content is a point.
void unsafeProjectPolygon(const TPolygon3D &poly, const TPose3D &pose, TPolygon2D &newPoly)
TCommonRegion & operator=(const TCommonRegion &r)
double evaluatePoint(const TPoint3D &point) const
Evaluate a point in the plane's equation.
map< string, CVectorDouble > results
3D segment, consisting of two points.
size_t cols() const
Returns the amount of columns in this matrix.
static double geometryEpsilon
std::array< double, 3 > director
Director vector.
TPoint3D point2
final point
void covariancesAndMean(const VECTOR_OF_VECTORS &elements, MATRIXLIKE &covariances, VECTORLIKE &means, const bool *elem_do_wrap2pi=nullptr)
Computes covariances and mean of any vector of containers.
void generate3DObject(TObject3D &obj) const
Project into 3D space.
bool PointIntoPolygon(double x, double y) const
Check if a point is inside the polygon.
void getRectangleBounds(const std::vector< TPoint2D > &poly, TPoint2D &pMin, TPoint2D &pMax)
Gets the rectangular bounds of a 2D polygon or set of 2D points.
void createPlaneFromPoseXZ(const mrpt::math::TPose3D &pose, TPlane &plane)
Given a pose, creates a plane orthogonal to its Y vector.
void getAsPose2D(TPose2D &outPose) const
double distance(const TPoint2D &point) const
Distance from a given point.
size_t rows() const
Returns the amount of rows in this matrix.
TPolygon3D poly
Actual polygon.
void getAsPose3DForcingOrigin(const TPoint3D ¢er, TPose3D &pose) const
3D Plane, represented by its equation
void composePoint(const TPoint3D &l, TPoint3D &g) const
void unitarize()
Unitarize normal vector.
int sign(T x)
Returns the sign of X as "1" or "-1".
double getRegressionPlane(const std::vector< TPoint3D > &points, TPlane &plane)
Using eigenvalues, gets the best fitting plane for a set of 3D points.
TPoint3D_< double > TPoint3D
Lightweight 3D point.
void getCenter(TPoint3D &p) const
Segment's central point.
FCreatePolygon(const std::vector< TSegment3D > &s)
TPoint2D point2
Destiny point.
TPolygon2D poly2D
Polygon, after being projected to the plane using inversePose.
TCommonRegion(const TPoint2D &p)
bool pointIntoPolygon2D(double px, double py, unsigned int polyEdges, const double *poly_xs, const double *poly_ys)
Returns true if the 2D point (px,py) falls INTO the given polygon.
double getAngle(const TPlane &p1, const TPlane &p2)
Computes the angle between two planes.
bool isPlane() const
Checks whether content is a plane.
bool contains(const TPoint3D &point) const
Check whether a point is inside the line.
T wrapToPi(T a)
Modifies the given angle to translate it into the ]-pi,pi] range.
double distance(const TPoint3D &point) const
Distance to 3D point.
bool contains(const TPoint2D &point) const
Check whether a point is inside a segment.
union TTempIntersection::@66 data
bool getPoint(TPoint3D &p) const
Gets the content as a point, returning false if the type is not adequate.
TPoint2D point1
Origin point.
bool SegmentsIntersection(const double x1, const double y1, const double x2, const double y2, const double x3, const double y3, const double x4, const double y4, double &ix, double &iy)
Returns the intersection point, and if it exists, between two segments.
return_t square(const num_t x)
Inline function for the square of a number.
void clear()
Completely removes all elements, although maintaining the matrix's size.
bool isLine() const
Checks whether content is a line.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
union TCommonRegion::@65 data
std::array< double, 3 > coefs
Line coefficients, stored as an array: .
TTempIntersection(const T2ListsOfSegments &segms)
TPolygon3D operator()(const std::vector< MatchingVertex > &vertices)
CMatrixDouble44 generateAxisBaseFromDirectionAndAxis(const mrpt::math::TVector3D &vec, uint8_t coord)
Creates a homogeneus matrix (4x4) such that the coordinate given (0 for x, 1 for y, 2 for z) corresponds to the provided vector.
double getRegressionLine(const std::vector< TPoint2D > &points, TLine2D &line)
Using eigenvalues, gets the best fitting line for a set of 2D points.
double getEpsilon()
Gets the value of the geometric epsilon (default = 1e-5)
void createFromPoseX(const mrpt::math::TPose3D &p, TLine3D &r)
Gets a 3D line corresponding to the X axis in a given pose.
mrpt::math::TPose3D pose
Plane's pose.
T2ListsOfSegments * segms
void getPrismBounds(const std::vector< TPoint3D > &poly, TPoint3D &pMin, TPoint3D &pMax)
Gets the prism bounds of a 3D polygon or set of 3D points.
void unitarize()
Unitarize director vector.
void getInverseHomogeneousMatrix(mrpt::math::CMatrixDouble44 &HG) const
void resize(size_t nRows, size_t nCols)
Changes the size of the matrix.
CMatrixDouble33 generateAxisBaseFromDirection(double dx, double dy, double dz)
Computes an axis base (a set of three 3D normal vectors) with the given vector being the first of the...
void createPlaneFromPoseAndAxis(const TPose3D &pose, TPlane &plane, size_t axis)
mrpt::math::TPoint2D composePoint(const TPoint2D l) const
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
MatchingVertex(size_t s1, size_t s2, bool s1p, bool s2p)
bool getLine(TLine3D &r) const
Gets the content as a line, returning false if the type is not adequate.
void project2D(const TPoint2D &point, const TPose2D &newXpose, TPoint2D &newPoint)
Uses the given pose 2D to project a point into a new base.
bool isLine() const
Checks whether content is a line.
void createFromPoseZ(const mrpt::math::TPose3D &p, TLine3D &r)
Gets a 3D line corresponding to the Z axis in a given pose.
void createPlaneFromPoseYZ(const mrpt::math::TPose3D &pose, TPlane &plane)
Given a pose, creates a plane orthogonal to its X vector.
void createFromPoseAndAxis(const TPose3D &p, TLine3D &r, size_t axis)
bool areAligned(const std::vector< TPoint2D > &points)
Checks whether this set of points acceptably fits a 2D line.
bool compatibleBounds(const TPoint3D &min1, const TPoint3D &max1, const TPoint3D &min2, const TPoint3D &max2)
bool contains(const TPoint2D &point) const
Check whether a point is inside the line.
TCommonRegion(const TCommonRegion &r)
bool intersectAux(const TPolygon3D &p1, const TPlane &pl1, const TPolygon3D &p2, const TPlane &pl2, TObject3D &obj)
void closestFromPointToSegment(double Px, double Py, double x1, double y1, double x2, double y2, double &out_x, double &out_y)
Computes the closest point from a given point to a segment.
static constexpr unsigned char GEOMETRIC_TYPE_SEGMENT
Object type identifier for TSegment2D or TSegment3D.
TTempIntersection(const TTempIntersection &t)
bool contains(const TPoint3D &point) const
Check whether a point is contained into the plane.
double distance(const TPoint3D &point) const
Distance between the line and a point.
TPlane plane
Plane containing the polygon.
void AddVertex(double x, double y)
Add a new vertex to polygon.
double minimumDistanceFromPointToSegment(const double Px, const double Py, const double x1, const double y1, const double x2, const double y2, T &out_x, T &out_y)
Computes the closest point from a given point to a segment, and returns that minimum distance...
std::array< double, 4 > coefs
Plane coefficients, stored as an array: .
bool intersect(const TSegment3D &s1, const TSegment3D &s2, TObject3D &obj)
Gets the intersection between two 3D segments.
bool getPlane(TPlane &p) const
Gets a plane which contains the polygon.
double phi
Orientation (rads)
TCommonRegion(const TSegment2D &s)
bool contains(const TPoint3D &point) const
Check whether a point is inside (or within geometryEpsilon of a polygon edge).
static constexpr unsigned char GEOMETRIC_TYPE_LINE
Object type identifier for TLine2D or TLine3D.
2D polygon, inheriting from std::vector<TPoint2D>.
3D polygon, inheriting from std::vector<TPoint3D>
double distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space.
void getMinAndMaxBounds(const std::vector< TPolygon3D > &v1, std::vector< TPoint3D > &minP, std::vector< TPoint3D > &maxP)
double distancePointToPolygon2D(double px, double py, unsigned int polyEdges, const double *poly_xs, const double *poly_ys)
Returns the closest distance of a given 2D point to a polygon, or "0" if the point is INTO the polygo...
3D line, represented by a base point and a director vector.
#define MRPT_UNUSED_PARAM(a)
Determines whether this is an X86 or AMD64 platform.
static struct FontData data
2D line without bounds, represented by its equation .