26 #define DEBUG_FUNCTION_CALLS() printf("%s @ %s:%d\n",__FUNCTION__,__FILE__,__LINE__);
28 static const bool debugConstructors =
false;
32 if(debugConstructors) printf(
"start of %s\n",__PRETTY_FUNCTION__);
42 PlanePolygon::PlanePolygon(vector< vector3f > points) : normals2D(0), edgeDir2D(0), edgeLengths(0), offsets2D(0), pixelLocs(0), vertices(0), vertices2D(0)
44 if(debugConstructors) printf(
"start of %s\n",__PRETTY_FUNCTION__);
50 if(debugConstructors) printf(
"end of %s\n",__PRETTY_FUNCTION__);
53 PlanePolygon::PlanePolygon(vector< vector3f > points, vector< vector2i > _pixelLocs) : normals2D(0), edgeDir2D(0), edgeLengths(0), offsets2D(0), pixelLocs(0), vertices(0), vertices2D(0)
55 if(debugConstructors) printf(
"start of %s\n",__PRETTY_FUNCTION__);
61 if(debugConstructors) printf(
"end of %s\n",__PRETTY_FUNCTION__);
66 if(debugConstructors) printf(
"start of %s\n",__PRETTY_FUNCTION__);
74 if(debugConstructors) printf(
"end of %s\n",__PRETTY_FUNCTION__);
79 static const bool debug =
true;
80 using namespace Eigen;
81 static Matrix3d
m, eigenVectors;
83 static SelfAdjointEigenSolver<Matrix3d>
solver;
86 double n = double(points.size());
97 for(i=0; i<points.size(); i++){
102 for(i=0; i<points.size(); i++){
115 m(0,1) = invN*sum_xy -
p0.x*
p0.y;
116 m(0,2) = invN*sum_xz -
p0.x*
p0.z;
117 m(1,0) = invN*sum_xy -
p0.x*
p0.y;
118 m(1,1) = invN*sum_yy -
p0.y*
p0.y;
119 m(1,2) = invN*sum_yz -
p0.y*
p0.z;
120 m(2,0) = invN*sum_xz -
p0.x*
p0.z;
121 m(2,1) = invN*sum_yz -
p0.y*
p0.z;
122 m(2,2) = invN*sum_zz -
p0.z*
p0.z;
124 eigenVectors =
solver.eigenvectors();
127 double minEig=0, midEig=0, maxEig=0;
128 int minInd=-1, midInd=-1, maxInd=-1;
129 for(
int i=0; i<3; i++){
140 midInd = 3 - (minInd+maxInd);
145 if(minInd<0 || maxInd<0 || maxInd==minInd){
153 if(debug) printf(
"Ill defined plane!\n");
159 printf(
"Planar points:\n");
160 for(i=0; i<points.size(); i++){
161 printf(
"%f,%f,%f\n",V3COMP(points[i]));
163 printf(
"\nEigenvalues order: %d %d %d\n",minInd,midInd,maxInd);
164 printf(
"\nCentroid: %f,%f,%f\n",V3COMP(
p0));
165 cout<<
"\nMatrix:\n"<<
m<<
"\n\nEigenValues:\n"<<
eigenValues<<
"\n\nEigenVectors:\n"<<eigenVectors<<
"\n\n";
169 normal.set(eigenVectors(0,minInd), eigenVectors(1,minInd), eigenVectors(2,minInd),0.0);
174 b1.set(eigenVectors(0,maxInd), eigenVectors(1,maxInd), eigenVectors(2,maxInd),0.0);
175 b2.set(eigenVectors(0,midInd), eigenVectors(1,midInd), eigenVectors(2,midInd),0.0);
177 sum_yy = invN*sum_yy;
178 sum_zz = invN*sum_zz;
179 sum_xy = invN*sum_xy;
180 sum_xz = invN*sum_xz;
181 sum_yz = invN*sum_yz;
187 static const bool debug =
true;
189 if(debug) printf(
"Too few points!\n");
196 for(
unsigned int i=0; i<points.size(); i++){
198 points2d.push_back(p);
210 for(
unsigned int i=0; i<N; i++){
229 height = 0.5*(max2D.y -
min2D.y);
230 if(
width<=0.0 || height<=0.0){
231 if(debug) printf(
"zero size polygon! width: %f, height:%f\n",
width, height);
251 bool interior =
true;
253 printf(
"Vector size mismatch in %s normals2D.size():%d offsets2D.size():%d vertices2D.size():%d\n",__PRETTY_FUNCTION__,
int(
normals2D.size()),
int(
offsets2D.size()),
int(
vertices2D.size()));
256 for(
unsigned int i=0; i<
normals2D.size() && interior; i++){
264 static const bool debug =
false;
265 using namespace Eigen;
275 sum_yy = weight1*sum_yy + weight2*poly2.sum_yy;
276 sum_zz = weight1*sum_zz + weight2*poly2.sum_zz;
277 sum_xy = weight1*sum_xy + weight2*poly2.sum_xy;
278 sum_xz = weight1*sum_xz + weight2*poly2.sum_xz;
279 sum_yz = weight1*sum_yz + weight2*poly2.sum_yz;
281 m(0,0) =
sum_xx - p0Double.x*p0Double.x;
282 m(0,1) = sum_xy - p0Double.x*p0Double.y;
283 m(0,2) = sum_xz - p0Double.x*p0Double.z;
284 m(1,0) = sum_xy - p0Double.x*p0Double.y;
285 m(1,1) = sum_yy - p0Double.y*p0Double.y;
286 m(1,2) = sum_yz - p0Double.y*p0Double.z;
287 m(2,0) = sum_xz - p0Double.x*p0Double.z;
288 m(2,1) = sum_yz - p0Double.y*p0Double.z;
289 m(2,2) = sum_zz - p0Double.z*p0Double.z;
292 eigenVectors =
solver.eigenvectors();
295 double minEig=0, midEig=0, maxEig=0;
296 int minInd=-1, midInd=-1, maxInd=-1;
297 for(
int i=0; i<3; i++){
308 midInd = 3 - (minInd+maxInd);
312 printf(
"\nEigenvalues order: %d %d %d\n",minInd,midInd,maxInd);
313 printf(
"\nCentroid: %f,%f,%f\n",V3COMP(p0Double));
314 std::cout<<
"\nMatrix:\n"<<
m<<
"\n\nEigenValues:\n"<<
eigenValues<<
"\n\nEigenVectors:\n"<<eigenVectors<<
"\n\n";
319 normal.set(eigenVectors(0,minInd), eigenVectors(1,minInd), eigenVectors(2,minInd),0.0);
321 p0.set(V3COMP(p0Double));
325 b1.set(eigenVectors(0,maxInd), eigenVectors(1,maxInd), eigenVectors(2,maxInd),0.0);
326 b2.set(eigenVectors(0,midInd), eigenVectors(1,midInd), eigenVectors(2,midInd),0.0);
328 vector<vector2f> points2d;
331 for(
unsigned int i=0; i<
vertices.size(); i++){
333 points2d.push_back(p);
335 for(
unsigned int i=0; i<poly2.
vertices.size(); i++){
337 points2d.push_back(p);
348 max2D.setAll(-FLT_MAX);
349 for(
unsigned int i=0; i<
vertices2D.size(); i++){
368 height = 0.5*(max2D.y -
min2D.y);
371 printf(
"normals2D.size():%d offsets2D.size():%d vertices2D.size():%d\n",
int(
normals2D.size()),
int(
offsets2D.size()),
int(
vertices2D.size()));
378 static const bool debug =
false;
379 using namespace Eigen;
383 for(
unsigned int i=0; i<polygons.size(); i++){
384 newNumPoints += polygons[i].numPoints;
385 p0Double += polygons[i].numPoints*vector3d(V3COMP(polygons[i].
p0));
387 p0Double = p0Double/newNumPoints;
394 sum_xy = weight*sum_xy;
395 sum_xz = weight*sum_xz;
396 sum_yy = weight*sum_yy;
397 sum_yz = weight*sum_yz;
398 sum_zz = weight*sum_zz;
400 for(
unsigned int i=0; i<polygons.size(); i++){
401 weight = polygons[i].numPoints/newNumPoints;
402 sum_xx += weight*polygons[i].sum_xx;
403 sum_xy += weight*polygons[i].sum_xy;
404 sum_xz += weight*polygons[i].sum_xz;
405 sum_yy += weight*polygons[i].sum_yy;
406 sum_yz += weight*polygons[i].sum_yz;
407 sum_zz += weight*polygons[i].sum_zz;
410 m(0,0) =
sum_xx - p0Double.x*p0Double.x;
411 m(0,1) = sum_xy - p0Double.x*p0Double.y;
412 m(0,2) = sum_xz - p0Double.x*p0Double.z;
413 m(1,0) = sum_xy - p0Double.x*p0Double.y;
414 m(1,1) = sum_yy - p0Double.y*p0Double.y;
415 m(1,2) = sum_yz - p0Double.y*p0Double.z;
416 m(2,0) = sum_xz - p0Double.x*p0Double.z;
417 m(2,1) = sum_yz - p0Double.y*p0Double.z;
418 m(2,2) = sum_zz - p0Double.z*p0Double.z;
421 eigenVectors =
solver.eigenvectors();
424 double minEig=0, midEig=0, maxEig=0;
425 int minInd=-1, midInd=-1, maxInd=-1;
426 for(
int i=0; i<3; i++){
437 midInd = 3 - (minInd+maxInd);
441 printf(
"\nEigenvalues order: %d %d %d\n",minInd,midInd,maxInd);
442 printf(
"\nCentroid: %f,%f,%f\n",V3COMP(p0Double));
443 std::cout<<
"\nMatrix:\n"<<
m<<
"\n\nEigenValues:\n"<<
eigenValues<<
"\n\nEigenVectors:\n"<<eigenVectors<<
"\n\n";
448 normal.set(eigenVectors(0,minInd), eigenVectors(1,minInd), eigenVectors(2,minInd),0.0);
450 p0.set(V3COMP(p0Double));
454 b1.set(eigenVectors(0,maxInd), eigenVectors(1,maxInd), eigenVectors(2,maxInd),0.0);
455 b2.set(eigenVectors(0,midInd), eigenVectors(1,midInd), eigenVectors(2,midInd),0.0);
457 vector<vector2f> points2d;
460 for(
unsigned int i=0; i<
vertices.size(); i++){
462 points2d.push_back(p);
464 for(
unsigned int i=0; i<polygons.size(); i++){
465 for(
unsigned int j=0; j<polygons[i].vertices.size(); j++){
467 points2d.push_back(p);
479 max2D.setAll(-FLT_MAX);
480 for(
unsigned int i=0; i<
vertices2D.size(); i++){
499 height = 0.5*(max2D.y -
min2D.y);
502 printf(
"normals2D.size():%d offsets2D.size():%d vertices2D.size():%d\n",
int(
normals2D.size()),
int(
offsets2D.size()),
int(
vertices2D.size()));
510 GVector::transformMatrix<float>(rotation, translation, M);
516 static const bool debug =
false;
518 Eigen::Vector3d t(M.m14,M.m24,M.m34),p(
p0.x,
p0.y,
p0.z);
521 printf(
"\nTransform Matrix:\n");
522 printf(
"%.6f %.6f %.6f %.6f \n",M.m11,M.m12,M.m13,M.m14);
523 printf(
"%.6f %.6f %.6f %.6f \n",M.m21,M.m22,M.m23,M.m24);
524 printf(
"%.6f %.6f %.6f %.6f \n",M.m31,M.m32,M.m33,M.m34);
525 printf(
"%.6f %.6f %.6f %.6f \n",M.m41,M.m42,M.m43,M.m44);
527 printf(
"\nbefore:\n");
528 printf(
"p0: %f,%f,%f\n",V3COMP(
p0));
529 printf(
"normal: %f,%f,%f\n",V3COMP(
normal));
530 printf(
"b1: %f,%f,%f\n",V3COMP(
b1));
531 printf(
"b2: %f,%f,%f\n",V3COMP(b2));
532 printf(
"xx:%f xy:%f xz:%f yy:%f yz:%f zz:%f\n",
sum_xx,sum_xy,sum_xz,sum_yy,sum_yz,sum_zz);
535 for(
unsigned int i=0; i<
vertices.size(); i++){
540 p0 =
p0.transform(M);
543 b1 =
b1.transform(M);
544 b2 = b2.transform(M);
567 m = R*
m*R.transpose() + t*p.transpose()*R.transpose() + R*p*t.transpose() + t*t.transpose();
577 printf(
"\nafter:\n");
578 printf(
"p0: %f,%f,%f\n",V3COMP(
p0));
579 printf(
"normal: %f,%f,%f\n",V3COMP(
normal));
580 printf(
"b1: %f,%f,%f\n",V3COMP(
b1));
581 printf(
"b2: %f,%f,%f\n",V3COMP(b2));
582 printf(
"xx:%f xy:%f xz:%f yy:%f yz:%f zz:%f\n\n",
sum_xx,sum_xy,sum_xz,sum_yy,sum_yz,sum_zz);
void merge(PlanePolygon &poly2)
Merge this plane polygon with the one provided.
bool validPolygon
Indicates whether a valid convex plane polygon fit was copmuted or not.
bool constructConvexPoly(vector< vector3f > &points)
Construct boindary points to make a convex polygon.
float width
Rectangular dimensions of the polygon.
vector2f min2D
Rectangular extents of the polygon in 2D.
vector< double > offsets2D
Offsets to the edges such that for an interior point p, normals2D[i].dot(p)+offsets2D[i]> 0 for all i...
SelfAdjointEigenSolver< Matrix3d > solver
Solver to solve for optimal plane parameters.
void setAll(num nx)
set the components of the vector to the same value
Matrix3d m
Matrices for computing optimal plane parameters.
Vector3d eigenValues
Eigenvectors of the plane scatter matrix.
bool computePlaneParameters(vector< vector3f > &points)
Compute Plane normal, offset and scatter matrix coefficients from given points.
vector3f p0
Point on the plane corresponding to the centroid of the sampled points.
double offset
Perpendicular offset of the plane from the origin.
vector< double > edgeLengths
Length of the edge (vertices2D[i], vertices2D[i+1])
vector2f projectOnto(const vector3f &p) const
Project 3D point onto the plane polygon and return corresponding 2D coordinates.
double conditionNumber
Ratio of the eigenvalues corresponding to the planar basis vectors.
double distFromPlane(vector3f p)
Returns distance of specified point from the plane.
vector< vector3f > vertices
Vertices of the polygon.
C++ Interfaces: PlanePolygon.
vector< vector2f > vertices2D
Vertices projected onto the 2D basis vectors.
PlanePolygon()
Empty (default) constructor has nothing to do.
vector3f b1
Basis vectors on the plane. b1 corresponds to the major axis and b2 to the minor axis.
void transform(vector3f translation, Quaternionf rotation)
Transforms the plane polygon by the specified translation and rotation.
GrahamsScan grahamsScan
Graham Scan class used to generate convex hull of the polygon.
vector3f corners[4]
Rectangular extents of the polygon in 3D.
~PlanePolygon()
Destructor.
vector< vector2i > pixelLocs
Pixel locations of the points sampled from the depth image used to construct the polygon.
vector< vector2d > normals2D
Normals to the edges. normals2D[i] is normal to the edge (vertices2D[i], vertices2D[i+1]) ...
vector3f intersect(vector3f l0, vector3f l)
Returns the point of intersection of the line =d*l+l0 and this plane.
vector3f rayFromPlane(vector3f p)
Returns ray perpendicular to the plane and pointing from the plane to the specified point p...
double numPoints
Number of points used to build the polygon.
bool liesAlongside(const vector3f &p) const
Returns true if the point, projected onto the plane, lies within the convex hull. ...
vector< vector2d > edgeDir2D
Unit vectors parallel to the edges. edgeDir2D[i] is parallel to the edge (vertices2D[i], vertices2D[i+1])
double sum_xx
Coefficients of the moments of the points.
vector3f normal
Normal to the plane.