45 bool getVerticesAndFaces(
const vector<math::TPolygon3D> &polys,vector<TPoint3D> &vertices,vector<CPolyhedron::TPolyhedronFace> &faces) {
46 vertices.reserve(4*polys.size());
47 faces.reserve(polys.size());
50 if (N<3)
return false;
53 for (
size_t i=0;i<N;i++) {
55 if (it2==vertices.end()) {
57 vertices.push_back((*it)[i]);
58 }
else f.
vertices[i]=it2-vertices.begin();
66 INF_NO_BODY=-2,
SUP_NO_BODY=-1,
UPWARDS_PYRAMID=0,
DOWNWARDS_PYRAMID=1,
UPWARDS_CUPOLA=2,
DOWNWARDS_CUPOLA=3,
ROTATED_UPWARDS_CUPOLA=4,
ROTATED_DOWNWARDS_CUPOLA=5,
PRISM=6,
ANTIPRISM=7,
UPWARDS_ROTUNDA=8,
DOWNWARDS_ROTUNDA=9,
ROTATED_UPWARDS_ROTUNDA=10,
ROTATED_DOWNWARDS_ROTUNDA=11
79 if (numBaseEdges&1)
return false;
80 if (i==N-1)
return false;
83 if (i!=N-1)
return false;
88 if (parts.size()>0)
return false;
94 if (numBaseEdges!=10)
return false;
95 if (i==N-1)
return false;
98 if (i!=N-1)
return false;
103 if (parts.size()>0)
return false;
109 if (i==N-1)
return false;
116 if (i==N-1)
return false;
120 if (numBaseEdges>5)
return false;
121 if (i!=N-1)
return false;
126 if (numBaseEdges>5)
return false;
127 if (i!=1)
return false;
131 if (parts.size()>0&&(*parts.rbegin()==
PRISM))
return false;
133 parts.push_back(
PRISM);
144 if (parts.size()==0)
return false;
152 else if (j<
PRISM)
return numBaseEdges>>1;
156 void insertCupola(
size_t numBaseEdges,
double angleShift,
double baseRadius,
double edgeLength,
bool isRotated,
bool isUpwards,
size_t base,vector<TPoint3D> &verts,vector<CPolyhedron::TPolyhedronFace> &faces) {
157 size_t edges2=numBaseEdges>>1;
158 double minorRadius=baseRadius*sin(
M_PI/numBaseEdges)/sin(
M_PI/edges2);
162 double h=sqrt(
square(edgeLength)-
square(baseRadius*cos(
M_PI/numBaseEdges)-minorRadius*cos(
M_PI/edges2)));
163 double height=verts[base].z+(isUpwards?h:-h);
164 angleShift+=
M_PI/edges2+(isRotated?-
M_PI/numBaseEdges:
M_PI/numBaseEdges);
165 size_t minorBase=verts.size();
166 for (
size_t i=0;i<edges2;i++) {
167 double ang=angleShift+2*
M_PI*i/edges2;
168 verts.push_back(
TPoint3D(minorRadius*cos(ang),minorRadius*sin(ang),
height));
174 size_t iq=isRotated?1:2,it=0;
175 for (
size_t i=0;i<edges2;i++) {
177 size_t iiq=(iq+1)%numBaseEdges+base;
178 size_t iiiq=(iiq+1)%numBaseEdges+base;
179 size_t iit=(it+1)%edges2+minorBase;
187 iq=(iq+2)%numBaseEdges;
189 faces.push_back(tri);
190 faces.push_back(quad);
192 if (edges2>=3) faces.push_back(cBase);
194 void insertRotunda(
double angleShift,
double baseRadius,
bool isRotated,
bool isUpwards,
size_t base,vector<TPoint3D> &verts,vector<CPolyhedron::TPolyhedronFace> &faces) {
195 double R1=baseRadius*sqrt((5.0-sqrt(5.0))/10.0);
196 double R2=baseRadius*sqrt((5.0+sqrt(5.0))/10.0);
197 double baseHeight=verts[base].z;
200 if (isRotated) angleShift+=
M_PI/5;
201 for (
size_t i=0;i<5;i++) {
202 double a=(i+i+1)*
M_PI/5+angleShift;
203 double b=(i+i)*
M_PI/5+angleShift;
204 double ca=cos(
a),sa=sin(
a),cb=cos(
b),sb=sin(
b);
207 p1[i].
z=baseHeight+(isUpwards?R2:-R2);
210 p2[i].
z=baseHeight+(isUpwards?R1:-R1);
212 size_t newBase=verts.size();
213 for (
size_t i=0;i<5;i++) verts.push_back(p1[i]);
214 for (
size_t i=0;i<5;i++) verts.push_back(p2[i]);
217 g.vertices.resize(5);
218 size_t baseStart=isRotated?2:1;
219 for (
size_t i=0;i<5;i++) {
226 f.
vertices[1]=((i+i+baseStart)%10)+base;
227 f.
vertices[2]=((i+i+9+baseStart)%10)+base;
229 g.vertices[0]=newBase+(ii%5)+5;
230 g.vertices[1]=newBase+i;
231 g.vertices[2]=newBase+i+5;
232 g.vertices[3]=(i+i+baseStart)%10+base;
233 g.vertices[4]=(i+i+baseStart+1)%10+base;
236 for (
size_t i=0;i<5;i++)
g.vertices[i]=i+newBase;
243 else if (j<
PRISM)
return numBaseEdges+ ((numBaseEdges>=6)?1:0);
244 else if (j==
PRISM)
return numBaseEdges;
245 else if (j==
ANTIPRISM)
return numBaseEdges<<1;
256 if (planes.size()<3)
return false;
261 for (
size_t i=1;i<planes.size();i++)
switch (o) {
264 if (
obj.getPlane(pl)) o=0;
265 else if (
obj.getLine(l)) o=1;
266 else if (
obj.getPoint(pnt)) o=2;
271 if (
obj.getLine(l)) o=1;
272 else if (
obj.getPoint(pnt)) o=2;
276 if (!planes[i]->contains(pnt))
return false;
286 const vector<uint32_t> &f=it->vertices;
289 if (*it2==
v1) hmf|=1;
290 else if (*it2==
v2) hmf|=2;
291 else if (*it2==
v3) hmf|=4;
293 if (hmf==7)
return true;
298 for (where=0;where<es.size();where++) {
300 if (e.
v1==
v1&&e.
v2==
v2)
return true;
301 else if (e.
v1==
v2&&e.
v2==
v1)
return false;
303 throw std::logic_error(
"Internal error. Edge not found");
307 const vector<uint32_t> &f=it->vertices;
310 else if (*it2==
v2)
res|=2;
311 if (
res==3)
return true;
317 if (N>5||N<3)
throw std::logic_error(
"Faces must have exactly 3, 4 or 5 vertices.");
340 double CPolyhedron::TPolyhedronFace::area(
const vector<TPoint3D> &vs)
const {
342 size_t N=vertices.size();
343 vector<SegmentVector> d(N-1);
344 for (
size_t i=1;i<N;i++) {
346 for (
size_t j=0;j<3;j++) {
347 d[i-1][j]=vs[vertices[i]][j]-vs[vertices[0]][j];
348 d[i-1].mod+=
square(d[i-1][j]);
350 d[i-1].mod=sqrt(d[i-1].mod);
353 for (
size_t i=1;i<N-1;i++)
res+=sqrt(
square(d[i-1].mod*d[i].mod)-
square(dotProduct<3,double>(d[i-1],d[i])));
357 void CPolyhedron::TPolyhedronFace::getCenter(
const vector<TPoint3D> &vrts,
TPoint3D &
p)
const {
364 size_t N=vertices.size();
370 CPolyhedronPtr CPolyhedron::Create(
const std::vector<math::TPolygon3D> &polys) {
371 vector<TPoint3D> vertices(0);
372 vector<TPolyhedronFace> faces;
374 else return CreateEmpty();
377 CPolyhedronPtr CPolyhedron::CreateCubicPrism(
double x1,
double x2,
double y1,
double y2,
double z1,
double z2) {
378 vector<TPoint3D> verts;
379 vector<TPolyhedronFace> faces;
380 for (
int i=0;i<8;i++) verts.push_back(
TPoint3D((i&1)?x2:x1,(i&2)?y2:y1,(i&4)?z2:z1));
381 static uint32_t faceVertices[]={0,1,5,4, 2,3,7,6, 0,2,6,4, 1,3,7,5, 0,1,3,2, 4,5,7,6};
388 return CreateNoCheck(verts,faces);
391 CPolyhedronPtr CPolyhedron::CreatePyramid(
const vector<TPoint2D> &baseVertices,
double height) {
393 if (baseVertices.size()<3)
throw std::logic_error(
"Not enought vertices");
394 vector<TPoint3D> verts;
395 vector<TPolyhedronFace> faces;
402 g.vertices.push_back(1);
408 g.vertices.push_back(i);
411 return CreateNoCheck(verts,faces);
414 CPolyhedronPtr CPolyhedron::CreateDoublePyramid(
const vector<TPoint2D> &baseVertices,
double height1,
double height2) {
416 if (N<3)
throw std::logic_error(
"Not enought vertices");
417 vector<TPoint3D> verts;
419 vector<TPolyhedronFace> faces;
421 verts.push_back(
TPoint3D(0,0,height1));
423 verts.push_back(
TPoint3D(0,0,-height2));
426 g.vertices.resize(3);
438 return CreateNoCheck(verts,faces);
441 CPolyhedronPtr CPolyhedron::CreateTruncatedPyramid(
const vector<TPoint2D> &baseVertices,
double height,
double ratio) {
443 if (
n<3)
throw std::logic_error(
"Not enough vertices");
444 vector<TPoint3D> verts(
n+
n);
445 vector<TPolyhedronFace> faces(
n+2);
448 g.vertices.resize(
n);
451 verts[i]=
TPoint3D(baseVertices[i].
x,baseVertices[i].
y,0);
464 return CreateNoCheck(verts,faces);
467 CPolyhedronPtr CPolyhedron::CreateCustomAntiprism(
const vector<TPoint2D> &bottomBase,
const vector<TPoint2D> &topBase,
const double height) {
469 if (
n<3)
throw std::logic_error(
"Not enough vertices");
470 if (
n!=topBase.size())
throw std::logic_error(
"Bases' number of vertices do not match");
471 vector<TPoint3D> verts(
n+
n);
472 vector<TPolyhedronFace> faces(
n+
n+2);
475 g.vertices.resize(
n);
478 verts[i]=
TPoint3D(bottomBase[i].
x,bottomBase[i].
y,0);
494 return CreateNoCheck(verts,faces);
498 vector<TPoint3D> verts(8);
499 vector<TPolyhedronFace> faces(6);
502 if (i&1) verts[i]=verts[i]+
v1;
503 if (i&2) verts[i]=verts[i]+
v2;
504 if (i&4) verts[i]=verts[i]+
v3;
525 faces[i+3].vertices.resize(4);
526 for (
uint32_t j=0;j<4;j++) faces[i+3].vertices[j]=faces[i].vertices[j]+valueAdd;
528 return CreateNoCheck(verts,faces);
531 CPolyhedronPtr CPolyhedron::CreateBifrustum(
const vector<TPoint2D> &baseVertices,
double height1,
double ratio1,
double height2,
double ratio2) {
533 size_t N=baseVertices.size();
534 vector<TPoint3D> verts(3*N);
536 for (
size_t i=0;i<N;i++) {
537 double x=baseVertices[i].x;
538 double y=baseVertices[i].y;
542 verts[i+N].x=
x*ratio1;
543 verts[i+N].y=
y*ratio1;
544 verts[i+N].z=height1;
545 verts[i+N2].x=
x*ratio2;
546 verts[i+N2].y=
y*ratio2;
547 verts[i+N2].z=-height2;
549 vector<TPolyhedronFace> faces(N2+2);
552 g.vertices.resize(N);
554 for (
size_t i=0;i<N;i++) {
569 return CreateNoCheck(verts,faces);
572 CPolyhedronPtr CPolyhedron::CreateTrapezohedron(
uint32_t numBaseEdges,
double baseRadius,
double basesDistance) {
573 if (numBaseEdges<3)
throw std::logic_error(
"Not enough vertices");
574 if (basesDistance==0||baseRadius==0)
return CreateEmpty();
575 size_t numBaseEdges2=numBaseEdges<<1;
576 vector<TPoint3D> verts(numBaseEdges2+2);
577 double space=2*
M_PI/numBaseEdges;
578 double shift=space/2;
579 double height1=basesDistance/2;
580 double cospii=cos(
M_PI/numBaseEdges);
581 double height2=height1*(cospii+1)/(1-cospii);
582 for (
size_t i=0;i<numBaseEdges;i++) {
584 double ang2=ang+shift;
585 size_t ii=i+numBaseEdges;
586 verts[i].x=baseRadius*cos(ang);
587 verts[i].y=baseRadius*sin(ang);
589 verts[ii].x=baseRadius*cos(ang2);
590 verts[ii].y=baseRadius*sin(ang2);
593 verts[numBaseEdges2].x=0;
594 verts[numBaseEdges2].y=0;
595 verts[numBaseEdges2].z=-height2;
596 verts[numBaseEdges2+1].x=0;
597 verts[numBaseEdges2+1].y=0;
598 verts[numBaseEdges2+1].z=height2;
599 vector<TPolyhedronFace> faces(numBaseEdges2);
602 g.vertices.resize(4);
604 g.vertices[3]=numBaseEdges2+1;
605 for (
size_t i=0;i<numBaseEdges;i++) {
606 size_t ii=(i+1)%numBaseEdges;
607 size_t i2=i+numBaseEdges;
613 g.vertices[2]=ii+numBaseEdges;
615 faces[i+numBaseEdges]=
g;
617 return CreateNoCheck(verts,faces);
621 if (baseRadius==0)
return CreateEmpty();
622 if (numBaseEdges<3)
throw std::logic_error(
"Not enough vertices");
623 vector<JohnsonBodyPart> parts;
626 size_t nParts=parts.size();
627 double edgeLength=2*baseRadius*sin(
M_PI/numBaseEdges);
628 double antiPrismHeight=sqrt(
square(edgeLength)-
square(baseRadius)*(2-2*cos(
M_PI/numBaseEdges)));
632 for (
size_t i=0;i<nParts;i++) nFaces+=
additionalFaces(parts[i],numBaseEdges);
633 vector<TPoint3D> verts;
634 verts.reserve(nVerts);
635 vector<TPolyhedronFace> faces;
636 faces.reserve(nFaces);
639 vector<pair<double,size_t> > basePositionInfo(nParts-1);
640 for (
size_t i=0;i<nParts-1;i++) {
641 if (parts[i]==
PRISM) h=edgeLength;
646 basePositionInfo[i]=make_pair(mHeight+=h,shifts);
649 double semi=
M_PI/numBaseEdges;
651 for (vector<pair<double,size_t> >::
const_iterator it=basePositionInfo.begin();it!=basePositionInfo.end();++it) generateShiftedBase(numBaseEdges,baseRadius,it->first-mHeight,semi*it->second,verts);
652 size_t initialBase=0,endBase=0;
654 face.vertices.reserve(numBaseEdges);
656 for (
size_t i=0;i<nParts;i++) {
660 face.vertices.resize(numBaseEdges);
661 for (
size_t i=0;i<numBaseEdges;i++)
face.vertices[i]=endBase+i;
662 faces.push_back(
face);
666 face.vertices.resize(numBaseEdges);
667 for (
size_t i=0;i<numBaseEdges;i++)
face.vertices[i]=initialBase+i;
668 faces.push_back(
face);
672 double apexHeight=baseRadius*sqrt(4*
square(sin(
M_PI/numBaseEdges))-1);
673 face.vertices.resize(3);
674 face.vertices[0]=verts.size();
675 face.vertices[1]=initialBase+numBaseEdges-1;
676 face.vertices[2]=initialBase;
678 faces.push_back(
face);
681 }
while (
face.vertices[2]<initialBase+numBaseEdges);
682 verts.push_back(
TPoint3D(0,0,verts[initialBase].
z+apexHeight));
686 double apexHeight=baseRadius*sqrt(4*
square(sin(
M_PI/numBaseEdges))-1);
687 face.vertices.resize(3);
688 face.vertices[0]=verts.size();
689 face.vertices[1]=endBase+numBaseEdges-1;
690 face.vertices[2]=endBase;
692 faces.push_back(
face);
695 }
while (
face.vertices[2]<endBase+numBaseEdges);
696 verts.push_back(
TPoint3D(0,0,verts[endBase].
z-apexHeight));
700 insertCupola(numBaseEdges,basePositionInfo.rbegin()->second*semi,baseRadius,edgeLength,
false,
true,initialBase,verts,faces);
704 insertCupola(numBaseEdges,basePositionInfo[0].second*semi,baseRadius,edgeLength,
false,
false,endBase,verts,faces);
708 insertCupola(numBaseEdges,basePositionInfo.rbegin()->second*semi,baseRadius,edgeLength,
true,
true,initialBase,verts,faces);
712 insertCupola(numBaseEdges,basePositionInfo[0].second*semi,baseRadius,edgeLength,
true,
false,endBase,verts,faces);
716 face.vertices.resize(4);
717 for (
size_t i=0;i<numBaseEdges;i++) {
718 size_t ii=(i+1)%numBaseEdges;
719 face.vertices[0]=initialBase+i;
720 face.vertices[1]=endBase+i;
721 face.vertices[2]=endBase+ii;
722 face.vertices[3]=initialBase+ii;
723 faces.push_back(
face);
728 face.vertices.resize(3);
729 face.vertices[0]=initialBase;
730 face.vertices[1]=endBase;
731 face.vertices[2]=initialBase+1;
734 size_t nextInitial=2;
735 for (
size_t i=0;i<numBaseEdges<<1;i++) {
736 faces.push_back(
face);
740 face.vertices[2]=endBase+nextEnd;
741 nextEnd=(nextEnd+1)%numBaseEdges;
743 face.vertices[2]=initialBase+nextInitial;
744 nextInitial=(nextInitial+1)%numBaseEdges;
746 nextIsEnd=!nextIsEnd;
751 insertRotunda(basePositionInfo.rbegin()->second*semi,baseRadius,
false,
true,initialBase,verts,faces);
755 insertRotunda(basePositionInfo[0].second*semi,baseRadius,
false,
false,endBase,verts,faces);
759 insertRotunda(basePositionInfo.rbegin()->second*semi,baseRadius,
true,
true,initialBase,verts,faces);
763 insertRotunda(basePositionInfo[0].second*semi,baseRadius,
true,
false,endBase,verts,faces);
766 throw std::logic_error(
"Internal error");
769 endBase+=numBaseEdges;
771 return CreateNoCheck(verts,faces);
778 void CPolyhedron::render_dl()
const {
779 #if MRPT_HAS_OPENGL_GLUT 785 glColor4ub(m_color.R,m_color.G,m_color.B,m_color.A);
800 glColor4ub(m_color.R,m_color.G,m_color.B,m_color.A);
803 glNormal3f(it->normal[0],it->normal[1],it->normal[2]);
817 if (!polygonsUpToDate) updatePolygons();
821 void CPolyhedron::getEdgesLength(std::vector<double> &lengths)
const {
822 lengths.resize(mEdges.size());
827 void CPolyhedron::getFacesArea(std::vector<double> &areas)
const {
828 areas.resize(mFaces.size());
833 double CPolyhedron::getVolume()
const {
839 if (!polygonsUpToDate) updatePolygons();
841 vector<double> areas(mFaces.size());
848 void CPolyhedron::getSetOfPolygons(std::vector<math::TPolygon3D> &vec)
const {
849 if (!polygonsUpToDate) updatePolygons();
850 size_t N=tempPolygons.size();
852 for (
size_t i=0;i<N;i++) vec[i]=tempPolygons[i].poly;
855 void CPolyhedron::getSetOfPolygonsAbsolute(std::vector<math::TPolygon3D> &vec)
const {
856 vec.resize(mFaces.size());
857 size_t N=mVertices.size();
858 vector<TPoint3D> nVerts;
861 for (
size_t i=0;i<N;i++) pose.
composePoint(mVertices[i],nVerts[i]);
865 void CPolyhedron::makeConvexPolygons() {
866 vector<TPolygon3D> polys,polysTMP,polys2;
867 getSetOfPolygons(polys);
868 polys2.reserve(polys.size());
870 else polys2.push_back(*it);
876 if (!setNormal(*it,
false))
throw std::logic_error(
"Bad face specification");
881 void CPolyhedron::getCenter(
TPoint3D ¢er)
const {
882 size_t N=mVertices.size();
883 if (N==0)
throw new std::logic_error(
"There are no vertices");
884 center.
x=center.
y=center.
z=0;
895 CPolyhedronPtr CPolyhedron::CreateRandomPolyhedron(
double radius) {
897 case 0:
return CreateTetrahedron(radius);
898 case 1:
return CreateHexahedron(radius);
899 case 2:
return CreateOctahedron(radius);
900 case 3:
return CreateDodecahedron(radius);
901 case 4:
return CreateIcosahedron(radius);
902 case 5:
return CreateTruncatedTetrahedron(radius);
903 case 6:
return CreateTruncatedHexahedron(radius);
904 case 7:
return CreateTruncatedOctahedron(radius);
905 case 8:
return CreateTruncatedDodecahedron(radius);
906 case 9:
return CreateTruncatedIcosahedron(radius);
907 case 10:
return CreateCuboctahedron(radius);
908 case 11:
return CreateRhombicuboctahedron(radius);
909 case 12:
return CreateIcosidodecahedron(radius);
910 case 13:
return CreateRhombicosidodecahedron(radius);
911 case 14:
return CreateTriakisTetrahedron(radius);
912 case 15:
return CreateTriakisOctahedron(radius);
913 case 16:
return CreateTetrakisHexahedron(radius);
914 case 17:
return CreateTriakisIcosahedron(radius);
915 case 18:
return CreatePentakisDodecahedron(radius);
916 case 19:
return CreateRhombicDodecahedron(radius);
917 case 20:
return CreateDeltoidalIcositetrahedron(radius);
918 case 21:
return CreateRhombicTriacontahedron(radius);
919 case 22:
return CreateDeltoidalHexecontahedron(radius);
926 case 29:
return CreateJohnsonSolidWithConstantBase(10,radius,
"R+");
927 case 30:
return CreateJohnsonSolidWithConstantBase(10,radius,
"R-PRR+");
928 case 31:
return CreateJohnsonSolidWithConstantBase(10,radius,
"R-AR+");
931 default:
return CreateEmpty();
935 CPolyhedronPtr CPolyhedron::getDual()
const {
939 size_t NV=mFaces.size();
940 size_t NE=mEdges.size();
941 size_t NF=mVertices.size();
942 vector<TPlane> planes(NF);
943 for (
size_t i=0;i<NF;i++) {
952 vector<TPoint3D> vertices(NV);
953 for (
size_t i=0;i<NV;i++) {
954 for (
size_t j=0;j<NF;j++) incidence(i,j)=
false;
955 vector<const TPlane *> fPls;
956 fPls.reserve(mFaces[i].vertices.size());
958 incidence(i,*it)=
true;
959 fPls.push_back(&planes[*it]);
961 if (!
getPlanesIntersection(fPls,vertices[i]))
throw std::logic_error(
"Dual polyhedron cannot be found");
963 vector<TPolyhedronFace> faces(NF);
964 for (
size_t i=0;i<NF;i++)
for (
size_t j=0;j<NV;j++)
if (incidence(j,i)) faces[i].vertices.push_back(j);
967 for (
size_t i=0;i<NE;i++)
for (
size_t j=0;j<NV;j++) arrayEF(i,j)=
faceContainsEdge(mFaces[j],mEdges[i]);
969 vector<uint32_t> &
face=it->vertices;
970 if (
face.size()<=3)
continue;
988 return Create(vertices,faces);
991 CPolyhedronPtr CPolyhedron::truncate(
double factor)
const {
992 if (factor<0)
return CreateEmpty();
993 if (factor==0)
return CreateNoCheck(mVertices,mFaces);
995 size_t NE=mEdges.size();
996 size_t NV=mVertices.size();
997 size_t NF=mFaces.size();
998 vector<TPoint3D> vertices(NE<<1);
999 vector<TPolyhedronFace> faces(NV+NF);
1000 for (
size_t i=0;i<NE;i++) {
1001 const TPoint3D &p1=mVertices[mEdges[i].v1];
1002 const TPoint3D &p2=mVertices[mEdges[i].v2];
1005 for (
size_t j=0;j<3;j++) {
1006 double d=(p2[j]-p1[j])*factor/2;
1010 faces[mEdges[i].v1].vertices.push_back(i+i);
1011 faces[mEdges[i].v2].vertices.push_back(i+i+1);
1013 for (
size_t i=0;i<NV;i++) {
1014 vector<uint32_t> &f=faces[i].vertices;
1016 if (sf==3)
continue;
1017 for (
size_t j=1;j<sf-1;j++) {
1024 f.erase(f.begin()+j);
1029 for (
size_t i=0;i<NF;i++) {
1030 vector<uint32_t> &f=faces[i+NV].vertices;
1031 const vector<uint32_t> &cf=mFaces[i].vertices;
1032 size_t hmV=cf.size();
1034 for (
size_t j=0;j<hmV;j++) {
1037 f.push_back(where<<1);
1038 f.push_back((where<<1)+1);
1040 f.push_back((where<<1)+1);
1041 f.push_back(where<<1);
1045 return Create(vertices,faces);
1046 }
else if (factor==1) {
1047 size_t NE=mEdges.size();
1048 size_t NV=mVertices.size();
1049 size_t NF=mFaces.size();
1050 vector<TPoint3D> vertices(NE);
1051 vector<TPolyhedronFace> faces(NV+NF);
1052 for (
size_t i=0;i<NE;i++) {
1053 const TPoint3D &p1=mVertices[mEdges[i].v1];
1054 const TPoint3D &p2=mVertices[mEdges[i].v2];
1056 for (
size_t j=0;j<3;j++)
dst[j]=(p1[j]+p2[j])/2;
1057 faces[mEdges[i].v1].vertices.push_back(i);
1058 faces[mEdges[i].v2].vertices.push_back(i);
1060 for (
size_t i=0;i<NV;i++) {
1061 vector<uint32_t> &f=faces[i].vertices;
1063 if (sf==3)
continue;
1064 for (
size_t j=1;j<sf-1;j++) {
1071 f.erase(f.begin()+j);
1076 for (
size_t i=0;i<NF;i++) {
1077 vector<uint32_t> &f=faces[i+NV].vertices;
1078 const vector<uint32_t> &cf=mFaces[i].vertices;
1079 size_t hmV=cf.size();
1081 for (
size_t j=0;j<hmV;j++) {
1087 return Create(vertices,faces);
1088 }
else return CreateEmpty();
1091 CPolyhedronPtr CPolyhedron::cantellate(
double factor)
const {
1092 if (factor<0)
return CreateEmpty();
1093 else if (factor==0)
return CreateNoCheck(mVertices,mFaces);
1094 size_t NV=mVertices.size();
1095 size_t NE=mEdges.size();
1096 size_t NF=mFaces.size();
1097 vector<TPolygon3D> origFaces(NF);
1098 getSetOfPolygons(origFaces);
1101 vector<TPoint3D> polyCenters(NF);
1102 vector<TPoint3D> polyNewCenters(NF);
1104 for (
size_t i=0;i<NF;i++) {
1105 origFaces[i].getCenter(polyCenters[i]);
1106 polyCenters[i]-=cnt;
1107 polyNewCenters[i]=polyCenters[i];
1108 polyNewCenters[i]*=(1+factor);
1109 polyNewCenters[i]+=cnt;
1110 NNV+=origFaces[i].size();
1112 vector<TPoint3D> vertices(NNV);
1113 vector<TPolyhedronFace> faces(NF+NV+NE);
1115 for (
size_t i=0;i<NF;i++) {
1117 const TPoint3D &nC=polyNewCenters[i];
1119 vector<uint32_t> &f=faces[i].vertices;
1120 size_t oPS=oP.size();
1121 for (
size_t j=0;j<oPS;j++) {
1122 vertices[j+ind]=nC+(oP[j]-oC);
1124 size_t curr=mFaces[i].vertices[j];
1125 faces[NF+curr].vertices.push_back(j+ind);
1127 searchForEdge(mEdges,curr,mFaces[i].vertices[(j+oPS-1)%oPS],edge);
1128 faces[NF+NV+edge].vertices.push_back(j+ind);
1129 searchForEdge(mEdges,curr,mFaces[i].vertices[(j+1)%oPS],edge);
1130 faces[NF+NV+edge].vertices.push_back(j+ind);
1136 vector<uint32_t> &f=it->vertices;
1137 if (f.size()==3)
continue;
1138 for (
size_t i=1;i<f.size()-1;i++)
for(;;)
if (
searchForEdge(edgeBegin,
end,f[i-1],f[i]))
break;
1141 f.erase(f.begin()+i);
1146 vector<uint32_t> &f=it->vertices;
1147 for (
size_t i=1;i<3;i++)
for (;;)
if (
searchForEdge(
begin,edgeBegin,f[i-1],f[i]))
break;
1150 f.erase(f.begin()+i);
1154 return Create(vertices,faces);
1157 CPolyhedronPtr CPolyhedron::augment(
double height)
const {
1158 size_t NV=mVertices.size();
1159 size_t NF=mFaces.size();
1160 vector<TPoint3D> vertices(NV+NF);
1161 std::copy(mVertices.begin(),mVertices.end(),vertices.begin());
1164 vector<TPolyhedronFace> faces(tnf);
1170 getCenter(phCenter);
1173 for (
size_t i=0;i<NF;i++) {
1175 const vector<uint32_t> &
face=mFaces[i].vertices;
1176 size_t N=
face.size();
1178 for (
size_t j=0;j<N;j++) tmp[j]=mVertices[
face[j]];
1183 else for (
size_t j=0;j<3;j++) vertex[j]=cTmp[j]+
height*pTmp.
coefs[j];
1185 for (
size_t j=0;j<N;j++) {
1192 return CreateNoCheck(vertices,faces);
1195 CPolyhedronPtr CPolyhedron::augment(
double height,
size_t numVertices)
const {
1196 size_t NV=mVertices.size();
1197 size_t NF=mFaces.size();
1204 if (tnv==NV)
return CreateNoCheck(mVertices,mFaces);
1205 vector<TPoint3D> vertices(tnv);
1206 std::copy(mVertices.begin(),mVertices.end(),vertices.begin());
1207 vector<TPolyhedronFace> faces(tnf);
1214 getCenter(phCenter);
1217 for (
size_t i=0;i<NF;i++) {
1218 const vector<uint32_t> &
face=mFaces[i].vertices;
1219 size_t N=
face.size();
1220 if (N!=numVertices) {
1221 faces[iF].vertices=
face;
1226 for (
size_t j=0;j<numVertices;j++) tmp[j]=mVertices[
face[j]];
1231 else for (
size_t j=0;j<3;j++) vertex[j]=cTmp[j]+
height*pTmp.
coefs[j];
1233 for (
size_t j=0;j<N;j++) {
1241 return CreateNoCheck(vertices,faces);
1244 CPolyhedronPtr CPolyhedron::augment(
bool direction)
const {
1245 size_t NV=mVertices.size();
1246 size_t NF=mFaces.size();
1247 vector<TPoint3D> vertices(NV+NF);
1248 std::copy(mVertices.begin(),mVertices.end(),vertices.begin());
1251 vector<TPolyhedronFace> faces(tnf);
1257 getCenter(phCenter);
1260 for (
size_t i=0;i<NF;i++) {
1262 const vector<uint32_t> &
face=mFaces[i].vertices;
1263 size_t N=
face.size();
1265 for (
size_t j=0;j<N;j++) tmp[j]=mVertices[
face[j]];
1271 else for (
size_t j=0;j<3;j++) vertex[j]=cTmp[j]+
height*pTmp.
coefs[j];
1273 for (
size_t j=0;j<N;j++) {
1280 return CreateNoCheck(vertices,faces);
1284 CPolyhedronPtr CPolyhedron::augment(
size_t numVertices,
bool direction)
const {
1285 size_t NV=mVertices.size();
1286 size_t NF=mFaces.size();
1293 if (tnv==NV)
return CreateNoCheck(mVertices,mFaces);
1294 vector<TPoint3D> vertices(tnv);
1295 std::copy(mVertices.begin(),mVertices.end(),vertices.begin());
1296 vector<TPolyhedronFace> faces(tnf);
1303 getCenter(phCenter);
1306 for (
size_t i=0;i<NF;i++) {
1307 const vector<uint32_t> &
face=mFaces[i].vertices;
1308 size_t N=
face.size();
1309 if (N!=numVertices) {
1310 faces[iF].vertices=
face;
1315 for (
size_t j=0;j<numVertices;j++) tmp[j]=mVertices[
face[j]];
1321 else for (
size_t j=0;j<3;j++) vertex[j]=cTmp[j]+
height*pTmp.
coefs[j];
1323 for (
size_t j=0;j<N;j++) {
1331 return CreateNoCheck(vertices,faces);
1334 CPolyhedronPtr CPolyhedron::rotate(
double angle)
const {
1335 vector<TPoint3D> vertices(mVertices);
1336 double c=cos(angle),
s=sin(angle);
1343 return CreateNoCheck(vertices,mFaces);
1347 vector<TPoint3D> vertices(mVertices);
1348 if (factor<=0)
throw std::logic_error(
"Factor must be a strictly positive number");
1353 return CreateNoCheck(vertices,mFaces);
1356 vector<TPoint2D> CPolyhedron::generateBase(
uint32_t numBaseEdges,
double baseRadius) {
1357 vector<TPoint2D> base(numBaseEdges);
1358 for (
size_t i=0;i<numBaseEdges;i++) {
1359 double ang=2*
M_PI*i/numBaseEdges;
1360 base[i].x=baseRadius*cos(ang);
1361 base[i].y=baseRadius*sin(ang);
1366 vector<TPoint2D> CPolyhedron::generateShiftedBase(
uint32_t numBaseEdges,
double baseRadius) {
1367 vector<TPoint2D> base(numBaseEdges);
1368 double shift=
M_PI/numBaseEdges;
1369 for (
size_t i=0;i<numBaseEdges;i++) {
1370 double ang=shift+2*
M_PI*i/numBaseEdges;
1371 base[i].x=baseRadius*cos(ang);
1372 base[i].y=baseRadius*sin(ang);
1377 void CPolyhedron::generateBase(
uint32_t numBaseEdges,
double baseRadius,
double height,vector<TPoint3D> &vec) {
1378 for (
size_t i=0;i<numBaseEdges;i++) {
1379 double ang=2*
M_PI*i/numBaseEdges;
1380 vec.push_back(
TPoint3D(baseRadius*cos(ang),baseRadius*sin(ang),
height));
1384 void CPolyhedron::generateShiftedBase(
uint32_t numBaseEdges,
double baseRadius,
double height,
double shift,vector<TPoint3D> &vec) {
1385 for (
size_t i=0;i<numBaseEdges;i++) {
1386 double ang=2*
M_PI*i/numBaseEdges+shift;
1387 vec.push_back(
TPoint3D(baseRadius*cos(ang),baseRadius*sin(ang),
height));
1391 void CPolyhedron::updatePolygons()
const {
1392 tempPolygons.resize(mFaces.size());
1394 polygonsUpToDate=
true;
1398 size_t N=doCheck?f.
vertices.size():3;
1400 for (
size_t i=0;i<N;i++) poly[i]=mVertices[f.
vertices[i]];
1402 if (!poly.
getPlane(tmp))
return false;
1406 if (tmp.evaluatePoint(
c)>0)
for (
size_t i=0;i<3;i++) f.
normal[i]=-f.
normal[i];
1417 if (
find(mEdges.begin(),mEdges.end(),e)==mEdges.end()) mEdges.push_back(e);
1422 if (
find(mEdges.begin(),mEdges.end(),e)==mEdges.end()) mEdges.push_back(e);
1425 bool CPolyhedron::checkConsistence(
const vector<TPoint3D> &vertices,
const vector<TPolyhedronFace> &faces) {
1426 size_t N=vertices.size();
1429 const vector<uint32_t> &e=it->vertices;
1435 size_t CPolyhedron::edgesInVertex(
size_t vertex)
const {
1441 size_t CPolyhedron::facesInVertex(
size_t vertex)
const {
1470 writeToStreamRender(out);
1472 out<<mVertices<<mFaces<<mWireframe<<mLineWidth;
1479 readFromStreamRender(
in);
1480 in>>mVertices>>mFaces>>mWireframe>>mLineWidth;
1481 if (!checkConsistence(mVertices,mFaces))
throw std::logic_error(
"Inconsistent data read from stream");
1483 if (!setNormal(*it))
throw std::logic_error(
"Bad face specification");
1490 CRenderizableDisplayList::notifyChange();
1505 m_pose.composePoint(bb_min, bb_min);
1506 m_pose.composePoint(bb_max, bb_max);
1543 CPolyhedronPtr CPolyhedron::Create(
const vector<TPoint3D> &vertices,
const vector<vector<uint32_t> > &faces) {
1544 vector<TPolyhedronFace> aux;
1545 for (vector<vector<uint32_t> >::
const_iterator it=faces.begin();it!=faces.end();++it) {
1550 return Create(vertices,aux);
1552 CPolyhedronPtr CPolyhedron::Create(
const vector<TPoint3D> &vertices,
const vector<TPolyhedronFace> &faces) {
1553 return CPolyhedronPtr(
new CPolyhedron(vertices,faces,
true));
1555 CPolyhedronPtr CPolyhedron::CreateTetrahedron(
double radius) {
1556 CPolyhedronPtr tetra=CreateJohnsonSolidWithConstantBase(3,radius*sqrt(8.0)/3.0,
"P+");
1560 CPolyhedronPtr CPolyhedron::CreateHexahedron(
double radius) {
1561 if (radius==0.0)
return CreateEmpty();
1562 double r=radius/sqrt(3.0);
1563 return CreateCubicPrism(-
r,
r,-
r,
r,-
r,
r);
1565 CPolyhedronPtr CPolyhedron::CreateOctahedron(
double radius) {
1566 return CreateJohnsonSolidWithConstantBase(4,radius,
"P-P+");
1568 CPolyhedronPtr CPolyhedron::CreateDodecahedron(
double radius) {
1569 return CreateIcosahedron(radius/sqrt(15-6*sqrt(5.0)))->getDual();
1571 CPolyhedronPtr CPolyhedron::CreateIcosahedron(
double radius) {
1573 double s2=4*
square(sin(ang));
1574 double prop=sqrt(s2-1)+sqrt(s2-2+2*cos(ang))/2;
1575 return CreateJohnsonSolidWithConstantBase(5,radius/prop,
"P-AP+",1);
1577 CPolyhedronPtr CPolyhedron::CreateTruncatedTetrahedron(
double radius) {
1578 return CreateTetrahedron(radius*sqrt(27.0/11.0))->truncate(2.0/3.0);
1580 CPolyhedronPtr CPolyhedron::CreateCuboctahedron(
double radius) {
1581 return CreateHexahedron(radius*sqrt(1.5))->truncate(1.0);
1583 CPolyhedronPtr CPolyhedron::CreateTruncatedHexahedron(
double radius) {
1584 return CreateHexahedron(radius*sqrt(3.0/(5-sqrt(8.0))))->truncate(2-sqrt(2.0));
1586 CPolyhedronPtr CPolyhedron::CreateTruncatedOctahedron(
double radius) {
1587 return CreateOctahedron(radius*3/sqrt(5.0))->truncate(2.0/3.0);
1589 CPolyhedronPtr CPolyhedron::CreateRhombicuboctahedron(
double radius,
bool type) {
1590 return CreateJohnsonSolidWithConstantBase(8,radius/sqrt(1+
square(sin(
M_PI/8))),
type?
"C-PRC+":
"GC-PRC+",3);
1592 CPolyhedronPtr CPolyhedron::CreateIcosidodecahedron(
double radius,
bool type) {
1593 return CreateJohnsonSolidWithConstantBase(10,radius,
type?
"GR-R+":
"R-R+",1);
1595 CPolyhedronPtr CPolyhedron::CreateTruncatedDodecahedron(
double radius) {
1596 return CreateDodecahedron(radius*sqrt(45.0)/sqrt(27+6*sqrt(5.0)))->truncate(1-sqrt(0.2));
1598 CPolyhedronPtr CPolyhedron::CreateTruncatedIcosahedron(
double radius) {
1599 return CreateIcosahedron(radius*sqrt(45.0)/sqrt(25+4*sqrt(5.0)))->truncate(2.0/3.0);
1601 CPolyhedronPtr CPolyhedron::CreateRhombicosidodecahedron(
double radius) {
1602 return CreateIcosahedron(radius*sqrt(10.0/(35.0+9.0*sqrt(5.0))))->cantellate(1.5*(sqrt(5.0)-1));
1604 CPolyhedronPtr CPolyhedron::CreatePentagonalRotunda(
double radius) {
1605 return CreateJohnsonSolidWithConstantBase(10,radius,
"R+");
1607 CPolyhedronPtr CPolyhedron::CreateTriakisTetrahedron(
double radius) {
1608 return CreateTruncatedTetrahedron(radius*3/sqrt(33.0))->getDual();
1610 CPolyhedronPtr CPolyhedron::CreateRhombicDodecahedron(
double radius) {
1611 return CreateCuboctahedron(radius/sqrt(2.0))->getDual();
1613 CPolyhedronPtr CPolyhedron::CreateTriakisOctahedron(
double radius) {
1614 return CreateTruncatedHexahedron(radius/sqrt((5-sqrt(8.0))))->getDual();
1616 CPolyhedronPtr CPolyhedron::CreateTetrakisHexahedron(
double radius) {
1617 return CreateTruncatedOctahedron(radius*sqrt(0.6))->getDual();
1619 CPolyhedronPtr CPolyhedron::CreateDeltoidalIcositetrahedron(
double radius) {
1620 return CreateRhombicuboctahedron(radius/sqrt(7-sqrt(32.0)),
true)->getDual();
1622 CPolyhedronPtr CPolyhedron::CreateRhombicTriacontahedron(
double radius) {
1623 return CreateIcosidodecahedron(radius*sqrt(2/(5-sqrt(5.0))),
true)->getDual();
1625 CPolyhedronPtr CPolyhedron::CreateTriakisIcosahedron(
double radius) {
1626 return CreateTruncatedDodecahedron(radius*sqrt(5/(25-8*sqrt(5.0))))->getDual();
1628 CPolyhedronPtr CPolyhedron::CreatePentakisDodecahedron(
double radius) {
1629 return CreateTruncatedIcosahedron(radius*sqrt(3/(17-6*sqrt(5.0))))->getDual();
1631 CPolyhedronPtr CPolyhedron::CreateDeltoidalHexecontahedron(
double radius) {
1632 return CreateRhombicosidodecahedron(radius*3.0/sqrt(15-2*sqrt(5.0)))->getDual();
1635 return CreateCubicPrism(p1.
x,p2.
x,p1.
y,p2.
y,p1.
z,p2.
z);
1637 CPolyhedronPtr CPolyhedron::CreateFrustum(
const vector<TPoint2D> &baseVertices,
double height,
double ratio) {
1638 return CreateTruncatedPyramid(baseVertices,
height,ratio);
1640 CPolyhedronPtr CPolyhedron::CreateCustomPrism(
const vector<TPoint2D> &baseVertices,
double height) {
1641 return CreateTruncatedPyramid(baseVertices,
height,1.0);
1643 CPolyhedronPtr CPolyhedron::CreateRegularAntiprism(
uint32_t numBaseEdges,
double baseRadius,
double height) {
1644 return CreateCustomAntiprism(generateBase(numBaseEdges,baseRadius),generateShiftedBase(numBaseEdges,baseRadius),
height);
1646 CPolyhedronPtr CPolyhedron::CreateRegularPrism(
uint32_t numBaseEdges,
double baseRadius,
double height) {
1647 return CreateCustomPrism(generateBase(numBaseEdges,baseRadius),
height);
1649 CPolyhedronPtr CPolyhedron::CreateRegularPyramid(
uint32_t numBaseEdges,
double baseRadius,
double height) {
1650 return CreatePyramid(generateBase(numBaseEdges,baseRadius),
height);
1652 CPolyhedronPtr CPolyhedron::CreateRegularDoublePyramid(
uint32_t numBaseEdges,
double baseRadius,
double height1,
double height2) {
1653 return CreateDoublePyramid(generateBase(numBaseEdges,baseRadius),height1,height2);
1655 CPolyhedronPtr CPolyhedron::CreateArchimedeanRegularPrism(
uint32_t numBaseEdges,
double baseRadius) {
1656 return CreateJohnsonSolidWithConstantBase(numBaseEdges,baseRadius,
"PR");
1658 CPolyhedronPtr CPolyhedron::CreateArchimedeanRegularAntiprism(
uint32_t numBaseEdges,
double baseRadius) {
1659 return CreateJohnsonSolidWithConstantBase(numBaseEdges,baseRadius,
"A");
1661 CPolyhedronPtr CPolyhedron::CreateRegularTruncatedPyramid(
uint32_t numBaseEdges,
double baseRadius,
double height,
double ratio) {
1662 return CreateTruncatedPyramid(generateBase(numBaseEdges,baseRadius),
height,ratio);
1664 CPolyhedronPtr CPolyhedron::CreateRegularFrustum(
uint32_t numBaseEdges,
double baseRadius,
double height,
double ratio) {
1665 return CreateRegularTruncatedPyramid(numBaseEdges,baseRadius,
height,ratio);
1667 CPolyhedronPtr CPolyhedron::CreateRegularBifrustum(
uint32_t numBaseEdges,
double baseRadius,
double height1,
double ratio1,
double height2,
double ratio2) {
1668 return CreateBifrustum(generateBase(numBaseEdges,baseRadius),height1,ratio1,height2,ratio2);
1670 CPolyhedronPtr CPolyhedron::CreateCupola(
uint32_t numBaseEdges,
double edgeLength) {
1671 return CreateJohnsonSolidWithConstantBase(numBaseEdges,edgeLength/(2*sin(
M_PI/numBaseEdges)),
"C+");
1673 CPolyhedronPtr CPolyhedron::CreateCatalanTrapezohedron(
uint32_t numBaseEdges,
double height) {
1674 return CreateArchimedeanRegularAntiprism(numBaseEdges,
height)->getDual();
1676 CPolyhedronPtr CPolyhedron::CreateCatalanDoublePyramid(
uint32_t numBaseEdges,
double height) {
1677 return CreateArchimedeanRegularPrism(numBaseEdges,
height)->getDual();
1680 CPolyhedronPtr CPolyhedron::CreateNoCheck(
const vector<TPoint3D> &vertices,
const vector<TPolyhedronFace> &faces)
1682 return CPolyhedronPtr(
new CPolyhedron(vertices,faces,
false));
1684 CPolyhedronPtr CPolyhedron::CreateEmpty()
void insertCupola(size_t numBaseEdges, double angleShift, double baseRadius, double edgeLength, bool isRotated, bool isUpwards, size_t base, vector< TPoint3D > &verts, vector< CPolyhedron::TPolyhedronFace > &faces)
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
bool BASE_IMPEXP splitInConvexComponents(const TPolygon2D &poly, std::vector< TPolygon2D > &components)
Splits a 2D polygon into convex components.
OPENGL_IMPEXP mrpt::utils::CStream & operator<<(mrpt::utils::CStream &out, const mrpt::opengl::CLight &o)
GLAPI void GLAPIENTRY glEnable(GLenum cap)
::mrpt::utils::CStream & operator>>(mrpt::utils::CStream &in, CAngularObservationMeshPtr &pObj)
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
bool BASE_IMPEXP traceRay(const std::vector< TPolygonWithPlane > &vec, const mrpt::poses::CPose3D &pose, double &dist)
Fast ray tracing method using polygons' properties.
GLenum GLenum GLenum GLenum GLenum scale
#define THROW_EXCEPTION(msg)
bool getVerticesAndFaces(const vector< math::TPolygon3D > &polys, vector< TPoint3D > &vertices, vector< CPolyhedron::TPolyhedronFace > &faces)
BASE_IMPEXP CRandomGenerator randomGenerator
A static instance of a CRandomGenerator class, for use in single-thread applications.
GLAPI void GLAPIENTRY glNormal3f(GLfloat nx, GLfloat ny, GLfloat nz)
This file implements several operations that operate element-wise on individual or pairs of container...
EIGEN_STRONG_INLINE iterator begin()
size_t additionalFaces(JohnsonBodyPart j, uint32_t numBaseEdges)
Standard object for storing any 3D lightweight object.
const Scalar * const_iterator
#define GL_ONE_MINUS_SRC_ALPHA
const_iterator find(const KEY &key) const
double z
X,Y,Z coordinates.
GLenum GLenum GLuint components
bool getPlanesIntersection(const vector< const TPlane *> &planes, TPoint3D &pnt)
GLsizei GLsizei GLuint * obj
GLAPI void GLAPIENTRY glLineWidth(GLfloat width)
This class represents arbitrary polyhedra.
const vector< TPoint3D > & verts
GLAPI void GLAPIENTRY glBlendFunc(GLenum sfactor, GLenum dfactor)
T square(const T x)
Inline function for the square of a number.
A renderizable object suitable for rendering with OpenGL's display lists.
uint32_t v2
Second vertex.
void composePoint(double lx, double ly, double lz, double &gx, double &gy, double &gz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=NULL, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=NULL, 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...
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
std::vector< uint32_t > vertices
Vector of indices to the vertex list.
This base provides a set of functions for maths stuff.
void insertRotunda(double angleShift, double baseRadius, bool isRotated, bool isUpwards, size_t base, vector< TPoint3D > &verts, vector< CPolyhedron::TPolyhedronFace > &faces)
FCreatePolygonFromFace(const vector< TPoint3D > &v)
Struct used to store a polyhedron face.
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
double normal[3]
Normal vector.
void unitarize()
Unitarize normal vector.
Struct used to store a polyhedron edge.
bool searchForEdge(const vector< CPolyhedron::TPolyhedronEdge > &es, uint32_t v1, uint32_t v2, size_t &where)
GLfloat GLfloat GLfloat GLfloat v3
3D Plane, represented by its equation
bool getPlane(TPlane &p) const
Gets a plane which contains the polygon. Returns false if the polygon is skew and cannot be fit insid...
class BASE_IMPEXP TPolygon3D
GLAPI void GLAPIENTRY glBegin(GLenum mode)
GLsizei const GLchar ** string
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
GLAPI void GLAPIENTRY glVertex3f(GLfloat x, GLfloat y, GLfloat z)
GLAPI void GLAPIENTRY glColor4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha)
size_t additionalVertices(JohnsonBodyPart j, uint32_t numBaseEdges)
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
bool analyzeJohnsonPartsString(const std::string &components, uint32_t numBaseEdges, vector< JohnsonBodyPart > &parts)
GLdouble GLdouble GLdouble r
class OPENGL_IMPEXP CPolyhedron
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
double & operator[](size_t i)
double coefs[4]
Plane coefficients, stored as an array: .
void OPENGL_IMPEXP checkOpenGLError()
Checks glGetError and throws an exception if an error situation is found.
GLuint GLsizei GLsizei * length
The namespace for 3D scene representation and rendering.
double evaluatePoint(const TPoint3D &point) const
Evaluate a point in the plane's equation.
GLAPI void GLAPIENTRY glEnd(void)
T operator()(const CPolyhedron::TPolyhedronFace &f)
GLfloat GLfloat GLfloat v2
double operator[](size_t i) const
GLuint GLenum GLenum transform
void getBestFittingPlane(TPlane &p) const
Gets the best fitting plane, disregarding whether the polygon actually fits inside or not...
double getHeight(const TPolygon3D &p, const TPoint3D &c)
GLenum GLsizei GLsizei height
unsigned __int32 uint32_t
GLAPI void GLAPIENTRY glDisable(GLenum cap)
GLubyte GLubyte GLubyte a
bool searchForFace(const vector< CPolyhedron::TPolyhedronFace > &fs, uint32_t v1, uint32_t v2, uint32_t v3)
bool BASE_IMPEXP intersect(const TSegment3D &s1, const TSegment3D &s2, TObject3D &obj)
Gets the intersection between two 3D segments.
GLuint GLuint GLsizei GLenum type
3D polygon, inheriting from std::vector<TPoint3D>
double BASE_IMPEXP distance(const TPoint2D &p1, const TPoint2D &p2)
Gets the distance between two points in a 2D space.
void getCenter(TPoint3D &p) const
Get polygon's central point.
double BASE_IMPEXP geometryEpsilon
Global epsilon to overcome small precision errors (Default=1e-5)
GLenum GLuint GLint GLenum face
bool faceContainsEdge(const CPolyhedron::TPolyhedronFace &f, const CPolyhedron::TPolyhedronEdge &e)
void getNormalVector(double(&vec)[3]) const
Get plane's normal vector.
3D line, represented by a base point and a director vector.