43 for (
size_t i = 0; i < f.
vertices.size(); i++)
50 const vector<math::TPolygon3D>& polys, vector<TPoint3D>& vertices,
51 vector<CPolyhedron::TPolyhedronFace>& faces)
53 vertices.reserve(4 * polys.size());
54 faces.reserve(polys.size());
56 it != polys.end(); ++it)
58 size_t N = it->size();
59 if (N < 3)
return false;
62 for (
size_t i = 0; i < N; i++)
65 find(vertices.begin(), vertices.end(), (*it)[i]);
66 if (it2 == vertices.end())
69 vertices.push_back((*it)[i]);
72 f.
vertices[i] = it2 - vertices.begin();
98 vector<JohnsonBodyPart>& parts)
109 if (parts.size() == 0) parts.push_back(
INF_NO_BODY);
114 if (numBaseEdges & 1)
return false;
115 if (i == N - 1)
return false;
119 if (i != N - 1)
return false;
120 if (parts.size() == 0) parts.push_back(
INF_NO_BODY);
127 if (parts.size() > 0)
return false;
137 if (numBaseEdges != 10)
return false;
138 if (i == N - 1)
return false;
142 if (i != N - 1)
return false;
143 if (parts.size() == 0) parts.push_back(
INF_NO_BODY);
150 if (parts.size() > 0)
return false;
160 if (i == N - 1)
return false;
171 if (i == N - 1)
return false;
176 if (numBaseEdges > 5)
return false;
177 if (i != N - 1)
return false;
178 if (parts.size() == 0) parts.push_back(
INF_NO_BODY);
182 if (numBaseEdges > 5)
return false;
183 if (i != 1)
return false;
188 if (parts.size() > 0 && (*parts.rbegin() ==
PRISM))
190 if (parts.size() == 0) parts.push_back(
INF_NO_BODY);
191 parts.push_back(
PRISM);
202 if (parts.size() == 0)
return false;
217 return numBaseEdges >> 1;
224 size_t numBaseEdges,
double angleShift,
double baseRadius,
225 double edgeLength,
bool isRotated,
bool isUpwards,
size_t base,
226 vector<TPoint3D>& verts, vector<CPolyhedron::TPolyhedronFace>& faces)
228 size_t edges2 = numBaseEdges >> 1;
230 baseRadius * sin(
M_PI / numBaseEdges) / sin(
M_PI / edges2);
237 baseRadius * cos(
M_PI / numBaseEdges) -
238 minorRadius * cos(
M_PI / edges2)));
239 double height = verts[base].z + (isUpwards ? h : -h);
240 angleShift +=
M_PI / edges2 +
241 (isRotated ? -
M_PI / numBaseEdges :
M_PI / numBaseEdges);
242 size_t minorBase = verts.size();
243 for (
size_t i = 0; i < edges2; i++)
245 double ang = angleShift + 2 *
M_PI * i / edges2;
247 TPoint3D(minorRadius * cos(ang), minorRadius * sin(ang),
height));
253 size_t iq = isRotated ? 1 : 2, it = 0;
254 for (
size_t i = 0; i < edges2; i++)
257 size_t iiq = (iq + 1) % numBaseEdges + base;
258 size_t iiiq = (iiq + 1) % numBaseEdges + base;
259 size_t iit = (it + 1) % edges2 + minorBase;
267 iq = (iq + 2) % numBaseEdges;
268 it = (it + 1) % edges2;
269 faces.push_back(tri);
270 faces.push_back(quad);
272 if (edges2 >= 3) faces.push_back(cBase);
275 double angleShift,
double baseRadius,
bool isRotated,
bool isUpwards,
276 size_t base, vector<TPoint3D>& verts,
277 vector<CPolyhedron::TPolyhedronFace>& faces)
279 double R1 = baseRadius * sqrt((5.0 - sqrt(5.0)) / 10.0);
280 double R2 = baseRadius * sqrt((5.0 + sqrt(5.0)) / 10.0);
281 double baseHeight = verts[base].z;
283 angleShift +=
M_PI / 10;
284 if (isRotated) angleShift +=
M_PI / 5;
285 for (
size_t i = 0; i < 5; i++)
287 double a = (i + i + 1) *
M_PI / 5 + angleShift;
288 double b = (i + i) *
M_PI / 5 + angleShift;
289 double ca = cos(
a), sa = sin(
a), cb = cos(
b), sb = sin(
b);
292 p1[i].
z = baseHeight + (isUpwards ? R2 : -R2);
295 p2[i].
z = baseHeight + (isUpwards ? R1 : -R1);
297 size_t newBase = verts.size();
298 for (
size_t i = 0; i < 5; i++) verts.push_back(p1[i]);
299 for (
size_t i = 0; i < 5; i++) verts.push_back(p2[i]);
302 g.vertices.resize(5);
303 size_t baseStart = isRotated ? 2 : 1;
304 for (
size_t i = 0; i < 5; i++)
306 size_t ii = (i + 1) % 5;
312 f.
vertices[1] = ((i + i + baseStart) % 10) + base;
313 f.
vertices[2] = ((i + i + 9 + baseStart) % 10) + base;
315 g.vertices[0] = newBase + (ii % 5) + 5;
316 g.vertices[1] = newBase + i;
317 g.vertices[2] = newBase + i + 5;
318 g.vertices[3] = (i + i + baseStart) % 10 + base;
319 g.vertices[4] = (i + i + baseStart + 1) % 10 + base;
322 for (
size_t i = 0; i < 5; i++)
g.vertices[i] = i + newBase;
333 return numBaseEdges + ((numBaseEdges >= 6) ? 1 : 0);
337 return numBaseEdges << 1;
349 if (*it == e.
v1 || *it == e.
v2) hm++;
355 if (planes.size() < 3)
return false;
360 for (
size_t i = 1; i < planes.size(); i++)
switch (o)
364 if (
obj.getPlane(pl))
366 else if (
obj.getLine(l))
368 else if (
obj.getPoint(pnt))
377 else if (
obj.getPoint(pnt))
383 if (!planes[i]->contains(pnt))
return false;
396 it != fs.end(); ++it)
398 const vector<uint32_t>& f = it->vertices;
410 if (hmf == 7)
return true;
418 for (where = 0; where < es.size(); where++)
426 throw std::logic_error(
"Internal error. Edge not found");
436 const vector<uint32_t>& f = it->vertices;
444 if (
res == 3)
return true;
452 throw std::logic_error(
"Faces must have exactly 3, 4 or 5 vertices.");
455 for (
size_t i = 1; i < N; i++)
457 throw std::logic_error(
"There is a non-regular polygon.");
461 throw std::logic_error(
"There is a non-regular polygon.");
474 const vector<TPoint3D>& vertices)
const
479 double CPolyhedron::TPolyhedronFace::area(
const vector<TPoint3D>& vs)
const
482 size_t N = vertices.size();
483 vector<SegmentVector> d(N - 1);
484 for (
size_t i = 1; i < N; i++)
487 for (
size_t j = 0; j < 3; j++)
489 d[i - 1][j] = vs[vertices[i]][j] - vs[vertices[0]][j];
490 d[i - 1].mod +=
square(d[i - 1][j]);
492 d[i - 1].mod = sqrt(d[i - 1].mod);
495 for (
size_t i = 1; i < N - 1; i++)
497 square(d[i - 1].mod * d[i].mod) -
498 square(dotProduct<3, double>(d[i - 1], d[i])));
502 void CPolyhedron::TPolyhedronFace::getCenter(
503 const vector<TPoint3D>& vrts,
TPoint3D&
p)
const
505 p.x =
p.y =
p.z = 0.0;
507 it != vertices.end(); ++it)
513 size_t N = vertices.size();
519 CPolyhedron::CPolyhedron(
const std::vector<math::TPolygon3D>& polys)
520 : mEdges(), mWireframe(false), mLineWidth(1), polygonsUpToDate(false)
522 std::vector<TPoint3D> vertices(0);
523 std::vector<TPolyhedronFace> faces;
525 throw std::logic_error(
"Can't create CPolygon");
527 mFaces = std::move(faces);
533 const vector<TPoint3D>& vertices,
const vector<vector<uint32_t>>& faces)
535 vector<TPolyhedronFace> aux;
537 it != faces.end(); ++it)
547 double x1,
double x2,
double y1,
double y2,
double z1,
double z2)
549 vector<TPoint3D> verts;
550 vector<TPolyhedronFace> faces;
551 for (
int i = 0; i < 8; i++)
553 TPoint3D((i & 1) ? x2 : x1, (i & 2) ? y2 : y1, (i & 4) ? z2 : z1));
554 static uint32_t faceVertices[] = {0, 1, 5, 4, 2, 3, 7, 6, 0, 2, 6, 4,
555 1, 3, 7, 5, 0, 1, 3, 2, 4, 5, 7, 6};
568 const vector<TPoint2D>& baseVertices,
double height)
571 if (baseVertices.size() < 3)
throw std::logic_error(
"Not enought vertices");
572 vector<TPoint3D> verts;
573 vector<TPolyhedronFace> faces;
576 it != baseVertices.end(); ++it)
577 verts.push_back(
TPoint3D(it->x, it->y, 0));
582 g.vertices.push_back(1);
589 g.vertices.push_back(i);
596 const vector<TPoint2D>& baseVertices,
double height1,
double height2)
599 if (N < 3)
throw std::logic_error(
"Not enought vertices");
600 vector<TPoint3D> verts;
601 verts.reserve(N + 2);
602 vector<TPolyhedronFace> faces;
603 faces.reserve(N << 1);
604 verts.push_back(
TPoint3D(0, 0, height1));
606 it != baseVertices.end(); ++it)
607 verts.push_back(
TPoint3D(it->x, it->y, 0));
608 verts.push_back(
TPoint3D(0, 0, -height2));
611 g.vertices.resize(3);
613 g.vertices[0] = N + 1;
628 const vector<TPoint2D>& baseVertices,
double height,
double ratio)
631 if (
n < 3)
throw std::logic_error(
"Not enough vertices");
632 vector<TPoint3D> verts(
n +
n);
633 vector<TPolyhedronFace> faces(
n + 2);
636 g.vertices.resize(
n);
640 verts[i] =
TPoint3D(baseVertices[i].
x, baseVertices[i].
y, 0);
642 baseVertices[i].
x * ratio, baseVertices[i].
y * ratio,
height);
658 const vector<TPoint2D>& bottomBase,
const vector<TPoint2D>& topBase,
662 if (
n < 3)
throw std::logic_error(
"Not enough vertices");
663 if (
n != topBase.size())
664 throw std::logic_error(
"Bases' number of vertices do not match");
665 vector<TPoint3D> verts(
n +
n);
666 vector<TPolyhedronFace> faces(
n +
n + 2);
669 g.vertices.resize(
n);
673 verts[i] =
TPoint3D(bottomBase[i].
x, bottomBase[i].
y, 0);
688 faces[
n +
n + 1] = h;
696 vector<TPoint3D> verts(8);
697 vector<TPolyhedronFace> faces(6);
701 if (i & 1) verts[i] = verts[i] +
v1;
702 if (i & 2) verts[i] = verts[i] +
v2;
703 if (i & 4) verts[i] = verts[i] +
v3;
725 faces[i + 3].vertices.resize(4);
727 faces[i + 3].vertices[j] = faces[i].vertices[j] + valueAdd;
733 const vector<TPoint2D>& baseVertices,
double height1,
double ratio1,
734 double height2,
double ratio2)
737 size_t N = baseVertices.size();
738 vector<TPoint3D> verts(3 * N);
740 for (
size_t i = 0; i < N; i++)
742 double x = baseVertices[i].x;
743 double y = baseVertices[i].y;
747 verts[i + N].x =
x * ratio1;
748 verts[i + N].y =
y * ratio1;
749 verts[i + N].z = height1;
750 verts[i + N2].x =
x * ratio2;
751 verts[i + N2].y =
y * ratio2;
752 verts[i + N2].z = -height2;
756 vector<TPolyhedronFace> faces(N2 + 2);
759 g.vertices.resize(N);
761 for (
size_t i = 0; i < N; i++)
763 size_t i2 = (i + 1) % N;
781 uint32_t numBaseEdges,
double baseRadius,
double basesDistance)
783 if (numBaseEdges < 3)
throw std::logic_error(
"Not enough vertices");
784 if (basesDistance == 0 || baseRadius == 0)
return CreateEmpty();
785 size_t numBaseEdges2 = numBaseEdges << 1;
786 vector<TPoint3D> verts(numBaseEdges2 + 2);
787 double space = 2 *
M_PI / numBaseEdges;
788 double shift = space / 2;
789 double height1 = basesDistance / 2;
790 double cospii = cos(
M_PI / numBaseEdges);
792 height1 * (cospii + 1) /
794 for (
size_t i = 0; i < numBaseEdges; i++)
796 double ang = space * i;
797 double ang2 = ang + shift;
798 size_t ii = i + numBaseEdges;
799 verts[i].x = baseRadius * cos(ang);
800 verts[i].y = baseRadius * sin(ang);
801 verts[i].z = -height1;
802 verts[ii].x = baseRadius * cos(ang2);
803 verts[ii].y = baseRadius * sin(ang2);
804 verts[ii].z = height1;
806 verts[numBaseEdges2].x = 0;
807 verts[numBaseEdges2].y = 0;
808 verts[numBaseEdges2].z = -height2;
809 verts[numBaseEdges2 + 1].x = 0;
810 verts[numBaseEdges2 + 1].y = 0;
811 verts[numBaseEdges2 + 1].z = height2;
812 vector<TPolyhedronFace> faces(numBaseEdges2);
815 g.vertices.resize(4);
817 g.vertices[3] = numBaseEdges2 + 1;
818 for (
size_t i = 0; i < numBaseEdges; i++)
820 size_t ii = (i + 1) % numBaseEdges;
821 size_t i2 = i + numBaseEdges;
827 g.vertices[2] = ii + numBaseEdges;
829 faces[i + numBaseEdges] =
g;
839 if (numBaseEdges < 3)
throw std::logic_error(
"Not enough vertices");
840 vector<JohnsonBodyPart> parts;
842 throw std::logic_error(
"Invalid string");
844 size_t nParts = parts.size();
845 double edgeLength = 2 * baseRadius * sin(
M_PI / numBaseEdges);
846 double antiPrismHeight = sqrt(
848 square(baseRadius) * (2 - 2 * cos(
M_PI / numBaseEdges)));
850 size_t nVerts = numBaseEdges * (nParts - 1) +
854 for (
size_t i = 0; i < nParts; i++)
856 vector<TPoint3D> verts;
857 verts.reserve(nVerts);
858 vector<TPolyhedronFace> faces;
859 faces.reserve(nFaces);
862 double h, mHeight = 0;
863 vector<pair<double, size_t>> basePositionInfo(nParts - 1);
864 for (
size_t i = 0; i < nParts - 1; i++)
866 if (parts[i] ==
PRISM)
875 basePositionInfo[i] = make_pair(mHeight += h, shifts);
878 double semi =
M_PI / numBaseEdges;
881 basePositionInfo.begin();
882 it != basePositionInfo.end(); ++it)
884 numBaseEdges, baseRadius, it->first - mHeight, semi * it->second,
886 size_t initialBase = 0, endBase = 0;
888 face.vertices.reserve(numBaseEdges);
890 for (
size_t p = 0;
p < nParts;
p++)
896 face.vertices.resize(numBaseEdges);
897 for (
size_t i = 0; i < numBaseEdges; i++)
898 face.vertices[i] = endBase + i;
899 faces.push_back(
face);
903 face.vertices.resize(numBaseEdges);
904 for (
size_t i = 0; i < numBaseEdges; i++)
905 face.vertices[i] = initialBase + i;
906 faces.push_back(
face);
912 baseRadius * sqrt(4 *
square(sin(
M_PI / numBaseEdges)) - 1);
913 face.vertices.resize(3);
914 face.vertices[0] = verts.size();
915 face.vertices[1] = initialBase + numBaseEdges - 1;
916 face.vertices[2] = initialBase;
919 faces.push_back(
face);
920 face.vertices[1] =
face.vertices[2];
922 }
while (
face.vertices[2] < initialBase + numBaseEdges);
924 TPoint3D(0, 0, verts[initialBase].
z + apexHeight));
931 baseRadius * sqrt(4 *
square(sin(
M_PI / numBaseEdges)) - 1);
932 face.vertices.resize(3);
933 face.vertices[0] = verts.size();
934 face.vertices[1] = endBase + numBaseEdges - 1;
935 face.vertices[2] = endBase;
938 faces.push_back(
face);
939 face.vertices[1] =
face.vertices[2];
941 }
while (
face.vertices[2] < endBase + numBaseEdges);
942 verts.push_back(
TPoint3D(0, 0, verts[endBase].
z - apexHeight));
949 numBaseEdges, basePositionInfo.rbegin()->second * semi,
950 baseRadius, edgeLength,
false,
true, initialBase, verts,
957 numBaseEdges, basePositionInfo[0].second * semi, baseRadius,
958 edgeLength,
false,
false, endBase, verts, faces);
964 numBaseEdges, basePositionInfo.rbegin()->second * semi,
965 baseRadius, edgeLength,
true,
true, initialBase, verts,
972 numBaseEdges, basePositionInfo[0].second * semi, baseRadius,
973 edgeLength,
true,
false, endBase, verts, faces);
977 face.vertices.resize(4);
978 for (
size_t i = 0; i < numBaseEdges; i++)
980 size_t ii = (i + 1) % numBaseEdges;
981 face.vertices[0] = initialBase + i;
982 face.vertices[1] = endBase + i;
983 face.vertices[2] = endBase + ii;
984 face.vertices[3] = initialBase + ii;
985 faces.push_back(
face);
991 face.vertices.resize(3);
992 face.vertices[0] = initialBase;
993 face.vertices[1] = endBase;
994 face.vertices[2] = initialBase + 1;
995 bool nextIsEnd =
true;
997 size_t nextInitial = 2;
998 for (
size_t i = 0; i < numBaseEdges << 1; i++)
1000 faces.push_back(
face);
1001 face.vertices[0] =
face.vertices[1];
1002 face.vertices[1] =
face.vertices[2];
1005 face.vertices[2] = endBase + nextEnd;
1006 nextEnd = (nextEnd + 1) % numBaseEdges;
1010 face.vertices[2] = initialBase + nextInitial;
1011 nextInitial = (nextInitial + 1) % numBaseEdges;
1013 nextIsEnd = !nextIsEnd;
1021 basePositionInfo.rbegin()->second * semi, baseRadius,
false,
1022 true, initialBase, verts, faces);
1028 basePositionInfo[0].second * semi, baseRadius,
false,
false,
1029 endBase, verts, faces);
1035 basePositionInfo.rbegin()->second * semi, baseRadius,
true,
1036 true, initialBase, verts, faces);
1042 basePositionInfo[0].second * semi, baseRadius,
true,
false,
1043 endBase, verts, faces);
1046 throw std::logic_error(
"Internal error");
1048 initialBase = endBase;
1049 endBase += numBaseEdges;
1060 #if MRPT_HAS_OPENGL_GLUT
1070 it !=
mEdges.end(); ++it)
1088 it !=
mFaces.end(); ++it)
1091 glNormal3f(it->normal[0], it->normal[1], it->normal[2]);
1093 it2 != it->vertices.end(); ++it2)
1113 lengths.resize(
mEdges.size());
1116 it !=
mEdges.end(); ++it, ++it2)
1122 areas.resize(
mFaces.size());
1125 it !=
mFaces.end(); ++it, ++it2)
1141 vector<double> areas(
mFaces.size());
1145 it !=
mFaces.end(); ++it, ++itP, ++itA)
1146 res += abs(itP->plane.distance(center)) * (*itA);
1155 for (
size_t i = 0; i < N; i++) vec[i] =
tempPolygons[i].poly;
1159 std::vector<math::TPolygon3D>& vec)
const
1161 vec.resize(
mFaces.size());
1163 vector<TPoint3D> nVerts;
1174 vector<TPolygon3D> polys, polysTMP, polys2;
1176 polys2.reserve(polys.size());
1178 it != polys.end(); ++it)
1180 polys2.insert(polys2.end(), polysTMP.begin(), polysTMP.end());
1182 polys2.push_back(*it);
1188 it !=
mFaces.end(); ++it)
1191 throw std::logic_error(
"Bad face specification");
1199 if (N == 0)
throw new std::logic_error(
"There are no vertices");
1200 center.
x = center.
y = center.
z = 0;
1324 size_t NV =
mFaces.size();
1325 size_t NE =
mEdges.size();
1327 vector<TPlane> planes(NF);
1328 for (
size_t i = 0; i < NF; i++)
1338 vector<TPoint3D> vertices(NV);
1339 for (
size_t i = 0; i < NV; i++)
1341 for (
size_t j = 0; j < NF; j++) incidence(i, j) =
false;
1342 vector<const TPlane*> fPls;
1343 fPls.reserve(
mFaces[i].vertices.size());
1345 it !=
mFaces[i].vertices.end(); ++it)
1347 incidence(i, *it) =
true;
1348 fPls.push_back(&planes[*it]);
1351 throw std::logic_error(
"Dual polyhedron cannot be found");
1353 vector<TPolyhedronFace> faces(NF);
1354 for (
size_t i = 0; i < NF; i++)
1355 for (
size_t j = 0; j < NV; j++)
1356 if (incidence(j, i)) faces[i].vertices.push_back(j);
1360 for (
size_t i = 0; i < NE; i++)
1361 for (
size_t j = 0; j < NV; j++)
1364 it != faces.end(); ++it)
1366 vector<uint32_t>&
face = it->vertices;
1367 if (
face.size() <= 3)
continue;
1374 for (
size_t i = 0; i < NE; i++)
1390 return mrpt::make_aligned_shared<CPolyhedron>(vertices, faces);
1398 else if (factor < 1)
1400 size_t NE =
mEdges.size();
1402 size_t NF =
mFaces.size();
1403 vector<TPoint3D> vertices(NE << 1);
1404 vector<TPolyhedronFace> faces(NV + NF);
1405 for (
size_t i = 0; i < NE; i++)
1411 for (
size_t j = 0; j < 3; j++)
1413 double d = (p2[j] - p1[j]) * factor / 2;
1417 faces[
mEdges[i].v1].vertices.push_back(i + i);
1418 faces[
mEdges[i].v2].vertices.push_back(i + i + 1);
1420 for (
size_t i = 0; i < NV; i++)
1422 vector<uint32_t>& f = faces[i].vertices;
1423 size_t sf = f.size();
1424 if (sf == 3)
continue;
1425 for (
size_t j = 1; j < sf - 1; j++)
1431 if (!((e1.
v1 == i || e1.
v2 == i) &&
1432 (e2.
v1 == i || e2.
v2 == i)))
1436 (e2.
v1 == i) ? e2.
v2 : e2.
v1))
1439 f.erase(f.begin() + j);
1444 for (
size_t i = 0; i < NF; i++)
1446 vector<uint32_t>& f = faces[i + NV].vertices;
1447 const vector<uint32_t>& cf =
mFaces[i].vertices;
1448 size_t hmV = cf.size();
1449 f.reserve(hmV << 1);
1450 for (
size_t j = 0; j < hmV; j++)
1455 f.push_back(where << 1);
1456 f.push_back((where << 1) + 1);
1460 f.push_back((where << 1) + 1);
1461 f.push_back(where << 1);
1465 return mrpt::make_aligned_shared<CPolyhedron>(vertices, faces);
1467 else if (factor == 1)
1469 size_t NE =
mEdges.size();
1471 size_t NF =
mFaces.size();
1472 vector<TPoint3D> vertices(NE);
1473 vector<TPolyhedronFace> faces(NV + NF);
1474 for (
size_t i = 0; i < NE; i++)
1479 for (
size_t j = 0; j < 3; j++)
dst[j] = (p1[j] + p2[j]) / 2;
1480 faces[
mEdges[i].v1].vertices.push_back(i);
1481 faces[
mEdges[i].v2].vertices.push_back(i);
1483 for (
size_t i = 0; i < NV; i++)
1485 vector<uint32_t>& f = faces[i].vertices;
1486 size_t sf = f.size();
1487 if (sf == 3)
continue;
1488 for (
size_t j = 1; j < sf - 1; j++)
1494 if (!((e1.
v1 == i || e1.
v2 == i) &&
1495 (e2.
v1 == 1 || e2.
v2 == i)))
1499 (e2.
v1 == i) ? e2.
v2 : e2.
v1))
1502 f.erase(f.begin() + j);
1507 for (
size_t i = 0; i < NF; i++)
1509 vector<uint32_t>& f = faces[i + NV].vertices;
1510 const vector<uint32_t>& cf =
mFaces[i].vertices;
1511 size_t hmV = cf.size();
1513 for (
size_t j = 0; j < hmV; j++)
1520 return mrpt::make_aligned_shared<CPolyhedron>(vertices, faces);
1530 else if (factor == 0)
1533 size_t NE =
mEdges.size();
1534 size_t NF =
mFaces.size();
1535 vector<TPolygon3D> origFaces(NF);
1539 vector<TPoint3D> polyCenters(NF);
1540 vector<TPoint3D> polyNewCenters(NF);
1542 for (
size_t i = 0; i < NF; i++)
1544 origFaces[i].getCenter(polyCenters[i]);
1545 polyCenters[i] -= cnt;
1546 polyNewCenters[i] = polyCenters[i];
1547 polyNewCenters[i] *= (1 + factor);
1548 polyNewCenters[i] += cnt;
1549 NNV += origFaces[i].size();
1551 vector<TPoint3D> vertices(NNV);
1552 vector<TPolyhedronFace> faces(NF + NV + NE);
1554 for (
size_t i = 0; i < NF; i++)
1556 const TPoint3D& oC = polyCenters[i];
1557 const TPoint3D& nC = polyNewCenters[i];
1559 vector<uint32_t>& f = faces[i].vertices;
1560 size_t oPS = oP.size();
1561 for (
size_t j = 0; j < oPS; j++)
1563 vertices[j + ind] = nC + (oP[j] - oC);
1564 f.push_back(j + ind);
1565 size_t curr =
mFaces[i].vertices[j];
1566 faces[NF + curr].vertices.push_back(j + ind);
1569 mEdges, curr,
mFaces[i].vertices[(j + oPS - 1) % oPS], edge);
1570 faces[NF + NV + edge].vertices.push_back(j + ind);
1572 mEdges, curr,
mFaces[i].vertices[(j + 1) % oPS], edge);
1573 faces[NF + NV + edge].vertices.push_back(j + ind);
1578 edgeBegin = faces.begin() + NF + NV,
1581 it != faces.begin() + NF + NV; ++it)
1583 vector<uint32_t>& f = it->vertices;
1584 if (f.size() == 3)
continue;
1585 for (
size_t i = 1; i < f.size() - 1; i++)
1592 f.erase(f.begin() + i);
1597 it != faces.end(); ++it)
1599 vector<uint32_t>& f =
1601 for (
size_t i = 1; i < 3; i++)
1608 f.erase(f.begin() + i);
1612 return mrpt::make_aligned_shared<CPolyhedron>(vertices, faces);
1618 size_t NF =
mFaces.size();
1619 vector<TPoint3D> vertices(NV + NF);
1623 it !=
mFaces.end(); ++it)
1624 tnf += it->vertices.size();
1625 vector<TPolyhedronFace> faces(tnf);
1634 for (
size_t i = 0; i < NF; i++)
1636 TPoint3D& vertex = vertices[NV + i];
1637 const vector<uint32_t>&
face =
mFaces[i].vertices;
1638 size_t N =
face.size();
1645 for (
size_t j = 0; j < 3; j++)
1648 for (
size_t j = 0; j < 3; j++)
1651 for (
size_t j = 0; j < N; j++)
1655 faces[iF + j] = fTmp;
1665 size_t NF =
mFaces.size();
1669 it !=
mFaces.end(); ++it)
1670 if (it->vertices.size() == numVertices)
1678 vector<TPoint3D> vertices(tnv);
1680 vector<TPolyhedronFace> faces(tnf);
1690 for (
size_t i = 0; i < NF; i++)
1692 const vector<uint32_t>&
face =
mFaces[i].vertices;
1693 size_t N =
face.size();
1694 if (N != numVertices)
1696 faces[iF].vertices =
face;
1701 for (
size_t j = 0; j < numVertices; j++) tmp[j] =
mVertices[
face[j]];
1706 for (
size_t j = 0; j < 3; j++)
1709 for (
size_t j = 0; j < 3; j++)
1712 for (
size_t j = 0; j < N; j++)
1716 faces[iF + j] = fTmp;
1727 size_t NF =
mFaces.size();
1728 vector<TPoint3D> vertices(NV + NF);
1732 it !=
mFaces.end(); ++it)
1733 tnf += it->vertices.size();
1734 vector<TPolyhedronFace> faces(tnf);
1743 for (
size_t i = 0; i < NF; i++)
1745 TPoint3D& vertex = vertices[NV + i];
1746 const vector<uint32_t>&
face =
mFaces[i].vertices;
1747 size_t N =
face.size();
1755 for (
size_t j = 0; j < 3; j++)
1758 for (
size_t j = 0; j < 3; j++)
1761 for (
size_t j = 0; j < N; j++)
1765 faces[iF + j] = fTmp;
1775 size_t NF =
mFaces.size();
1779 it !=
mFaces.end(); ++it)
1780 if (it->vertices.size() == numVertices)
1788 vector<TPoint3D> vertices(tnv);
1790 vector<TPolyhedronFace> faces(tnf);
1800 for (
size_t i = 0; i < NF; i++)
1802 const vector<uint32_t>&
face =
mFaces[i].vertices;
1803 size_t N =
face.size();
1804 if (N != numVertices)
1806 faces[iF].vertices =
face;
1811 for (
size_t j = 0; j < numVertices; j++) tmp[j] =
mVertices[
face[j]];
1817 for (
size_t j = 0; j < 3; j++)
1820 for (
size_t j = 0; j < 3; j++)
1823 for (
size_t j = 0; j < N; j++)
1827 faces[iF + j] = fTmp;
1838 double c = cos(angle),
s = sin(angle);
1844 it->x = A *
c - B *
s;
1845 it->y = B *
c + A *
s;
1854 throw std::logic_error(
"Factor must be a strictly positive number");
1865 uint32_t numBaseEdges,
double baseRadius)
1867 vector<TPoint2D> base(numBaseEdges);
1868 for (
size_t i = 0; i < numBaseEdges; i++)
1870 double ang = 2 *
M_PI * i / numBaseEdges;
1871 base[i].x = baseRadius * cos(ang);
1872 base[i].y = baseRadius * sin(ang);
1878 uint32_t numBaseEdges,
double baseRadius)
1880 vector<TPoint2D> base(numBaseEdges);
1881 double shift =
M_PI / numBaseEdges;
1882 for (
size_t i = 0; i < numBaseEdges; i++)
1884 double ang = shift + 2 *
M_PI * i / numBaseEdges;
1885 base[i].x = baseRadius * cos(ang);
1886 base[i].y = baseRadius * sin(ang);
1893 vector<TPoint3D>& vec)
1895 for (
size_t i = 0; i < numBaseEdges; i++)
1897 double ang = 2 *
M_PI * i / numBaseEdges;
1904 uint32_t numBaseEdges,
double baseRadius,
double height,
double shift,
1905 vector<TPoint3D>& vec)
1907 for (
size_t i = 0; i < numBaseEdges; i++)
1909 double ang = 2 *
M_PI * i / numBaseEdges + shift;
1926 size_t N = doCheck ? f.
vertices.size() : 3;
1930 if (!poly.
getPlane(tmp))
return false;
1934 if (tmp.evaluatePoint(
c) > 0)
1935 for (
size_t i = 0; i < 3; i++) f.
normal[i] = -f.
normal[i];
1959 const vector<TPoint3D>& vertices,
const vector<TPolyhedronFace>& faces)
1961 size_t N = vertices.size();
1962 if (vertices.size() > 0)
1964 it != vertices.end() - 1; ++it)
1966 it2 != vertices.end(); ++it2)
1967 if (*it == *it2)
return false;
1969 it != faces.end(); ++it)
1971 const vector<uint32_t>& e = it->vertices;
1974 if (*it2 >= N)
return false;
1983 it !=
mEdges.end(); ++it)
1984 if (it->v1 == vertex || it->v2 == vertex)
res++;
1992 it !=
mFaces.end(); ++it)
1993 if (
find(it->vertices.begin(), it->vertices.end(), vertex) !=
2009 out << o.
v1 << o.
v2;
2044 throw std::logic_error(
"Inconsistent data read from stream");
2046 it !=
mFaces.end(); ++it)
2049 throw std::logic_error(
"Bad face specification");
2117 it != tetra->mVertices.end(); ++it)
2118 it->z -= radius / 3;
2124 double r = radius / sqrt(3.0);
2137 double ang =
M_PI / 5;
2138 double s2 = 4 *
square(sin(ang));
2139 double prop = sqrt(s2 - 1) + sqrt(s2 - 2 + 2 * cos(ang)) / 2;
2153 ->truncate(2 - sqrt(2.0));
2160 double radius,
bool type)
2164 type ?
"C-PRC+" :
"GC-PRC+", 3);
2169 10, radius,
type ?
"GR-R+" :
"R-R+", 1);
2174 ->truncate(1 - sqrt(0.2));
2179 ->truncate(2.0 / 3.0);
2184 ->cantellate(1.5 * (sqrt(5.0) - 1));
2237 const vector<TPoint2D>& baseVertices,
double height,
double ratio)
2242 const vector<TPoint2D>& baseVertices,
double height)
2264 uint32_t numBaseEdges,
double baseRadius,
double height1,
double height2)
2267 generateBase(numBaseEdges, baseRadius), height1, height2);
2270 uint32_t numBaseEdges,
double baseRadius)
2275 uint32_t numBaseEdges,
double baseRadius)
2280 uint32_t numBaseEdges,
double baseRadius,
double height,
double ratio)
2286 uint32_t numBaseEdges,
double baseRadius,
double height,
double ratio)
2289 numBaseEdges, baseRadius,
height, ratio);
2292 uint32_t numBaseEdges,
double baseRadius,
double height1,
double ratio1,
2293 double height2,
double ratio2)
2296 generateBase(numBaseEdges, baseRadius), height1, ratio1, height2,
2300 uint32_t numBaseEdges,
double edgeLength)
2303 numBaseEdges, edgeLength / (2 * sin(
M_PI / numBaseEdges)),
"C+");
2317 const vector<TPoint3D>& vertices,
const vector<TPolyhedronFace>& faces)