43 const double& Px,
const double& Py,
const double& x1,
const double& y1,
44 const double& x2,
const double& y2,
double& out_x,
double& out_y)
46 if (x1 == x2 && y1 == y2)
55 double Ratio = ((Px - x1) * Dx + (Py - y1) * Dy) / (Dx * Dx + Dy * Dy);
70 out_x = x1 + (Ratio * Dx);
71 out_y = y1 + (Ratio * Dy);
81 const double& Px,
const double& Py,
const double& x1,
const double& y1,
82 const double& x2,
const double& y2,
double& out_x,
double& out_y)
84 if (x1 == x2 && y1 == y2)
93 double Ratio = ((Px - x1) * Dx + (Py - y1) * Dy) / (Dx * Dx + Dy * Dy);
95 out_x = x1 + (Ratio * Dx);
96 out_y = y1 + (Ratio * Dy);
104 const double& Px,
const double& Py,
const double& x1,
const double& y1,
105 const double& x2,
const double& y2)
107 if (x1 == x2 && y1 == y2)
115 double Ratio = ((Px - x1) * Dx + (Py - y1) * Dy) / (Dx * Dx + Dy * Dy);
117 return square(x1 + (Ratio * Dx) - Px) +
square(y1 + (Ratio * Dy) - Py);
125 const double x1,
const double y1,
const double x2,
const double y2,
126 const double x3,
const double y3,
const double x4,
const double y4,
127 double& ix,
double& iy)
129 double UpperX, UpperY, LowerX, LowerY, Ax, Bx, Cx, Ay, By, Cy, d, f, e,
148 if (UpperX < x4 || x3 < LowerX)
return false;
150 else if (UpperX < x3 || x4 < LowerX)
169 if (UpperY < y4 || y3 < LowerY)
return false;
171 else if (UpperY < y3 || y4 < LowerY)
176 d = (By * Cx) - (Bx * Cy);
177 f = (Ay * Bx) - (Ax * By);
181 if (d < 0 || d > f)
return false;
183 else if (d > 0 || d < f)
186 e = (Ax * Cy) - (Ay * Cx);
190 if (e < 0 || e > f)
return false;
192 else if (e > 0 || e < f)
195 Ratio = (Ax * -By) - (Ay * -Bx);
199 Ratio = ((Cy * -Bx) - (Cx * -By)) / Ratio;
200 ix = x1 + (Ratio * Ax);
201 iy = y1 + (Ratio * Ay);
205 if ((Ax * -Cy) == (-Cx * Ay))
223 const double x1,
const double y1,
const double x2,
const double y2,
224 const double x3,
const double y3,
const double x4,
const double y4,
225 float& ix,
float& iy)
229 ix =
static_cast<float>(
x);
230 iy =
static_cast<float>(
y);
238 const double& px,
const double& py,
unsigned int polyEdges,
239 const double* poly_xs,
const double* poly_ys)
244 if (polyEdges < 3)
return res;
248 for (i = 0; i < polyEdges; i++)
250 if ((poly_ys[i] <= py && py < poly_ys[j]) ||
251 (poly_ys[j] <= py && py < poly_ys[i]))
254 if (px - poly_xs[i] <
255 ((poly_xs[j] - poly_xs[i]) * (py - poly_ys[i]) /
256 (poly_ys[j] - poly_ys[i])))
269 const double& px,
const double& py,
unsigned int polyEdges,
270 const double* poly_xs,
const double* poly_ys)
273 double minDist = 1e20f;
281 for (i = 0; i < polyEdges; i++)
285 double closestX, closestY;
287 px, py, poly_xs[j], poly_ys[j], poly_xs[i], poly_ys[i], closestX,
290 minDist =
min(d, minDist);
303 const double& p1_x,
const double& p1_y,
const double& p1_z,
304 const double& p2_x,
const double& p2_y,
const double& p2_z,
305 const double& p3_x,
const double& p3_y,
const double& p3_z,
306 const double& p4_x,
const double& p4_y,
const double& p4_z,
double&
x,
307 double&
y,
double&
z,
double& dist)
309 const double EPS = 1e-30f;
311 double p13_x, p13_y, p13_z;
312 double p43_x, p43_y, p43_z;
313 double p21_x, p21_y, p21_z;
315 double d1343, d4321, d1321, d4343, d2121;
326 if (fabs(p43_x) < EPS && fabs(p43_y) < EPS && fabs(p43_z) < EPS)
332 if (fabs(p21_x) < EPS && fabs(p21_y) < EPS && fabs(p21_z) < EPS)
335 d1343 = p13_x * p43_x + p13_y * p43_y + p13_z * p43_z;
336 d4321 = p43_x * p21_x + p43_y * p21_y + p43_z * p21_z;
337 d1321 = p13_x * p21_x + p13_y * p21_y + p13_z * p21_z;
338 d4343 = p43_x * p43_x + p43_y * p43_y + p43_z * p43_z;
339 d2121 = p21_x * p21_x + p21_y * p21_y + p21_z * p21_z;
341 denom = d2121 * d4343 - d4321 * d4321;
342 if (fabs(denom) < EPS)
return false;
344 numer = d1343 * d4321 - d1321 * d4343;
346 double mua = numer / denom;
347 double mub = (d1343 + d4321 * mua) / d4343;
348 double pa_x, pa_y, pa_z;
349 double pb_x, pb_y, pb_z;
351 pa_x = p1_x + mua * p21_x;
352 pa_y = p1_y + mua * p21_y;
353 pa_z = p1_z + mua * p21_z;
355 pb_x = p3_x + mub * p43_x;
356 pb_y = p3_y + mub * p43_y;
357 pb_z = p3_z + mub * p43_z;
363 x = 0.5 * (pa_x + pb_x);
364 y = 0.5 * (pa_y + pb_y);
365 z = 0.5 * (pa_z + pb_z);
374 const double& R1_x_min,
const double& R1_x_max,
const double& R1_y_min,
375 const double& R1_y_max,
const double& R2_x_min,
const double& R2_x_max,
376 const double& R2_y_min,
const double& R2_y_max,
const double& R2_pose_x,
377 const double& R2_pose_y,
const double& R2_pose_phi)
382 double ccos = cos(R2_pose_phi);
383 double ssin = sin(R2_pose_phi);
385 xs[0] = R2_pose_x + ccos * R2_x_min - ssin * R2_y_min;
386 ys[0] = R2_pose_y + ssin * R2_x_min + ccos * R2_y_min;
388 xs[1] = R2_pose_x + ccos * R2_x_max - ssin * R2_y_min;
389 ys[1] = R2_pose_y + ssin * R2_x_max + ccos * R2_y_min;
391 xs[2] = R2_pose_x + ccos * R2_x_max - ssin * R2_y_max;
392 ys[2] = R2_pose_y + ssin * R2_x_max + ccos * R2_y_max;
394 xs[3] = R2_pose_x + ccos * R2_x_min - ssin * R2_y_max;
395 ys[3] = R2_pose_y + ssin * R2_x_min + ccos * R2_y_max;
399 if (R1_x_min <= xs[0] && xs[0] <= R1_x_max && R1_y_min <= ys[0] &&
402 if (R1_x_min <= xs[1] && xs[1] <= R1_x_max && R1_y_min <= ys[1] &&
405 if (R1_x_min <= xs[2] && xs[2] <= R1_x_max && R1_y_min <= ys[2] &&
408 if (R1_x_min <= xs[3] && xs[3] <= R1_x_max && R1_y_min <= ys[3] &&
427 for (
int idx = 0; idx < 4; idx++)
430 R1_x_min, R1_y_min, R1_x_max, R1_y_min, xs[idx], ys[idx],
431 xs[(idx + 1) % 4], ys[(idx + 1) % 4], ix, iy))
434 R1_x_max, R1_y_min, R1_x_max, R1_y_max, xs[idx], ys[idx],
435 xs[(idx + 1) % 4], ys[(idx + 1) % 4], ix, iy))
438 R1_x_max, R1_y_max, R1_x_min, R1_y_max, xs[idx], ys[idx],
439 xs[(idx + 1) % 4], ys[(idx + 1) % 4], ix, iy))
442 R1_x_min, R1_y_max, R1_x_min, R1_y_min, xs[idx], ys[idx],
443 xs[(idx + 1) % 4], ys[(idx + 1) % 4], ix, iy))
453 template <
class T2D,
class U2D,
class T3D,
class U3D>
468 proj1.generate2DObject(proj1_2D);
469 proj2.generate2DObject(proj2_2D);
472 if (
intersect(proj1_2D, proj2_2D, obj2D))
492 TPoint3D pMin = ((s11[0][i1] < s21[0][i1]) ? s21 : s11)[0];
493 TPoint3D pMax = ((s11[1][i1] < s21[1][i1]) ? s11 : s21)[1];
499 else if (pMax[i1] < pMin[i1])
515 TPoint2D pMin = ((s11[0][i1] < s21[0][i1]) ? s21 : s11)[0];
516 TPoint2D pMax = ((s11[1][i1] < s21[1][i1]) ? s11 : s21)[1];
522 else if (pMax[i1] < pMin[i1])
539 size_t N = poly.size();
541 for (
size_t i = 0; i < N; i++)
553 for (
size_t i = 0; i < 3; i++)
559 if (d < 0 || d > bestKnown)
return false;
574 if (
obj.getLine(lin3D))
586 TObject3D obj3D1, obj3D2, obj3Dp1, obj3Dp2;
628 const vector<TPolygon3D>& oldPolys, vector<TPolygonWithPlane>& newPolys)
630 size_t N = oldPolys.size();
632 for (
size_t i = 0; i < N; i++) newPolys[i] = oldPolys[i];
671 if (!
obj.getPoint(
p))
return false;
690 if (!
obj.getPoint(
p))
return false;
704 for (
size_t i = 0; i < 3; i++)
724 size_t c1 = (i1 + 1) % 3, c2 = (i1 + 2) % 3;
774 const static size_t c1[] = {1, 2, 0};
775 const static size_t c2[] = {2, 0, 1};
777 for (
size_t i = 0; i < 3; i++)
787 for (
size_t k = 0; k < 3; k++)
p[k] = r2.
pBase[k] + u * r2.
director[k];
844 else if (
obj.getPoint(
p))
857 else if (
obj.getPoint(
p))
865 double c = 0, n1 = 0, n2 = 0;
866 for (
size_t i = 0; i < 3; i++)
872 double s = sqrt(n1 * n2);
875 return (
c /
s < 0) ?
M_PI : 0;
882 double c = 0, n1 = 0, n2 = 0;
883 for (
size_t i = 0; i < 3; i++)
889 double s = sqrt(n1 * n2);
899 double c = 0, n1 = 0, n2 = 0;
900 for (
size_t i = 0; i < 3; i++)
906 double s = sqrt(n1 * n2);
909 return (
c /
s < 0) ?
M_PI : 0;
916 double c = 0, n1 = 0, n2 = 0;
917 for (
size_t i = 0; i < 2; i++)
923 double s = sqrt(n1 * n2);
926 return (
c /
s < 0) ?
M_PI : 0;
928 return acos(
c / sqrt(n1 * n2));
935 for (
size_t i = 0; i < 3; i++)
937 r.pBase[i] = m.get_unsafe(i, 3);
938 r.director[i] = m.get_unsafe(i, axis);
962 for (
size_t i = 0; i < 3; i++)
964 r.pBase[i] = m.get_unsafe(i, 3);
966 for (
size_t j = 0; j < 3; j++)
967 r.director[i] += m.get_unsafe(i, j) * vector[j];
973 r.coefs[0] = cos(
p.phi);
974 r.coefs[1] = -sin(
p.phi);
975 r.coefs[2] = -
r.coefs[0] *
p.x -
r.coefs[1] *
p.y;
980 r.coefs[0] = sin(
p.phi);
981 r.coefs[1] = cos(
p.phi);
982 r.coefs[2] = -
r.coefs[0] *
p.x -
r.coefs[1] *
p.y;
988 double c = cos(
p.phi);
989 double s = sin(
p.phi);
990 r.coefs[0] = vector[0] *
c + vector[1] *
s;
991 r.coefs[1] = -vector[0] *
s + vector[1] *
c;
992 r.coefs[2] = -
r.coefs[0] *
p.x -
r.coefs[1] *
p.y;
998 if (N < 3)
return false;
1001 for (
size_t i = 0; i < N - 1; i++)
1004 mat(i, 0) =
p.x - orig.
x;
1005 mat(i, 1) =
p.y - orig.
y;
1006 mat(i, 2) =
p.z - orig.
z;
1018 size_t N =
points.size();
1019 if (N < 2)
return false;
1022 for (
size_t i = 0; i < N - 1; i++)
1025 mat(i, 0) =
p.x - orig.
x;
1026 mat(i, 1) =
p.y - orig.
y;
1035 for (
size_t i = 1;; i++)
try
1040 catch (logic_error&)
1047 size_t N =
points.size();
1048 if (N < 2)
return false;
1051 for (
size_t i = 0; i < N - 1; i++)
1054 mat(i, 0) =
p.x - orig.
x;
1055 mat(i, 1) =
p.y - orig.
y;
1056 mat(i, 2) =
p.z - orig.
z;
1065 for (
size_t i = 1;; i++)
try
1070 catch (logic_error&)
1082 for (
size_t i = 0; i < 3; i++)
1085 for (
size_t j = 0; j < 3; j++)
1095 for (
size_t i = 0; i < 3; i++)
1097 newPlane.
coefs[i] = 0;
1098 for (
size_t j = 0; j < 3; j++)
1099 newPlane.
coefs[i] += mat.get_unsafe(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);
1182 double c = cos(newXpose.
phi());
1183 double s = sin(newXpose.
phi());
1187 newLine.
coefs[1] * newXpose.
y());
1194 size_t N = line.size();
1196 for (
size_t i = 0; i < N; i++) newLine[i] = newXpose + line[i];
1203 switch (
obj.getType())
1248 if (
obj.getPoint(
p))
1250 else if (
obj.getSegment(
s))
1260 if (p1.size() < 3)
return false;
1263 poseNeg =
CPose2D(0, 0, 0) - pose;
1266 size_t N = projPoly.size();
1267 projPoly.push_back(projPoly[0]);
1268 double pre = projPoly[0].y;
1269 vector<TPoint2D> pnts;
1271 for (
size_t i = 1; i <= N; i++)
1273 double cur = projPoly[i].y;
1279 pnts[0] = projPoly[i - 1];
1280 pnts[1] = projPoly[i];
1284 pnts.push_back(projPoly[i]);
1288 double a = projPoly[i - 1].x;
1289 double c = projPoly[i].x;
1290 double x =
a - pre * (
c -
a) / (cur - pre);
1296 switch (pnts.size())
1315 throw std::logic_error(
"Polygon is not convex");
1340 delete data.segment;
1353 if (&
r ==
this)
return *
this;
1355 switch (
type =
r.type)
1399 if (&
t ==
this)
return *
this;
1401 switch (
type =
t.type)
1440 size_t N = poly.size();
1442 for (
size_t i = 0; i < N - 1; i++)
1449 switch (
obj.getType())
1472 std::vector<TSegmentWithLine> segs1,segs2;
1475 unsigned int hmInters=0;
1476 for (
size_t i=0;i<segs1.size();i++) {
1478 for (
size_t j=0;j<segs2.size();j++)
if (
intersect(s1,segs2[j],
obj)) {
1479 intersections(i,j)=
obj;
1483 for (
size_t i=0;i<intersections.
getRowCount();i++) {
1488 if (p1.contains(p2[0])) {
1491 }
else if (p2.contains(p1[0])) {
1494 }
else return false;
1519 if (
obj.getPoint(pnt))
1522 p.getAsPose3DForcingOrigin(p1[0], pose);
1530 else if (
obj.getSegment(sgm))
1531 return intersectInCommonPlane<TPolygon2D, TSegment2D>(p1, s2,
p,
obj);
1541 if (
obj.getPoint(pnt))
1544 p.getAsPose3DForcingOrigin(p1[0], pose);
1552 else if (
obj.isLine())
1553 return intersectInCommonPlane<TPolygon2D, TLine2D>(p1, r2,
p,
obj);
1569 else if (
obj.getLine(ln))
1570 return intersectInCommonPlane<TPolygon2D, TLine2D>(p1, ln,
p,
obj);
1582 return intersectInCommonPlane<TPolygon2D, TPolygon2D>(
1584 else if (
obj.getLine(ln))
1587 if (!intersectInCommonPlane<TPolygon2D, TLine2D>(p1, ln, pl1, obj1))
1589 if (!intersectInCommonPlane<TPolygon2D, TLine2D>(p2, ln, pl2, obj2))
1610 for (
size_t i = 0; i < 3; i++)
1611 if ((min1[i] > max2[i]) || (min2[i] > max1[i]))
return false;
1623 if (!p1.
getPlane(pl1))
return false;
1624 if (!p2.
getPlane(pl2))
return false;
1630 const std::vector<TPolygon3D>& polys, std::vector<TPlane>& planes)
1632 size_t N = polys.size();
1639 const std::vector<TPolygon3D>&
v1, std::vector<TPoint3D>& minP,
1640 std::vector<TPoint3D>& maxP)
1644 size_t N =
v1.size();
1649 it !=
v1.end(); ++it)
1658 const std::vector<TPolygon3D>&
v1,
const std::vector<TPolygon3D>&
v2,
1661 std::vector<TPlane>
w1,
w2;
1664 std::vector<TPoint3D> minBounds1, maxBounds1, minBounds2, maxBounds2;
1667 size_t M =
v1.size(), N =
v2.size();
1671 for (
size_t i = 0; i < M; i++)
1672 for (
size_t j = 0; j < N; j++)
1674 minBounds1[i], maxBounds1[i], minBounds2[j], maxBounds2[j]))
1682 const std::vector<TPolygon3D>&
v1,
const std::vector<TPolygon3D>&
v2,
1683 std::vector<TObject3D>& objs)
1686 std::vector<TPlane>
w1,
w2;
1689 std::vector<TPoint3D> minBounds1, maxBounds1, minBounds2, maxBounds2;
1697 it1 !=
v1.end(); ++it1, ++itP1, ++itMin1, ++itMax1)
1700 const TPlane& plane1 = *itP1;
1702 const TPoint3D &min1 = *itMin1, max1 = *itMax1;
1706 it2 !=
v2.end(); ++it2, ++itP2, ++itMin2, ++itMax2)
1710 objs.push_back(
obj);
1887 double dx = p2.
x - p1.
x;
1888 double dy = p2.
y - p1.
y;
1889 return sqrt(dx * dx + dy * dy);
1894 double dx = p2.
x - p1.
x;
1895 double dy = p2.
y - p1.
y;
1896 double dz = p2.
z - p1.
z;
1897 return sqrt(dx * dx + dy * dy + dz * dz);
1903 size_t N = poly.size();
1904 if (N < 1)
throw logic_error(
"Empty polygon");
1907 for (
size_t i = 1; i < N; i++)
1909 pMin.
x =
min(pMin.
x, poly[i].x);
1910 pMin.
y =
min(pMin.
y, poly[i].y);
1911 pMax.
x = max(pMax.
x, poly[i].x);
1912 pMax.
y = max(pMax.
y, poly[i].y);
1942 -(
p.coefs[0] * r1.
pBase[0] +
p.coefs[1] * r1.
pBase[1] +
1943 p.coefs[2] * r1.
pBase[2]);
1944 return p.distance(r2.
pBase);
1954 for (
size_t i = 0; i < 3; i++)
2018 size_t N = poly.size();
2019 if (N < 1)
throw logic_error(
"Empty polygon");
2022 for (
size_t i = 1; i < N; i++)
2024 pMin.
x =
min(pMin.
x, poly[i].x);
2025 pMin.
y =
min(pMin.
y, poly[i].y);
2026 pMin.
z =
min(pMin.
z, poly[i].z);
2027 pMax.
x = max(pMax.
x, poly[i].x);
2028 pMax.
y = max(pMax.
y, poly[i].y);
2029 pMax.
z = max(pMax.
z, poly[i].z);
2037 for (
size_t i = 0; i < 3; i++)
2039 plane.
coefs[i] = m.get_unsafe(i, axis);
2040 plane.
coefs[3] -= plane.
coefs[i] * m.get_unsafe(i, 3);
2060 const CPose3D& pose,
const double (&normal)[3],
TPlane& plane)
2064 for (
size_t i = 0; i < 3; i++)
2067 for (
size_t j = 0; j < 3; j++)
2068 plane.
coefs[i] += normal[j] * m.get_unsafe(i, j);
2069 plane.
coefs[3] -= plane.
coefs[i] * m.get_unsafe(i, 3);
2078 char coord1 = (
coord + 1) % 3;
2079 char coord2 = (
coord + 2) % 3;
2082 for (
size_t i = 0; i < 3; i++)
matrix.set_unsafe(i,
coord, vec[i]);
2083 matrix.set_unsafe(0, coord1, 0);
2084 double h = hypot(vec[1], vec[2]);
2087 matrix.set_unsafe(1, coord1, 1);
2088 matrix.set_unsafe(2, coord1, 0);
2092 matrix.set_unsafe(1, coord1, -vec[2] / h);
2093 matrix.set_unsafe(2, coord1, vec[1] / h);
2114 covars.eigenVectors(eigenVec, eigenVal);
2116 (eigenVal.get_unsafe(0, 0) >= eigenVal.get_unsafe(1, 1)) ? 0 : 1;
2117 line.
coefs[0] = -eigenVec.get_unsafe(1, selected);
2118 line.
coefs[1] = eigenVec.get_unsafe(0, selected);
2121 eigenVal.get_unsafe(1 - selected, 1 - selected) /
2122 eigenVal.get_unsafe(selected, selected));
2128 return (e1 < e2) ? ((e1 < e3) ? 0 : 2) : ((e2 < e3) ? 1 : 2);
2134 return (e1 > e2) ? ((e1 > e3) ? 0 : 2) : ((e2 > e3) ? 1 : 2);
2142 covars.eigenVectors(eigenVec, eigenVal);
2144 eigenVal.get_unsafe(0, 0), eigenVal.get_unsafe(1, 1),
2145 eigenVal.get_unsafe(2, 2));
2146 for (
size_t i = 0; i < 3; i++)
2148 line.
pBase[i] = means[i];
2149 line.
director[i] = eigenVec.get_unsafe(i, selected);
2151 size_t i1 = (selected + 1) % 3, i2 = (selected + 2) % 3;
2153 (eigenVal.get_unsafe(i1, i1) + eigenVal.get_unsafe(i2, i2)) /
2154 eigenVal.get_unsafe(selected, selected));
2159 vector<double> means;
2163 covars.eigenVectors(eigenVec, eigenVal);
2164 for (
size_t i = 0; i < 3; ++i)
2165 if (eigenVal.get_unsafe(i, i) < 0 &&
2167 eigenVal.set_unsafe(i, i, 0);
2169 eigenVal.get_unsafe(0, 0), eigenVal.get_unsafe(1, 1),
2170 eigenVal.get_unsafe(2, 2));
2172 for (
size_t i = 0; i < 3; i++)
2174 plane.
coefs[i] = eigenVec.get_unsafe(i, selected);
2177 size_t i1 = (selected + 1) % 3, i2 = (selected + 2) % 3;
2179 eigenVal.get_unsafe(selected, selected) /
2180 (eigenVal.get_unsafe(i1, i1) + eigenVal.get_unsafe(i2, i2)));
2184 const std::vector<TSegment3D>& segms, std::vector<TPolygon3D>& polys)
2186 std::vector<TSegment3D> tmp;
2198 : seg1(s1), seg2(s2), seg1Point(s1p), seg2Point(s2p)
2205 const std::vector<TSegment3D>&
segs;
2210 size_t N = vertices.size();
2213 it != vertices.end(); ++it)
2214 res.push_back(segs[it->seg2][it->seg2Point ? 1 : 0]);
2220 if (
v.size() > 0 &&
v[0].seg1 == i)
return true;
2222 it !=
v.end(); ++it)
2223 if (it->seg1 == i || it->seg2 == i)
return false;
2228 std::vector<std::vector<MatchingVertex>>&
res, std::vector<bool>& used,
2229 size_t searching,
unsigned char mask, std::vector<MatchingVertex>& current)
2232 if (!used[i] && mat.
isNotNull(searching, i))
2234 unsigned char match = mat(searching, i) &
mask;
2240 if (
true == (s1p = (!(match & 3)))) match >>= 2;
2242 if (current.size() >= 2 && current[0].seg1 == i)
2244 if (s2p != current[0].seg1Point)
2250 it != current.end(); ++it)
2251 used[it->seg2] =
true;
2252 res.push_back(current);
2263 mat,
res, used, i, s2p ? 0x3 : 0xC, current))
2274 std::vector<std::vector<MatchingVertex>>&
res, std::vector<bool>& used)
2276 vector<MatchingVertex> cur;
2277 for (
size_t i = 0; i < used.size(); i++)
2282 const std::vector<TSegment3D>& segms, std::vector<TPolygon3D>& polys,
2283 std::vector<TSegment3D>& remainder)
2285 std::vector<TSegment3D> tmp;
2286 tmp.reserve(segms.size());
2288 it != segms.end(); ++it)
2292 remainder.push_back(*it);
2293 size_t N = tmp.size();
2295 for (
size_t i = 0; i < N - 1; i++)
2296 for (
size_t j = i + 1; j < N; j++)
2319 std::vector<std::vector<MatchingVertex>> results;
2320 std::vector<bool> usedSegments(N,
false);
2322 polys.resize(results.size());
2324 results.begin(), results.end(), polys.begin(),
FCreatePolygon(segms));
2325 for (
size_t i = 0; i < N; i++)
2326 if (!usedSegments[i]) remainder.push_back(tmp[i]);
2330 const std::vector<TObject3D>& objs, std::vector<TPolygon3D>& polys)
2332 std::vector<TObject3D> tmp;
2333 std::vector<TSegment3D> sgms;
2340 const std::vector<TObject3D>& objs, std::vector<TPolygon3D>& polys,
2341 std::vector<TObject3D>& remainder)
2343 std::vector<TObject3D> tmp;
2344 std::vector<TSegment3D> sgms, remainderSgms;
2349 remainder.end(), remainderSgms.begin(), remainderSgms.end());
2353 const std::vector<TObject3D>& objs, std::vector<TPolygon3D>& polys,
2354 std::vector<TSegment3D>& remainder1, std::vector<TObject3D>& remainder2)
2356 std::vector<TObject3D> tmp;
2357 std::vector<TSegment3D> sgms;
2393 size_t N = poly.size();
2394 if (N <= 3)
return false;
2395 vector<TSegmentWithLine> segms(N);
2396 for (
size_t i = 0; i < N - 1; i++)
2401 for (
size_t i = 0; i < N; i++)
2403 size_t ii = (i + 2) % N, i_ = (i + N - 1) % N;
2404 for (
size_t j = ii; j != i_; j = (j + 1) % N)
2409 segms[i].segment[(
distance(pnt, segms[i].segment.point1) <
2410 distance(pnt, segms[i].segment.point2))
2415 for (
size_t k = 0; (k < N) && !
cross; k++)
2418 if (
obj.getPoint(pTmp) &&
2425 if (
cross)
continue;
2430 if (
sign(segms[i].line.evaluatePoint(poly[(i + N - 1) % N])) ==
2431 sign(segms[i].line.evaluatePoint(poly[(i + 2) % N])))
2436 p1.insert(p1.end(), poly.begin() + i + 1, poly.end());
2437 p1.insert(p1.end(), poly.begin(), poly.begin() + j + 1);
2439 p2.end(), poly.begin() + j + 1, poly.begin() + i + 1);
2444 p1.end(), poly.begin() + i + 1, poly.begin() + j + 1);
2445 p2.insert(p2.end(), poly.begin() + j + 1, poly.end());
2446 p2.insert(p2.end(), poly.begin(), poly.begin() + i + 1);
2454 vector<TPolygon2D> tempComps;
2457 components.end(), tempComps.begin(), tempComps.end());
2462 components.end(), tempComps.begin(), tempComps.end());
2488 if (!poly.
getPlane(
p))
throw std::logic_error(
"Polygon is skew");
2490 p.getAsPose3DForcingOrigin(poly[0], pose1);
2495 vector<TPolygon2D> components2D;
2500 components2D.begin(), components2D.end(),
components.begin(),
2551 else if (
obj.getPoint(
p))
2554 double ang1 = atan2(-l1.
coefs[0], l1.
coefs[1]);
2555 double ang2 = atan2(-l2.
coefs[0], l2.
coefs[1]);
2556 double ang = (ang1 + ang2) / 2;
2557 bis.
coefs[0] = -sin(ang);
2558 bis.
coefs[1] = cos(ang);
2574 p.getAsPose3D(pose);
2583 const vector<TPolygonWithPlane>& vec,
const CPose3D& pose,
double& dist)
2592 it != vec.end(); ++it)
float cross(const mPointHull &O, const mPointHull &A, const mPointHull &B)
const std::vector< TSegment3D > & segs
TPolygon3D operator()(const std::vector< MatchingVertex > &vertices)
FCreatePolygon(const std::vector< TSegment3D > &s)
FUnprojectPolygon2D(const CPose3D &p)
TPolygon3D operator()(const TPolygon2D &poly2D)
A numeric matrix of compile-time fixed size.
A wrapper of a TPolygon2D class, implementing CSerializable.
bool PointIntoPolygon(double x, double y) const
Check if a point is inside the polygon.
void AddVertex(double x, double y)
Add a new vertex to polygon.
A sparse matrix container (with cells of any type), with iterators.
size_t getRowCount() const
Returns the amount of rows in this matrix.
bool isNotNull(size_t nRow, size_t nCol) const
Checks whether an element of the matrix is not the default object.
size_t getColCount() const
Returns the amount of columns in this matrix.
size_t getNonNullElements() const
Gets the amount of non-null elements inside the matrix.
void clear()
Completely removes all elements, although maintaining the matrix's size.
void resize(size_t nRows, size_t nCols)
Changes the size of the matrix.
2D polygon, inheriting from std::vector<TPoint2D>.
void removeRedundantVertices()
Erase every redundant vertex from the polygon, saving space.
bool contains(const TPoint2D &point) const
Check whether a point is inside (or within geometryEpsilon of a polygon edge).
3D polygon, inheriting from std::vector<TPoint3D>
void getBestFittingPlane(TPlane &p) const
Gets the best fitting plane, disregarding whether the polygon actually fits inside or not.
bool contains(const TPoint3D &point) const
Check whether a point is inside (or within geometryEpsilon of a polygon edge).
bool getPlane(TPlane &p) const
Gets a plane which contains the polygon.
Slightly heavyweight type to speed-up calculations with polygons in 3D.
TPolygon3D poly
Actual polygon.
TPolygonWithPlane()
Basic constructor.
TPolygon2D poly2D
Polygon, after being projected to the plane using inversePose.
mrpt::poses::CPose3D pose
Plane's pose.
static void getPlanes(const std::vector< TPolygon3D > &oldPolys, std::vector< TPolygonWithPlane > &newPolys)
Static method for vectors.
TPlane plane
Plane containing the polygon.
mrpt::poses::CPose3D inversePose
Plane's inverse pose.
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction.
A class used to store a 2D point.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle.
const double & phi() const
Get the phi angle of the 2D pose (in radians)
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
mrpt::math::CMatrixDouble44 getHomogeneousMatrixVal() const
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=nullptr, bool use_small_rot_approx=false) const
An alternative, slightly more efficient way of doing with G and L being 3D points and P this 6D pose...
double x() const
Common members of all points & poses classes.
const Scalar * const_iterator
bool intersectAux(const TPolygon3D &p1, const TPlane &pl1, const TPolygon3D &p2, const TPlane &pl2, TObject3D &obj)
bool firstOrNonPresent(size_t i, const std::vector< MatchingVertex > &v)
void getMinAndMaxBounds(const std::vector< TPolygon3D > &v1, std::vector< TPoint3D > &minP, std::vector< TPoint3D > &maxP)
static double geometryEpsilon
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)
bool compatibleBounds(const TPoint3D &min1, const TPoint3D &max1, const TPoint3D &min2, const TPoint3D &max2)
size_t getIndexOfMax(const T &e1, const T &e2, const T &e3)
void getSegmentsWithLine(const TPolygon2D &poly, vector< TSegmentWithLine > &segs)
void createFromPoseAndAxis(const CPose3D &p, TLine3D &r, size_t axis)
bool intersect(const TPolygonWithPlane &p1, const TLine3D &l2, double &d, double bestKnown)
char fromObject(const TObject2D &obj)
void unsafeProjectPoint(const TPoint3D &point, const CPose3D &pose, TPoint2D &newPoint)
bool intersectInCommonLine(const mrpt::math::TSegment3D &s1, const mrpt::math::TSegment3D &s2, const mrpt::math::TLine3D &lin, mrpt::math::TObject3D &obj)
bool intersectInCommonPlane(const T3D &o1, const U3D &o2, const mrpt::math::TPlane &p, mrpt::math::TObject3D &obj)
void unsafeProjectPolygon(const TPolygon3D &poly, const CPose3D &pose, TPolygon2D &newPoly)
void createPlaneFromPoseAndAxis(const CPose3D &pose, TPlane &plane, size_t axis)
void getPlanes(const std::vector< TPolygon3D > &polys, std::vector< TPlane > &planes)
size_t getIndexOfMin(const T &e1, const T &e2, const T &e3)
GLuint GLenum GLenum transform
GLsizei GLsizei GLuint * obj
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble GLdouble w2
GLsizei GLsizei GLenum GLenum const GLvoid * data
GLenum GLenum GLuint components
GLuint GLuint GLsizei GLenum type
GLfloat GLfloat GLfloat v2
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
GLdouble GLdouble GLdouble r
GLubyte GLubyte GLubyte a
GLsizei const GLfloat * points
bool areAligned(const std::vector< TPoint2D > &points)
Checks whether this set of points acceptably fits a 2D line.
bool splitInConvexComponents(const TPolygon2D &poly, std::vector< TPolygon2D > &components)
Splits a 2D polygon into convex components.
void createPlaneFromPoseYZ(const mrpt::poses::CPose3D &pose, TPlane &plane)
Given a pose, creates a plane orthogonal to its X vector.
void createPlaneFromPoseAndNormal(const mrpt::poses::CPose3D &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 getRectangleBounds(const std::vector< TPoint2D > &poly, TPoint2D &pMin, TPoint2D &pMax)
Gets the rectangular bounds of a 2D polygon or set of 2D points.
void createFromPoseX(const mrpt::poses::CPose3D &p, TLine3D &r)
Gets a 3D line corresponding to the X axis in a given pose.
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.
const unsigned char GEOMETRIC_TYPE_POINT
Object type identifier for TPoint2D or TPoint3D.
void project2D(const TPoint2D &point, const mrpt::poses::CPose2D &newXpose, TPoint2D &newPoint)
Uses the given pose 2D to project a point into a new base.
void createFromPoseY(const mrpt::poses::CPose3D &p, TLine3D &r)
Gets a 3D line corresponding to the Y axis in a given pose.
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.
void createPlaneFromPoseXY(const mrpt::poses::CPose3D &pose, TPlane &plane)
Given a pose, creates a plane orthogonal to its Z vector.
bool traceRay(const std::vector< TPolygonWithPlane > &vec, const mrpt::poses::CPose3D &pose, double &dist)
Fast ray tracing method using polygons' properties.
const unsigned char GEOMETRIC_TYPE_LINE
Object type identifier for TLine2D or TLine3D.
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.
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.
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)
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.
double distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space.
void setEpsilon(double nE)
Changes the value of the geometric epsilon (default = 1e-5)
void project3D(const TPoint3D &point, const mrpt::poses::CPose3D &newXYpose, TPoint3D &newPoint)
Uses the given pose 3D to project a point into a new base.
double getRegressionLine(const std::vector< TPoint2D > &points, TLine2D &line)
Using eigenvalues, gets the best fitting line for a set of 2D points.
const unsigned char GEOMETRIC_TYPE_POLYGON
Object type identifier for TPolygon2D or TPolygon3D.
void getPrismBounds(const std::vector< TPoint3D > &poly, TPoint3D &pMin, TPoint3D &pMax)
Gets the prism bounds of a 3D polygon or set of 3D points.
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.
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...
const unsigned char GEOMETRIC_TYPE_SEGMENT
Object type identifier for TSegment2D or TSegment3D.
double getEpsilon()
Gets the value of the geometric epsilon (default = 1e-5)
bool intersect(const TSegment3D &s1, const TSegment3D &s2, TObject3D &obj)
Gets the intersection between two 3D segments.
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.
bool conformAPlane(const std::vector< TPoint3D > &points)
Checks whether this polygon or set of points acceptably fits a plane.
void generateAxisBaseFromDirectionAndAxis(const double(&vec)[3], char coord, CMatrixDouble &matrix)
Creates a homogeneus matrix (4x4) such that the coordinate given (0 for x, 1 for y,...
void crossProduct3D(const T &v0, const U &v1, V &vOut)
Computes the cross product of two 3D vectors, returning a vector normal to both.
void getSegmentBisector(const TSegment2D &sgm, TLine2D &bis)
Gets the bisector of a 2D segment.
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.
double getRegressionPlane(const std::vector< TPoint3D > &points, TPlane &plane)
Using eigenvalues, gets the best fitting plane for a set of 3D points.
double getAngle(const TPlane &p1, const TPlane &p2)
Computes the angle between two planes.
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 createFromPoseAndVector(const mrpt::poses::CPose3D &p, const double(&vector)[3], TLine3D &r)
Gets a 3D line corresponding to any arbitrary vector, in the base given by the pose.
const unsigned char GEOMETRIC_TYPE_PLANE
Object type identifier for TPlane.
void createPlaneFromPoseXZ(const mrpt::poses::CPose3D &pose, TPlane &plane)
Given a pose, creates a plane orthogonal to its Y vector.
void createFromPoseZ(const mrpt::poses::CPose3D &p, TLine3D &r)
Gets a 3D line corresponding to the Z axis in a given pose.
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.
#define THROW_EXCEPTION(msg)
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
This base provides a set of functions for maths stuff.
T square(const T x)
Inline function for the square of a number.
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values,...
int sign(T x)
Returns the sign of X as "1" or "-1".
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
This file implements several operations that operate element-wise on individual or pairs of container...
MatchingVertex(size_t s1, size_t s2, bool s1p, bool s2p)
TCommonRegion & operator=(const TCommonRegion &r)
TCommonRegion(const TSegment2D &s)
TCommonRegion(const TPoint2D &p)
TCommonRegion(const TCommonRegion &r)
TSegmentWithLine(const TPoint2D &p1, const TPoint2D &p2)
TSegmentWithLine(const TSegment2D &s)
TTempIntersection(const T2ListsOfSegments &segms)
TTempIntersection(const TTempIntersection &t)
T2ListsOfSegments * segms
TTempIntersection & operator=(const TTempIntersection &t)
TTempIntersection(const TCommonRegion &common)
2D line without bounds, represented by its equation .
double coefs[3]
Line coefficients, stored as an array: .
void unitarize()
Unitarize line's normal vector.
double distance(const TPoint2D &point) const
Distance from a given point.
void getAsPose2D(mrpt::poses::CPose2D &outPose) const
Get a pose2D whose X axis corresponds to the line.
bool contains(const TPoint2D &point) const
Check whether a point is inside the line.
3D line, represented by a base point and a director vector.
double distance(const TPoint3D &point) const
Distance between the line and a point.
double director[3]
Director vector.
void unitarize()
Unitarize director vector.
bool contains(const TPoint3D &point) const
Check whether a point is inside the line.
void generate2DObject(TLine2D &l) const
Project into 2D space, discarding the Z coordinate.
TPoint3D pBase
Base point.
Standard type for storing any lightweight 2D type.
void generate3DObject(TObject3D &obj) const
Project into 3D space.
bool getLine(TLine2D &r) const
Gets the content as a line, returning false if the type is inadequate.
bool getSegment(TSegment2D &s) const
Gets the content as a segment, returning false if the type is inadequate.
bool getPolygon(TPolygon2D &p) const
Gets the content as a polygon, returning false if the type is inadequate.
bool getPoint(TPoint2D &p) const
Gets the content as a point, returning false if the type is inadequate.
Standard object for storing any 3D lightweight object.
static void getSegments(const std::vector< TObject3D > &objs, std::vector< TSegment3D > &sgms)
Static method to retrieve every segment included in a vector of objects.
bool getPlane(TPlane &p) const
Gets the content as a plane, returning false if the type is not adequate.
bool getSegment(TSegment3D &s) const
Gets the content as a segment, returning false if the type is not adequate.
bool getLine(TLine3D &r) const
Gets the content as a line, returning false if the type is not adequate.
static void getPolygons(const std::vector< TObject3D > &objs, std::vector< TPolygon3D > &polys)
Static method to retrieve every polygon included in a vector of objects.
bool getPoint(TPoint3D &p) const
Gets the content as a point, returning false if the type is not adequate.
bool isPoint() const
Checks whether content is a point.
bool getPolygon(TPolygon3D &p) const
Gets the content as a polygon, returning false if the type is not adequate.
3D Plane, represented by its equation
double distance(const TPoint3D &point) const
Distance to 3D point.
double evaluatePoint(const TPoint3D &point) const
Evaluate a point in the plane's equation.
void getAsPose3D(mrpt::poses::CPose3D &outPose)
Gets a pose whose XY plane corresponds to this plane.
bool contains(const TPoint3D &point) const
Check whether a point is contained into the plane.
double coefs[4]
Plane coefficients, stored as an array: .
void unitarize()
Unitarize normal vector.
double x
X,Y,Z coordinates.
2D segment, consisting of two points.
bool contains(const TPoint2D &point) const
Check whether a point is inside a segment.
TPoint2D point2
Destiny point.
TPoint2D point1
Origin point.
void getCenter(TPoint2D &p) const
Segment's central point.
3D segment, consisting of two points.
TPoint3D point1
Origin point.
void getCenter(TPoint3D &p) const
Segment's central point.
TPoint3D point2
Destiny point.
bool contains(const TPoint3D &point) const
Check whether a point is inside the segment.