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)
void getCenter(TPoint2D &p) const
Segment's central point.
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...
bool intersectInCommonLine(const mrpt::math::TSegment3D &s1, const mrpt::math::TSegment3D &s2, const mrpt::math::TLine3D &lin, mrpt::math::TObject3D &obj)
const unsigned char GEOMETRIC_TYPE_PLANE
Object type identifier for TPlane.
bool getPoint(TPoint2D &p) const
Gets the content as a point, returning false if the type is inadequate.
double x() const
Common members of all points & poses classes.
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.
void setEpsilon(double nE)
Changes the value of the geometric epsilon (default = 1e-5)
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.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
const unsigned char GEOMETRIC_TYPE_LINE
Object type identifier for TLine2D or TLine3D.
bool splitInConvexComponents(const TPolygon2D &poly, std::vector< TPolygon2D > &components)
Splits a 2D polygon into convex components.
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, 2 for z) corresponds to the provided vector.
const unsigned char GEOMETRIC_TYPE_POINT
Object type identifier for TPoint2D or TPoint3D.
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)
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.
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.
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.
bool traceRay(const std::vector< TPolygonWithPlane > &vec, const mrpt::poses::CPose3D &pose, double &dist)
Fast ray tracing method using polygons' properties.
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)
void createPlaneFromPoseAndAxis(const CPose3D &pose, TPlane &plane, size_t axis)
#define THROW_EXCEPTION(msg)
void unsafeProjectPolygon(const TPolygon3D &poly, const CPose3D &pose, TPolygon2D &newPoly)
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...
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
size_t getColCount() const
Returns the amount of columns in this matrix.
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 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.
void getAsPose3D(mrpt::poses::CPose3D &outPose)
Gets a pose whose XY plane corresponds to this plane.
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)
const Scalar * const_iterator
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)
GLenum GLenum GLuint components
double distance(const TPoint3D &point) const
Distance to 3D point.
size_t getIndexOfMin(const T &e1, const T &e2, const T &e3)
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) ...
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.
A sparse matrix container (with cells of any type), with iterators.
TTempIntersection(const TCommonRegion &common)
void createFromPoseY(const mrpt::poses::CPose3D &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.
T square(const T x)
Inline function for the square of a number.
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.
void createFromPoseX(const mrpt::poses::CPose3D &p, TLine3D &r)
Gets a 3D line corresponding to the X axis in a given pose.
const std::vector< TSegment3D > & segs
TTempIntersection & operator=(const TTempIntersection &t)
TPolygonWithPlane()
Basic constructor.
bool contains(const TPoint3D &point) const
Check whether a point is inside the line.
size_t getRowCount() const
Returns the amount of rows in this matrix.
void unitarize()
Unitarize line's normal vector.
A numeric matrix of compile-time fixed size.
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)
3D segment, consisting of two points.
void createPlaneFromPoseXY(const mrpt::poses::CPose3D &pose, TPlane &plane)
Given a pose, creates a plane orthogonal to its Z vector.
static double geometryEpsilon
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
mrpt::math::CMatrixDouble44 getHomogeneousMatrixVal() const
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.
void createPlaneFromPoseXZ(const mrpt::poses::CPose3D &pose, TPlane &plane)
Given a pose, creates a plane orthogonal to its Y vector.
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.
const unsigned char GEOMETRIC_TYPE_SEGMENT
Object type identifier for TSegment2D or TSegment3D.
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.
3D Plane, represented by its equation
bool getPlane(TPlane &p) const
Gets a plane which contains the polygon.
double coefs[3]
Line coefficients, stored as an array: .
double getRegressionPlane(const std::vector< TPoint3D > &points, TPlane &plane)
Using eigenvalues, gets the best fitting plane for a set of 3D points.
double x
X,Y,Z coordinates.
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.
A class used to store a 2D point.
void unitarize()
Unitarize director vector.
int sign(T x)
Returns the sign of X as "1" or "-1".
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
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.
mrpt::poses::CPose3D pose
Plane's pose.
double director[3]
Director vector.
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 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).
void getAsPose2D(mrpt::poses::CPose2D &outPose) const
Get a pose2D whose X axis corresponds to the line.
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
FUnprojectPolygon2D(const CPose3D &p)
TTempIntersection(const T2ListsOfSegments &segms)
TPolygon3D operator()(const std::vector< MatchingVertex > &vertices)
void createFromPoseAndAxis(const CPose3D &p, TLine3D &r, size_t axis)
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.
A class used to store a 2D pose, including the 2D coordinate point and a heading (phi) angle...
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
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 coefs[4]
Plane coefficients, stored as an array: .
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...
const double & phi() const
Get the phi angle of the 2D pose (in radians)
void resize(size_t nRows, size_t nCols)
Changes the size of the matrix.
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.
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.
mrpt::poses::CPose3D inversePose
Plane's inverse pose.
void unsafeProjectPoint(const TPoint3D &point, const CPose3D &pose, TPoint2D &newPoint)
void createPlaneFromPoseYZ(const mrpt::poses::CPose3D &pose, TPlane &plane)
Given a pose, creates a plane orthogonal to its X vector.
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)
size_t getIndexOfMax(const T &e1, const T &e2, const T &e3)
GLfloat GLfloat GLfloat v2
void createFromPoseZ(const mrpt::poses::CPose3D &p, TLine3D &r)
Gets a 3D line corresponding to the Z axis in a given pose.
TCommonRegion(const TCommonRegion &r)
bool intersectAux(const TPolygon3D &p1, const TPlane &pl1, const TPolygon3D &p2, const TPlane &pl2, TObject3D &obj)
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.
double getEpsilon()
Gets the value of the geometric epsilon (default = 1e-5)
const unsigned char GEOMETRIC_TYPE_POLYGON
Object type identifier for TPolygon2D or TPolygon3D.
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...
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.
TCommonRegion(const TSegment2D &s)
GLuint GLuint GLsizei GLenum type
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.
GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint GLdouble w1
3D line, represented by a base point and a director vector.
2D line without bounds, represented by its equation .