26 #include <Eigen/Dense> 40 const double& Px,
const double& Py,
const double& x1,
const double& y1,
41 const double& x2,
const double& y2,
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 const double& Px,
const double& Py,
const double& x1,
const double& y1,
79 const double& x2,
const double& y2,
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 const double& Px,
const double& Py,
const double& x1,
const double& y1,
102 const double& x2,
const double& y2)
104 if (x1 == x2 && y1 == y2)
112 double Ratio = ((Px - x1) * Dx + (Py - y1) * Dy) / (Dx * Dx + Dy * Dy);
114 return square(x1 + (Ratio * Dx) - Px) +
square(y1 + (Ratio * Dy) - Py);
122 const double x1,
const double y1,
const double x2,
const double y2,
123 const double x3,
const double y3,
const double x4,
const double y4,
124 double& ix,
double& iy)
126 double UpperX, UpperY, LowerX, LowerY, Ax, Bx, Cx, Ay, By, Cy, d, f, e,
145 if (UpperX < x4 || x3 < LowerX)
return false;
147 else if (UpperX < x3 || x4 < LowerX)
166 if (UpperY < y4 || y3 < LowerY)
return false;
168 else if (UpperY < y3 || y4 < LowerY)
173 d = (By * Cx) - (Bx * Cy);
174 f = (Ay * Bx) - (Ax * By);
178 if (d < 0 || d > f)
return false;
180 else if (d > 0 || d < f)
183 e = (Ax * Cy) - (Ay * Cx);
187 if (e < 0 || e > f)
return false;
189 else if (e > 0 || e < f)
192 Ratio = (Ax * -By) - (Ay * -Bx);
196 Ratio = ((Cy * -Bx) - (Cx * -By)) / Ratio;
197 ix = x1 + (Ratio * Ax);
198 iy = y1 + (Ratio * Ay);
202 if ((Ax * -Cy) == (-Cx * Ay))
220 const double x1,
const double y1,
const double x2,
const double y2,
221 const double x3,
const double y3,
const double x4,
const double y4,
222 float& ix,
float& iy)
226 ix =
static_cast<float>(
x);
227 iy =
static_cast<float>(
y);
235 const double& px,
const double& py,
unsigned int polyEdges,
236 const double* poly_xs,
const double* poly_ys)
241 if (polyEdges < 3)
return res;
245 for (i = 0; i < polyEdges; i++)
247 if ((poly_ys[i] <= py && py < poly_ys[j]) ||
248 (poly_ys[j] <= py && py < poly_ys[i]))
251 if (px - poly_xs[i] <
252 ((poly_xs[j] - poly_xs[i]) * (py - poly_ys[i]) /
253 (poly_ys[j] - poly_ys[i])))
266 const double& px,
const double& py,
unsigned int polyEdges,
267 const double* poly_xs,
const double* poly_ys)
270 double minDist = 1e20f;
278 for (i = 0; i < polyEdges; i++)
282 double closestX, closestY;
284 px, py, poly_xs[j], poly_ys[j], poly_xs[i], poly_ys[i], closestX,
287 minDist =
min(d, minDist);
300 const double& p1_x,
const double& p1_y,
const double& p1_z,
301 const double& p2_x,
const double& p2_y,
const double& p2_z,
302 const double& p3_x,
const double& p3_y,
const double& p3_z,
303 const double& p4_x,
const double& p4_y,
const double& p4_z,
double&
x,
304 double&
y,
double&
z,
double& dist)
306 const double EPS = 1e-30f;
308 double p13_x, p13_y, p13_z;
309 double p43_x, p43_y, p43_z;
310 double p21_x, p21_y, p21_z;
312 double d1343, d4321, d1321, d4343, d2121;
323 if (fabs(p43_x) < EPS && fabs(p43_y) < EPS && fabs(p43_z) < EPS)
329 if (fabs(p21_x) < EPS && fabs(p21_y) < EPS && fabs(p21_z) < EPS)
332 d1343 = p13_x * p43_x + p13_y * p43_y + p13_z * p43_z;
333 d4321 = p43_x * p21_x + p43_y * p21_y + p43_z * p21_z;
334 d1321 = p13_x * p21_x + p13_y * p21_y + p13_z * p21_z;
335 d4343 = p43_x * p43_x + p43_y * p43_y + p43_z * p43_z;
336 d2121 = p21_x * p21_x + p21_y * p21_y + p21_z * p21_z;
338 denom = d2121 * d4343 - d4321 * d4321;
339 if (fabs(denom) < EPS)
return false;
341 numer = d1343 * d4321 - d1321 * d4343;
343 double mua = numer / denom;
344 double mub = (d1343 + d4321 * mua) / d4343;
345 double pa_x, pa_y, pa_z;
346 double pb_x, pb_y, pb_z;
348 pa_x = p1_x + mua * p21_x;
349 pa_y = p1_y + mua * p21_y;
350 pa_z = p1_z + mua * p21_z;
352 pb_x = p3_x + mub * p43_x;
353 pb_y = p3_y + mub * p43_y;
354 pb_z = p3_z + mub * p43_z;
360 x = 0.5 * (pa_x + pb_x);
361 y = 0.5 * (pa_y + pb_y);
362 z = 0.5 * (pa_z + pb_z);
371 const double& R1_x_min,
const double& R1_x_max,
const double& R1_y_min,
372 const double& R1_y_max,
const double& R2_x_min,
const double& R2_x_max,
373 const double& R2_y_min,
const double& R2_y_max,
const double& R2_pose_x,
374 const double& R2_pose_y,
const double& R2_pose_phi)
379 double ccos = cos(R2_pose_phi);
380 double ssin = sin(R2_pose_phi);
382 xs[0] = R2_pose_x + ccos * R2_x_min - ssin * R2_y_min;
383 ys[0] = R2_pose_y + ssin * R2_x_min + ccos * R2_y_min;
385 xs[1] = R2_pose_x + ccos * R2_x_max - ssin * R2_y_min;
386 ys[1] = R2_pose_y + ssin * R2_x_max + ccos * R2_y_min;
388 xs[2] = R2_pose_x + ccos * R2_x_max - ssin * R2_y_max;
389 ys[2] = R2_pose_y + ssin * R2_x_max + ccos * R2_y_max;
391 xs[3] = R2_pose_x + ccos * R2_x_min - ssin * R2_y_max;
392 ys[3] = R2_pose_y + ssin * R2_x_min + ccos * R2_y_max;
396 if (R1_x_min <= xs[0] && xs[0] <= R1_x_max && R1_y_min <= ys[0] &&
399 if (R1_x_min <= xs[1] && xs[1] <= R1_x_max && R1_y_min <= ys[1] &&
402 if (R1_x_min <= xs[2] && xs[2] <= R1_x_max && R1_y_min <= ys[2] &&
405 if (R1_x_min <= xs[3] && xs[3] <= R1_x_max && R1_y_min <= ys[3] &&
424 for (
int idx = 0; idx < 4; idx++)
427 R1_x_min, R1_y_min, R1_x_max, R1_y_min, xs[idx], ys[idx],
428 xs[(idx + 1) % 4], ys[(idx + 1) % 4], ix, iy))
431 R1_x_max, R1_y_min, R1_x_max, R1_y_max, xs[idx], ys[idx],
432 xs[(idx + 1) % 4], ys[(idx + 1) % 4], ix, iy))
435 R1_x_max, R1_y_max, R1_x_min, R1_y_max, xs[idx], ys[idx],
436 xs[(idx + 1) % 4], ys[(idx + 1) % 4], ix, iy))
439 R1_x_min, R1_y_max, R1_x_min, R1_y_min, xs[idx], ys[idx],
440 xs[(idx + 1) % 4], ys[(idx + 1) % 4], ix, iy))
450 template <
class T2D,
class U2D,
class T3D,
class U3D>
465 proj1.generate2DObject(proj1_2D);
466 proj2.generate2DObject(proj2_2D);
469 if (
intersect(proj1_2D, proj2_2D, obj2D))
489 TPoint3D pMin = ((s11[0][i1] < s21[0][i1]) ? s21 : s11)[0];
490 TPoint3D pMax = ((s11[1][i1] < s21[1][i1]) ? s11 : s21)[1];
496 else if (pMax[i1] < pMin[i1])
512 TPoint2D pMin = ((s11[0][i1] < s21[0][i1]) ? s21 : s11)[0];
513 TPoint2D pMax = ((s11[1][i1] < s21[1][i1]) ? s11 : s21)[1];
519 else if (pMax[i1] < pMin[i1])
532 newPoint.
x = dummy.
x;
533 newPoint.
y = dummy.
y;
538 size_t N = poly.size();
540 for (
size_t i = 0; i < N; i++)
552 for (
size_t i = 0; i < 3; i++)
558 if (d < 0 || d > bestKnown)
return false;
573 if (
obj.getLine(lin3D))
585 TObject3D obj3D1, obj3D2, obj3Dp1, obj3Dp2;
631 const vector<TPolygon3D>& oldPolys, vector<TPolygonWithPlane>& newPolys)
633 size_t N = oldPolys.size();
635 for (
size_t i = 0; i < N; i++) newPolys[i] = oldPolys[i];
674 if (!
obj.getPoint(
p))
return false;
693 if (!
obj.getPoint(
p))
return false;
707 for (
size_t i = 0; i < 3; i++)
727 size_t c1 = (i1 + 1) % 3, c2 = (i1 + 2) % 3;
777 const static size_t c1[] = {1, 2, 0};
778 const static size_t c2[] = {2, 0, 1};
780 for (
size_t i = 0; i < 3; i++)
790 for (
size_t k = 0; k < 3; k++)
p[k] = r2.
pBase[k] + u * r2.
director[k];
847 else if (
obj.getPoint(
p))
860 else if (
obj.getPoint(
p))
868 double c = 0, n1 = 0, n2 = 0;
869 for (
size_t i = 0; i < 3; i++)
875 double s = sqrt(n1 * n2);
878 return (
c /
s < 0) ?
M_PI : 0;
885 double c = 0, n1 = 0, n2 = 0;
886 for (
size_t i = 0; i < 3; i++)
892 double s = sqrt(n1 * n2);
902 double c = 0, n1 = 0, n2 = 0;
903 for (
size_t i = 0; i < 3; i++)
909 double s = sqrt(n1 * n2);
912 return (
c /
s < 0) ?
M_PI : 0;
919 const double ang1 = std::atan2(-r1.
coefs[0], r1.
coefs[1]);
920 const double ang2 = std::atan2(-r2.
coefs[0], r2.
coefs[1]);
928 p.getHomogeneousMatrix(m);
929 for (
size_t i = 0; i < 3; i++)
931 r.pBase[i] = m(i, 3);
932 r.director[i] = m(i, axis);
956 p.getHomogeneousMatrix(m);
957 for (
size_t i = 0; i < 3; i++)
959 r.pBase[i] = m(i, 3);
961 for (
size_t j = 0; j < 3; j++)
r.director[i] += m(i, j) * vector[j];
967 r.coefs[0] = cos(
p.phi);
968 r.coefs[1] = -sin(
p.phi);
969 r.coefs[2] = -
r.coefs[0] *
p.x -
r.coefs[1] *
p.y;
974 r.coefs[0] = sin(
p.phi);
975 r.coefs[1] = cos(
p.phi);
976 r.coefs[2] = -
r.coefs[0] *
p.x -
r.coefs[1] *
p.y;
982 double c = cos(
p.phi);
983 double s = sin(
p.phi);
984 r.coefs[0] = vector[0] *
c + vector[1] *
s;
985 r.coefs[1] = -vector[0] *
s + vector[1] *
c;
986 r.coefs[2] = -
r.coefs[0] *
p.x -
r.coefs[1] *
p.y;
992 if (N < 3)
return false;
995 for (
size_t i = 0; i < N - 1; i++)
998 mat(i, 0) =
p.x - orig.
x;
999 mat(i, 1) =
p.y - orig.
y;
1000 mat(i, 2) =
p.z - orig.
z;
1002 return mat.
rank() == 2;
1012 size_t N =
points.size();
1013 if (N < 2)
return false;
1016 for (
size_t i = 0; i < N - 1; i++)
1019 mat(i, 0) =
p.x - orig.
x;
1020 mat(i, 1) =
p.y - orig.
y;
1022 return mat.
rank() == 1;
1029 for (
size_t i = 1;; i++)
1036 catch (logic_error&)
1044 size_t N =
points.size();
1045 if (N < 2)
return false;
1048 for (
size_t i = 0; i < N - 1; i++)
1051 mat(i, 0) =
p.x - orig.
x;
1052 mat(i, 1) =
p.y - orig.
y;
1053 mat(i, 2) =
p.z - orig.
z;
1055 return mat.
rank() == 1;
1062 for (
size_t i = 1;; i++)
try 1067 catch (logic_error&)
1078 for (
size_t i = 0; i < 3; i++)
1081 for (
size_t j = 0; j < 3; j++)
1092 for (
size_t i = 0; i < 3; i++)
1094 newPlane.
coefs[i] = 0;
1095 for (
size_t j = 0; j < 3; j++)
1096 newPlane.
coefs[i] += mat(i, j) * plane.
coefs[j];
1108 squareNorm<3, double>(newPlane.
coefs) /
1109 squareNorm<3, double>(plane.
coefs));
1116 size_t N = polygon.size();
1117 newPolygon.resize(N);
1118 for (
size_t i = 0; i < N; i++)
1119 project3D(polygon[i], newXYpose, newPolygon[i]);
1125 switch (
object.getType())
1138 object.getSegment(
p);
1162 object.getPolygon(
p);
1181 double c = cos(newXpose.
phi);
1182 double s = sin(newXpose.
phi);
1186 newLine.
coefs[1] * newXpose.
y);
1193 size_t N = line.size();
1195 for (
size_t i = 0; i < N; i++) newLine[i] = newXpose + line[i];
1202 switch (
obj.getType())
1247 if (
obj.getPoint(
p))
1249 else if (
obj.getSegment(
s))
1259 if (p1.size() < 3)
return false;
1262 poseNeg =
TPose2D(0, 0, 0) - pose;
1265 size_t N = projPoly.size();
1266 projPoly.push_back(projPoly[0]);
1267 double pre = projPoly[0].y;
1268 vector<TPoint2D> pnts;
1270 for (
size_t i = 1; i <= N; i++)
1272 double cur = projPoly[i].y;
1278 pnts[0] = projPoly[i - 1];
1279 pnts[1] = projPoly[i];
1283 pnts.push_back(projPoly[i]);
1287 double a = projPoly[i - 1].x;
1288 double c = projPoly[i].x;
1289 double x =
a - pre * (
c -
a) / (cur - pre);
1290 pnts.emplace_back(
x, 0);
1295 switch (pnts.size())
1314 throw std::logic_error(
"Polygon is not convex");
1339 delete data.segment;
1352 if (&
r ==
this)
return *
this;
1354 switch (
type =
r.type)
1398 if (&
t ==
this)
return *
this;
1400 switch (
type =
t.type)
1439 size_t N = poly.size();
1441 for (
size_t i = 0; i < N - 1; i++)
1448 switch (
obj.getType())
1471 std::vector<TSegmentWithLine> segs1,segs2;
1474 unsigned int hmInters=0;
1475 for (
size_t i=0;i<segs1.size();i++) {
1477 for (
size_t j=0;j<segs2.size();j++)
if (
intersect(s1,segs2[j],
obj)) {
1478 intersections(i,j)=
obj;
1482 for (
size_t i=0;i<intersections.
rows();i++) {
1483 for (
size_t j=0;j<intersections.
cols();j++) cout<<
fromObject(intersections(i,j));
1487 if (p1.contains(p2[0])) {
1490 }
else if (p2.contains(p1[0])) {
1493 }
else return false;
1518 if (
obj.getPoint(pnt))
1521 p.getAsPose3DForcingOrigin(p1[0], pose);
1532 else if (
obj.getSegment(sgm))
1533 return intersectInCommonPlane<TPolygon2D, TSegment2D>(p1, s2,
p,
obj);
1543 if (
obj.getPoint(pnt))
1546 p.getAsPose3DForcingOrigin(p1[0], pose);
1557 else if (
obj.isLine())
1558 return intersectInCommonPlane<TPolygon2D, TLine2D>(p1, r2,
p,
obj);
1574 else if (
obj.getLine(ln))
1575 return intersectInCommonPlane<TPolygon2D, TLine2D>(p1, ln,
p,
obj);
1587 return intersectInCommonPlane<TPolygon2D, TPolygon2D>(
1589 else if (
obj.getLine(ln))
1592 if (!intersectInCommonPlane<TPolygon2D, TLine2D>(p1, ln, pl1, obj1))
1594 if (!intersectInCommonPlane<TPolygon2D, TLine2D>(p2, ln, pl2, obj2))
1615 for (
size_t i = 0; i < 3; i++)
1616 if ((min1[i] > max2[i]) || (min2[i] > max1[i]))
return false;
1628 if (!p1.
getPlane(pl1))
return false;
1629 if (!p2.
getPlane(pl2))
return false;
1635 const std::vector<TPolygon3D>& polys, std::vector<TPlane>& planes)
1637 size_t N = polys.size();
1644 const std::vector<TPolygon3D>&
v1, std::vector<TPoint3D>& minP,
1645 std::vector<TPoint3D>& maxP)
1649 size_t N =
v1.size();
1653 for (
const auto& it :
v1)
1662 const std::vector<TPolygon3D>&
v1,
const std::vector<TPolygon3D>&
v2,
1665 std::vector<TPlane>
w1,
w2;
1668 std::vector<TPoint3D> minBounds1, maxBounds1, minBounds2, maxBounds2;
1671 size_t M =
v1.size(), N =
v2.size();
1675 for (
size_t i = 0; i < M; i++)
1676 for (
size_t j = 0; j < N; j++)
1678 minBounds1[i], maxBounds1[i], minBounds2[j], maxBounds2[j]))
1686 const std::vector<TPolygon3D>&
v1,
const std::vector<TPolygon3D>&
v2,
1687 std::vector<TObject3D>& objs)
1690 std::vector<TPlane>
w1,
w2;
1693 std::vector<TPoint3D> minBounds1, maxBounds1, minBounds2, maxBounds2;
1697 auto itP1 =
w1.begin();
1698 auto itMin1 = minBounds1.begin();
1699 auto itMax1 = maxBounds1.begin();
1700 for (
auto it1 =
v1.begin(); it1 !=
v1.end();
1701 ++it1, ++itP1, ++itMin1, ++itMax1)
1704 const TPlane& plane1 = *itP1;
1705 auto itP2 =
w2.begin();
1706 const TPoint3D &min1 = *itMin1, max1 = *itMax1;
1707 auto itMin2 = minBounds2.begin();
1708 auto itMax2 = maxBounds2.begin();
1709 for (
auto it2 =
v2.begin(); it2 !=
v2.end();
1710 ++it2, ++itP2, ++itMin2, ++itMax2)
1714 objs.push_back(
obj);
1891 double dx = p2.
x - p1.
x;
1892 double dy = p2.
y - p1.
y;
1893 return sqrt(dx * dx + dy * dy);
1898 double dx = p2.
x - p1.
x;
1899 double dy = p2.
y - p1.
y;
1900 double dz = p2.
z - p1.
z;
1901 return sqrt(dx * dx + dy * dy + dz * dz);
1907 size_t N = poly.size();
1908 if (N < 1)
throw logic_error(
"Empty polygon");
1911 for (
size_t i = 1; i < N; i++)
1913 pMin.
x =
min(pMin.
x, poly[i].x);
1914 pMin.
y =
min(pMin.
y, poly[i].y);
1915 pMax.
x = max(pMax.
x, poly[i].x);
1916 pMax.
y = max(pMax.
y, poly[i].y);
1946 -(
p.coefs[0] * r1.
pBase[0] +
p.coefs[1] * r1.
pBase[1] +
1947 p.coefs[2] * r1.
pBase[2]);
1948 return p.distance(r2.
pBase);
1958 for (
size_t i = 0; i < 3; i++)
2022 size_t N = poly.size();
2023 if (N < 1)
throw logic_error(
"Empty polygon");
2026 for (
size_t i = 1; i < N; i++)
2028 pMin.
x =
min(pMin.
x, poly[i].x);
2029 pMin.
y =
min(pMin.
y, poly[i].y);
2030 pMin.
z =
min(pMin.
z, poly[i].z);
2031 pMax.
x = max(pMax.
x, poly[i].x);
2032 pMax.
y = max(pMax.
y, poly[i].y);
2033 pMax.
z = max(pMax.
z, poly[i].z);
2042 for (
size_t i = 0; i < 3; i++)
2044 plane.
coefs[i] = m(i, axis);
2065 const TPose3D& pose,
const double (&normal)[3],
TPlane& plane)
2070 for (
size_t i = 0; i < 3; i++)
2073 for (
size_t j = 0; j < 3; j++) plane.
coefs[i] += normal[j] * m(i, j);
2087 for (
size_t i = 0; i < 3; i++) m(i,
coord) = vec[i];
2089 double h = hypot(vec[1], vec[2]);
2097 m(1, coord1) = -vec[2] / h;
2098 m(2, coord1) = vec[1] / h;
2100 m(0, coord2) = m(1,
coord) * m(2, coord1) - m(2,
coord) * m(1, coord1);
2101 m(1, coord2) = m(2,
coord) * m(0, coord1) - m(0,
coord) * m(2, coord1);
2102 m(2, coord2) = m(0,
coord) * m(1, coord1) - m(1,
coord) * m(0, coord1);
2111 std::vector<double> eigenVals;
2116 line.
coefs[0] = -eigenVecs(1, 1);
2117 line.
coefs[1] = eigenVecs(0, 1);
2119 return std::sqrt(eigenVals[0] / eigenVals[1]);
2125 return (e1 < e2) ? ((e1 < e3) ? 0 : 2) : ((e2 < e3) ? 1 : 2);
2134 std::vector<double> eigenVal;
2138 const size_t selected = 2;
2139 for (
size_t i = 0; i < 3; i++)
2141 line.
pBase[i] = means[i];
2142 line.
director[i] = eigenVec(i, selected);
2144 size_t i1 = (selected + 1) % 3, i2 = (selected + 2) % 3;
2145 return std::sqrt((eigenVal[i1] + eigenVal[i2]) / eigenVal[selected]);
2150 vector<double> means;
2154 std::vector<double> eigenVal;
2158 for (
size_t i = 0; i < 3; ++i)
2162 const size_t selected = 0;
2164 for (
size_t i = 0; i < 3; i++)
2166 plane.
coefs[i] = eigenVec(i, selected);
2169 size_t i1 = (selected + 1) % 3, i2 = (selected + 2) % 3;
2170 return std::sqrt(eigenVal[selected] / (eigenVal[i1] + eigenVal[i2]));
2174 const std::vector<TSegment3D>& segms, std::vector<TPolygon3D>& polys)
2176 std::vector<TSegment3D> tmp;
2188 : seg1(s1), seg2(s2), seg1Point(s1p), seg2Point(s2p)
2195 const std::vector<TSegment3D>&
segs;
2200 size_t N = vertices.size();
2202 for (
const auto& vertice : vertices)
2203 res.push_back(segs[vertice.seg2][vertice.seg2Point ? 1 : 0]);
2209 if (
v.size() > 0 &&
v[0].seg1 == i)
return true;
2210 for (
const auto& it :
v)
2211 if (it.seg1 == i || it.seg2 == i)
return false;
2216 std::vector<std::vector<MatchingVertex>>&
res, std::vector<bool>& used,
2217 size_t searching,
unsigned char mask, std::vector<MatchingVertex>& current)
2219 for (
size_t i = 0; i < mat.
cols(); i++)
2220 if (!used[i] && mat.
isNotNull(searching, i))
2222 unsigned char match = mat(searching, i) &
mask;
2228 if (
true == (s1p = (!(match & 3)))) match >>= 2;
2230 if (current.size() >= 2 && current[0].seg1 == i)
2232 if (s2p != current[0].seg1Point)
2234 current.emplace_back(searching, i, s1p, s2p);
2235 for (
auto it = current.begin(); it != current.end();
2237 used[it->seg2] =
true;
2238 res.push_back(current);
2247 current.emplace_back(searching, i, s1p, s2p);
2249 mat,
res, used, i, s2p ? 0x3 : 0xC, current))
2260 std::vector<std::vector<MatchingVertex>>&
res, std::vector<bool>& used)
2262 vector<MatchingVertex> cur;
2263 for (
size_t i = 0; i < used.size(); i++)
2268 const std::vector<TSegment3D>& segms, std::vector<TPolygon3D>& polys,
2269 std::vector<TSegment3D>& remainder)
2271 std::vector<TSegment3D> tmp;
2272 tmp.reserve(segms.size());
2273 for (
const auto& segm : segms)
2275 tmp.push_back(segm);
2277 remainder.push_back(segm);
2278 size_t N = tmp.size();
2280 for (
size_t i = 0; i < N - 1; i++)
2281 for (
size_t j = i + 1; j < N; j++)
2304 std::vector<std::vector<MatchingVertex>>
results;
2305 std::vector<bool> usedSegments(N,
false);
2310 for (
size_t i = 0; i < N; i++)
2311 if (!usedSegments[i]) remainder.push_back(tmp[i]);
2315 const std::vector<TObject3D>& objs, std::vector<TPolygon3D>& polys)
2317 std::vector<TObject3D> tmp;
2318 std::vector<TSegment3D> sgms;
2325 const std::vector<TObject3D>& objs, std::vector<TPolygon3D>& polys,
2326 std::vector<TObject3D>& remainder)
2328 std::vector<TObject3D> tmp;
2329 std::vector<TSegment3D> sgms, remainderSgms;
2334 remainder.end(), remainderSgms.begin(), remainderSgms.end());
2338 const std::vector<TObject3D>& objs, std::vector<TPolygon3D>& polys,
2339 std::vector<TSegment3D>& remainder1, std::vector<TObject3D>& remainder2)
2341 std::vector<TObject3D> tmp;
2342 std::vector<TSegment3D> sgms;
2378 size_t N = poly.size();
2379 if (N <= 3)
return false;
2380 vector<TSegmentWithLine> segms(N);
2381 for (
size_t i = 0; i < N - 1; i++)
2386 for (
size_t i = 0; i < N; i++)
2388 size_t ii = (i + 2) % N, i_ = (i + N - 1) % N;
2389 for (
size_t j = ii; j != i_; j = (j + 1) % N)
2393 pnt, segms[i].segment
2394 [(
distance(pnt, segms[i].segment.point1) <
2395 distance(pnt, segms[i].segment.point2))
2400 for (
size_t k = 0; (k < N) && !
cross; k++)
2403 if (
obj.getPoint(pTmp) &&
2410 if (
cross)
continue;
2415 if (
sign(segms[i].line.evaluatePoint(poly[(i + N - 1) % N])) ==
2416 sign(segms[i].line.evaluatePoint(poly[(i + 2) % N])))
2421 p1.insert(p1.end(), poly.begin() + i + 1, poly.end());
2422 p1.insert(p1.end(), poly.begin(), poly.begin() + j + 1);
2424 p2.end(), poly.begin() + j + 1, poly.begin() + i + 1);
2429 p1.end(), poly.begin() + i + 1, poly.begin() + j + 1);
2430 p2.insert(p2.end(), poly.begin() + j + 1, poly.end());
2431 p2.insert(p2.end(), poly.begin(), poly.begin() + i + 1);
2439 vector<TPolygon2D> tempComps;
2442 components.end(), tempComps.begin(), tempComps.end());
2447 components.end(), tempComps.begin(), tempComps.end());
2473 if (!poly.
getPlane(
p))
throw std::logic_error(
"Polygon is skew");
2475 p.getAsPose3DForcingOrigin(poly[0], pose1);
2480 vector<TPolygon2D> components2D;
2485 components2D.begin(), components2D.end(),
components.begin(),
2536 else if (
obj.getPoint(
p))
2539 double ang1 = atan2(-l1.
coefs[0], l1.
coefs[1]);
2540 double ang2 = atan2(-l2.
coefs[0], l2.
coefs[1]);
2541 double ang = (ang1 + ang2) / 2;
2542 bis.
coefs[0] = -sin(ang);
2543 bis.
coefs[1] = cos(ang);
2559 p.getAsPose3D(pose);
2568 const vector<TPolygonWithPlane>& vec,
const TPose3D& pose,
double& dist)
2576 for (
const auto& it : vec)
2586 double dx,
double dy,
double dz)
2590 if (std::abs(dx) < 1e-10 && std::abs(dy) < 1e-10 && std::abs(dz) < 1e-10)
2597 double n = sqrt(n_xy +
square(dz));
2604 if (fabs(dx) > 1e-4 || fabs(dy) > 1e-4)
2606 P(0, 1) = -dy / n_xy;
2607 P(1, 1) = dx / n_xy;
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 intersectInCommonLine(const mrpt::math::TSegment3D &s1, const mrpt::math::TSegment3D &s2, const mrpt::math::TLine3D &lin, mrpt::math::TObject3D &obj)
bool getPoint(TPoint2D &p) const
Gets the content as a point, returning false if the type is inadequate.
void generateAxisBaseFromDirectionAndAxis(const double(&vec)[3], uint8_t coord, CMatrixDouble44 &matrix)
Creates a homogeneus matrix (4x4) such that the coordinate given (0 for x, 1 for y, 2 for z) corresponds to the provided vector.
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 RectanglesIntersection(const double &R1_x_min, const double &R1_x_max, const double &R1_y_min, const double &R1_y_max, const double &R2_x_min, const double &R2_x_max, const double &R2_y_min, const double &R2_y_max, const double &R2_pose_x, const double &R2_pose_y, const double &R2_pose_phi)
Returns whether two rotated rectangles intersect.
bool splitInConvexComponents(const TPolygon2D &poly, std::vector< TPolygon2D > &components)
Splits a 2D polygon into convex components.
double x
X,Y,Z coordinates.
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)
double distance(const TPoint3D &point) const
Distance between the line and a point.
void closestFromPointToLine(const double &Px, const double &Py, const double &x1, const double &y1, const double &x2, const double &y2, double &out_x, double &out_y)
Computes the closest point from a given point to a (infinite) line.
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)
void closestFromPointToSegment(const double &Px, const double &Py, const double &x1, const double &y1, const double &x2, const 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_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 minDistBetweenLines(const double &p1_x, const double &p1_y, const double &p1_z, const double &p2_x, const double &p2_y, const double &p2_z, const double &p3_x, const double &p3_y, const double &p3_z, const double &p4_x, const double &p4_y, const double &p4_z, double &x, double &y, double &z, double &dist)
Calculates the minimum distance between a pair of lines.
bool getSegment(TSegment3D &s) const
Gets the content as a segment, returning false if the type is not adequate.
double closestSquareDistanceFromPointToLine(const double &Px, const double &Py, const double &x1, const double &y1, const double &x2, const double &y2)
Returns the square distance from a point to a line.
bool contains(const TPoint2D &point) const
Check whether a point is inside a segment.
FUnprojectPolygon2D(const TPose3D &p)
bool pointIntoPolygon2D(const double &px, const 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.
size_t getNonNullElements() const
Gets the amount of non-null elements inside the matrix.
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.
mrpt::math::TPoint2D composePoint(const TPoint2D l) const
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 createPlaneFromPoseXY(const mrpt::math::TPose3D &pose, TPlane &plane)
Given a pose, creates a plane orthogonal to its Z vector.
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.
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.
bool contains(const TPoint2D &point) const
Check whether a point is inside the line.
TSegmentWithLine(const TSegment2D &s)
void getInverseHomogeneousMatrix(mrpt::math::CMatrixDouble44 &HG) const
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 getAsPose2D(TPose2D &outPose) const
GLenum GLenum GLuint components
double distance(const TPoint3D &point) const
Distance to 3D point.
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...
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()
GLsizei GLsizei GLuint * obj
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) ...
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.
GLsizei const GLfloat * points
static void getSegments(const std::vector< TObject3D > &objs, std::vector< TSegment3D > &sgms)
Static method to retrieve every segment included in a vector of objects.
void generate2DObject(TLine2D &l) const
Project into 2D space, discarding the Z coordinate.
T square(const T x)
Inline function for the square of a number.
const std::vector< TSegment3D > & segs
TTempIntersection & operator=(const TTempIntersection &t)
bool contains(const TPoint3D &point) const
Check whether a point is inside the line.
static constexpr unsigned char GEOMETRIC_TYPE_PLANE
Object type identifier for TPlane.
void unitarize()
Unitarize line's normal vector.
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.
TCommonRegion & operator=(const TCommonRegion &r)
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.
void fromHomogeneousMatrix(const mrpt::math::CMatrixDouble44 &HG)
TPoint3D point2
Destiny point.
double distancePointToPolygon2D(const double &px, const 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...
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.
bool PointIntoPolygon(double x, double y) const
Check if a point is inside the polygon.
void unitarize()
Unitarize normal vector.
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.
size_t rows() const
Returns the amount of rows in this matrix.
TPolygon3D poly
Actual polygon.
static void getPolygons(const std::vector< TObject3D > &objs, std::vector< TPolygon3D > &polys)
Static method to retrieve every polygon included in a vector of objects.
void setEpsilon(double nE)
Changes the value of the geometric epsilon (default = 1e-5)
3D Plane, represented by its equation
bool getPlane(TPlane &p) const
Gets a plane which contains the polygon.
double getRegressionPlane(const std::vector< TPoint3D > &points, TPlane &plane)
Using eigenvalues, gets the best fitting plane for a set of 3D points.
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)
double getAngle(const TPlane &p1, const TPlane &p2)
Computes the angle between two planes.
static void getPlanes(const std::vector< TPolygon3D > &oldPolys, std::vector< TPolygonWithPlane > &newPolys)
Static method for vectors.
T wrapToPi(T a)
Modifies the given angle to translate it into the ]-pi,pi] range.
void unitarize()
Unitarize director vector.
bool contains(const TPoint3D &point) const
Check whether a point is inside (or within geometryEpsilon of a polygon edge).
float cross(const mPointHull &O, const mPointHull &A, const mPointHull &B)
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.
void getHomogeneousMatrix(mrpt::math::CMatrixDouble44 &HG) const
void clear()
Completely removes all elements, although maintaining the matrix's size.
bool contains(const TPoint2D &point) const
Check whether a point is inside (or within geometryEpsilon of a polygon edge).
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
TPolygonWithPlane()=default
Basic constructor.
std::array< double, 3 > coefs
Line coefficients, stored as an array: .
TTempIntersection(const T2ListsOfSegments &segms)
TPolygon3D operator()(const std::vector< MatchingVertex > &vertices)
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
GLdouble GLdouble GLdouble r
double getRegressionLine(const std::vector< TPoint2D > &points, TLine2D &line)
Using eigenvalues, gets the best fitting line for a set of 2D points.
void generate3DObject(TObject3D &obj) const
Project into 3D space.
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.
double getEpsilon()
Gets the value of the geometric epsilon (default = 1e-5)
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)
Lightweight 3D pose (three spatial coordinates, plus three angular coordinates).
void getAsPose3D(mrpt::math::TPose3D &outPose) const
void removeRedundantVertices()
Erase every redundant vertex from the polygon, saving space.
MatchingVertex(size_t s1, size_t s2, bool s1p, bool s2p)
bool contains(const TPoint3D &point) const
Check whether a point is inside the segment.
bool getLine(TLine3D &r) const
Gets the content as a line, returning false if the type is not adequate.
double evaluatePoint(const TPoint3D &point) const
Evaluate a point in the plane's equation.
void project2D(const TPoint2D &point, const TPose2D &newXpose, TPoint2D &newPoint)
Uses the given pose 2D to project a point into a new base.
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.
int sign(T x)
Returns the sign of X as "1" or "-1".
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)
GLfloat GLfloat GLfloat v2
TCommonRegion(const TCommonRegion &r)
bool intersectAux(const TPolygon3D &p1, const TPlane &pl1, const TPolygon3D &p2, const TPlane &pl2, TObject3D &obj)
static constexpr unsigned char GEOMETRIC_TYPE_SEGMENT
Object type identifier for TSegment2D or TSegment3D.
TTempIntersection(const TTempIntersection &t)
double distance(const TPoint2D &point) const
Distance from a given point.
GLuint GLenum GLenum transform
void getBestFittingPlane(TPlane &p) const
Gets the best fitting plane, disregarding whether the polygon actually fits inside or not...
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: .
GLsizei GLsizei GLenum GLenum const GLvoid * data
GLubyte GLubyte GLubyte a
bool intersect(const TSegment3D &s1, const TSegment3D &s2, TObject3D &obj)
Gets the intersection between two 3D segments.
double phi
Orientation (rads)
TCommonRegion(const TSegment2D &s)
GLuint GLuint GLsizei GLenum type
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)
bool contains(const TPoint3D &point) const
Check whether a point is contained into the plane.
void unsafeProjectPolygon(const TPolygon3D &poly, const TPose3D &pose, TPolygon2D &newPoly)
void composePoint(const TPoint3D &l, TPoint3D &g) const
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
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.
2D line without bounds, represented by its equation .