CGR Localization
 All Classes Namespaces Files Functions Variables Macros Pages
plane_polygon.cpp
1 //========================================================================
2 // This software is free: you can redistribute it and/or modify
3 // it under the terms of the GNU Lesser General Public License Version 3,
4 // as published by the Free Software Foundation.
5 //
6 // This software is distributed in the hope that it will be useful,
7 // but WITHOUT ANY WARRANTY; without even the implied warranty of
8 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
9 // GNU Lesser General Public License for more details.
10 //
11 // You should have received a copy of the GNU Lesser General Public License
12 // Version 3 in the file COPYING that came with this distribution.
13 // If not, see <http://www.gnu.org/licenses/>.
14 //========================================================================
20 //========================================================================
21 
22 #include "plane_polygon.h"
23 
24 //============================================================================================
25 
26 #define DEBUG_FUNCTION_CALLS() printf("%s @ %s:%d\n",__FUNCTION__,__FILE__,__LINE__);
27 
28 static const bool debugConstructors = false;
29 
30 PlanePolygon::PlanePolygon() : normals2D(0), edgeDir2D(0), edgeLengths(0), offsets2D(0), pixelLocs(0), vertices(0), vertices2D(0)
31 {
32  if(debugConstructors) printf("start of %s\n",__PRETTY_FUNCTION__);
33  normal.zero();
34  offset = 0.0;
35  b1.zero();
36  b2.zero();
37  p0.zero();
38  numPoints = 0.0;
39  validPolygon = false;
40 }
41 
42 PlanePolygon::PlanePolygon(vector< vector3f > points) : normals2D(0), edgeDir2D(0), edgeLengths(0), offsets2D(0), pixelLocs(0), vertices(0), vertices2D(0)
43 {
44  if(debugConstructors) printf("start of %s\n",__PRETTY_FUNCTION__);
45  numPoints = points.size();
47  if(validPolygon)
49  pixelLocs.clear();
50  if(debugConstructors) printf("end of %s\n",__PRETTY_FUNCTION__);
51 }
52 
53 PlanePolygon::PlanePolygon(vector< vector3f > points, vector< vector2i > _pixelLocs) : normals2D(0), edgeDir2D(0), edgeLengths(0), offsets2D(0), pixelLocs(0), vertices(0), vertices2D(0)
54 {
55  if(debugConstructors) printf("start of %s\n",__PRETTY_FUNCTION__);
56  numPoints = points.size();
58  if(validPolygon)
60  pixelLocs = _pixelLocs;
61  if(debugConstructors) printf("end of %s\n",__PRETTY_FUNCTION__);
62 }
63 
65 {
66  if(debugConstructors) printf("start of %s\n",__PRETTY_FUNCTION__);
67  normals2D.clear();
68  edgeDir2D.clear();
69  edgeLengths.clear();
70  offsets2D.clear();
71  pixelLocs.clear();
72  vertices.clear();
73  vertices2D.clear();
74  if(debugConstructors) printf("end of %s\n",__PRETTY_FUNCTION__);
75 }
76 
77 bool PlanePolygon::computePlaneParameters(vector< vector3f >& points)
78 {
79  static const bool debug = true;
80  using namespace Eigen;
81  static Matrix3d m, eigenVectors;
82  static Vector3d eigenValues;
83  static SelfAdjointEigenSolver<Matrix3d> solver;
84 
85  vector3f p;
86  double n = double(points.size());
87 
88  sum_xx = 0.0;
89  sum_yy = 0.0;
90  sum_zz = 0.0;
91  sum_xy = 0.0;
92  sum_xz = 0.0;
93  sum_yz = 0.0;
94  unsigned int i;
95 
96  p0.zero();
97  for(i=0; i<points.size(); i++){
98  p0 += points[i];
99  }
100  p0/=n;
101  // Compute statistics required to construct the Scatter Matrix
102  for(i=0; i<points.size(); i++){
103  p = points[i];
104  sum_xx += sq(p.x);
105  sum_yy += sq(p.y);
106  sum_zz += sq(p.z);
107  sum_xy += p.x*p.y;
108  sum_xz += p.x*p.z;
109  sum_yz += p.y*p.z;
110  }
111 
112  double invN = 1.0/n;
113 
114  m(0,0) = invN*sum_xx - p0.x*p0.x;
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;
123  solver.compute(m);
124  eigenVectors = solver.eigenvectors();
125  eigenValues = solver.eigenvalues();
126 
127  double minEig=0, midEig=0, maxEig=0;
128  int minInd=-1, midInd=-1, maxInd=-1;
129  for(int i=0; i<3; i++){
130  if(minEig>eigenValues(i) || minInd<0){
131  minEig = eigenValues(i);
132  minInd = i;
133  }
134  if(maxEig<eigenValues(i) || maxInd<0){
135  maxEig = eigenValues(i);
136  maxInd = i;
137  }
138  }
139 
140  midInd = 3 - (minInd+maxInd);
141  midEig = eigenValues(midInd);
142 
143  conditionNumber = midEig/maxEig;
144 
145  if(minInd<0 || maxInd<0 || maxInd==minInd){
146  // Ill-defined plane
147  normal.zero();
148  offset = 0.0;
149  b1.zero();
150  b2.zero();
151  p0.zero();
152  numPoints = 0.0;
153  if(debug) printf("Ill defined plane!\n");
154  return false;
155  }
156 
157 
158  if(debug && false){
159  printf("Planar points:\n");
160  for(i=0; i<points.size(); i++){
161  printf("%f,%f,%f\n",V3COMP(points[i]));
162  }
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";
166  }
167 
168  n = n;
169  normal.set(eigenVectors(0,minInd), eigenVectors(1,minInd), eigenVectors(2,minInd),0.0);
170  normal.normalize();
171  if(normal.dot(p0)<0.0)
172  normal = -normal;
173  offset = -normal.dot(p0);
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);
176  sum_xx = invN*sum_xx;
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;
182  return true;
183 }
184 
185 bool PlanePolygon::constructConvexPoly(vector< vector3f >& points)
186 {
187  static const bool debug = true;
188  if(points.size()<3){
189  if(debug) printf("Too few points!\n");
190  return false; //Can't construct a polygon with less than 3 vertices!
191  }
192 
193  vector<vector2f> &points2d = vertices2D;
194  points2d.clear();
195 
196  for(unsigned int i=0; i<points.size(); i++){
197  vector2f p(b1.dot(points[i]-p0), b2.dot(points[i]-p0));
198  points2d.push_back(p);
199  }
200  vertices2D = grahamsScan.run(points2d);
201 
202  unsigned int N = vertices2D.size();
203  normals2D.resize(N);
204  offsets2D.resize(N);
205  vertices.resize(N);
206 
207  vector3f p;
208  min2D.setAll(FLT_MAX);
209  max2D.setAll(-FLT_MAX);
210  for(unsigned int i=0; i<N; i++){
211  p = vertices2D[i].x*b1 + vertices2D[i].y*b2 + p0;
212  min2D.x = min(min2D.x,vertices2D[i].x);
213  min2D.y = min(min2D.y,vertices2D[i].y);
214  max2D.x = max(max2D.x,vertices2D[i].x);
215  max2D.y = max(max2D.y,vertices2D[i].y);
216  vertices[i] = p;
217  normals2D[i] = (vertices2D[(i+1)%N]-vertices2D[i]).perp().norm();
218  offsets2D[i] = -normals2D[i].dot(vertices2D[i]);
219  if(normals2D[i].dot(vertices2D[(i+2)%N])+offsets2D[i]<0.0){
220  normals2D[i] = -normals2D[i];
221  offsets2D[i] = -offsets2D[i];
222  }
223  }
224  corners[0] = p0 + b1*min2D.x + b2*min2D.y;
225  corners[1] = p0 + b1*max2D.x + b2*max2D.y;
226  corners[2] = p0 + b1*max2D.x + b2*min2D.y;
227  corners[3] = p0 + b1*min2D.x + b2*max2D.y;
228  width = 0.5*(max2D.x - min2D.x);
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);
232  return false;
233  }
234  return true;
235 }
236 
238 {
239  return fabs(p.dot(normal) + offset);
240 }
241 
243 {
244  return normal*(p.dot(normal)+offset);
245 }
246 
247 
249 {
250  vector2f p2 = projectOnto(p);
251  bool interior = true;
252  if(normals2D.size() != offsets2D.size() || offsets2D.size() != vertices2D.size()){
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()));
254  exit(1);
255  }
256  for(unsigned int i=0; i<normals2D.size() && interior; i++){
257  interior = (normals2D[i].dot(p2)+offsets2D[i])>0.0;
258  }
259  return interior;
260 }
261 
263 {
264  static const bool debug = false;
265  using namespace Eigen;
266 
267  double newNumPoints = numPoints + poly2.numPoints;
268  vector3d p0Double = (numPoints*vector3d(V3COMP(p0)) + poly2.numPoints*vector3d(V3COMP(poly2.p0)))/newNumPoints;
269 
270  // Compute statistics required to construct the MI tensor
271 
272  double weight1 = numPoints/newNumPoints, weight2 = poly2.numPoints/newNumPoints;
273 
274  sum_xx = weight1*sum_xx + weight2*poly2.sum_xx;
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;
280 
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;
290 
291  solver.compute(m);
292  eigenVectors = solver.eigenvectors();
293  eigenValues = solver.eigenvalues();
294 
295  double minEig=0, midEig=0, maxEig=0;
296  int minInd=-1, midInd=-1, maxInd=-1;
297  for(int i=0; i<3; i++){
298  if(minEig>eigenValues(i) || minInd<0){
299  minEig = eigenValues(i);
300  minInd = i;
301  }
302  if(maxEig<eigenValues(i) || maxInd<0){
303  maxEig = eigenValues(i);
304  maxInd = i;
305  }
306  }
307 
308  midInd = 3 - (minInd+maxInd);
309  midEig = eigenValues(midInd);
310 
311  if(debug){
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";
315  //exit(0);
316  }
317 
318  numPoints = newNumPoints;
319  normal.set(eigenVectors(0,minInd), eigenVectors(1,minInd), eigenVectors(2,minInd),0.0);
320  normal.normalize();
321  p0.set(V3COMP(p0Double));
322  if(normal.dot(p0) <0.0)
323  normal = -normal;
324  offset = -normal.dot(p0);
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);
327 
328  vector<vector2f> points2d;
329  points2d.clear();
330 
331  for(unsigned int i=0; i<vertices.size(); i++){
332  vector2f p(b1.dot(vertices[i]-p0), b2.dot(vertices[i]-p0));
333  points2d.push_back(p);
334  }
335  for(unsigned int i=0; i<poly2.vertices.size(); i++){
336  vector2f p(b1.dot(poly2.vertices[i]-p0), b2.dot(poly2.vertices[i]-p0));
337  points2d.push_back(p);
338  }
339 
340  vertices2D = grahamsScan.run(points2d);
341 
342  unsigned int N = vertices2D.size();
343  normals2D.resize(N);
344  offsets2D.resize(N);
345  vertices.resize(N);
346  vector3f p;
347  min2D.setAll(FLT_MAX);
348  max2D.setAll(-FLT_MAX);
349  for(unsigned int i=0; i<vertices2D.size(); i++){
350  p = vertices2D[i].x*b1 + vertices2D[i].y*b2 + p0;
351  min2D.x = min(min2D.x,vertices2D[i].x);
352  min2D.y = min(min2D.y,vertices2D[i].y);
353  max2D.x = max(max2D.x,vertices2D[i].x);
354  max2D.y = max(max2D.y,vertices2D[i].y);
355  vertices[i] = p;
356  normals2D[i] = (vertices2D[(i+1)%N]-vertices2D[i]).perp().norm();
357  offsets2D[i] = -normals2D[i].dot(vertices2D[i]);
358  if(normals2D[i].dot(vertices2D[(i+2)%N])+offsets2D[i]<0.0){
359  normals2D[i] = -normals2D[i];
360  offsets2D[i] = -offsets2D[i];
361  }
362  }
363  corners[0] = p0 + b1*min2D.x + b2*min2D.y;
364  corners[1] = p0 + b1*max2D.x + b2*max2D.y;
365  corners[2] = p0 + b1*max2D.x + b2*min2D.y;
366  corners[3] = p0 + b1*min2D.x + b2*max2D.y;
367  width = 0.5*(max2D.x - min2D.x);
368  height = 0.5*(max2D.y - min2D.y);
369 
370  if(normals2D.size() != offsets2D.size() || offsets2D.size() != vertices2D.size()){
371  printf("normals2D.size():%d offsets2D.size():%d vertices2D.size():%d\n",int(normals2D.size()), int(offsets2D.size()), int(vertices2D.size()));
372  exit(3);
373  }
374 }
375 
376 void PlanePolygon::merge(vector< PlanePolygon >& polygons)
377 {
378  static const bool debug = false;
379  using namespace Eigen;
380 
381  double newNumPoints = numPoints;
382  vector3d p0Double = numPoints*vector3d(V3COMP(p0));
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));
386  }
387  p0Double = p0Double/newNumPoints;
388 
389  // Compute statistics required to construct the MI tensor
390 
391  double weight = numPoints/newNumPoints;
392 
393  sum_xx = weight*sum_xx;
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;
399 
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;
408  }
409 
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;
419 
420  solver.compute(m);
421  eigenVectors = solver.eigenvectors();
422  eigenValues = solver.eigenvalues();
423 
424  double minEig=0, midEig=0, maxEig=0;
425  int minInd=-1, midInd=-1, maxInd=-1;
426  for(int i=0; i<3; i++){
427  if(minEig>eigenValues(i) || minInd<0){
428  minEig = eigenValues(i);
429  minInd = i;
430  }
431  if(maxEig<eigenValues(i) || maxInd<0){
432  maxEig = eigenValues(i);
433  maxInd = i;
434  }
435  }
436 
437  midInd = 3 - (minInd+maxInd);
438  midEig = eigenValues(midInd);
439 
440  if(debug){
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";
444  //exit(0);
445  }
446 
447  numPoints = newNumPoints;
448  normal.set(eigenVectors(0,minInd), eigenVectors(1,minInd), eigenVectors(2,minInd),0.0);
449  normal.normalize();
450  p0.set(V3COMP(p0Double));
451  if(normal.dot(p0) <0.0)
452  normal = -normal;
453  offset = -normal.dot(p0);
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);
456 
457  vector<vector2f> points2d;
458  points2d.clear();
459 
460  for(unsigned int i=0; i<vertices.size(); i++){
461  vector2f p(b1.dot(vertices[i]-p0), b2.dot(vertices[i]-p0));
462  points2d.push_back(p);
463  }
464  for(unsigned int i=0; i<polygons.size(); i++){
465  for(unsigned int j=0; j<polygons[i].vertices.size(); j++){
466  vector2f p(b1.dot(polygons[i].vertices[j]-p0), b2.dot(polygons[i].vertices[j]-p0));
467  points2d.push_back(p);
468  }
469  }
470 
471  vertices2D = grahamsScan.run(points2d);
472 
473  unsigned int N = vertices2D.size();
474  normals2D.resize(N);
475  offsets2D.resize(N);
476  vertices.resize(N);
477  vector3f p;
478  min2D.setAll(FLT_MAX);
479  max2D.setAll(-FLT_MAX);
480  for(unsigned int i=0; i<vertices2D.size(); i++){
481  p = vertices2D[i].x*b1 + vertices2D[i].y*b2 + p0;
482  min2D.x = min(min2D.x,vertices2D[i].x);
483  min2D.y = min(min2D.y,vertices2D[i].y);
484  max2D.x = max(max2D.x,vertices2D[i].x);
485  max2D.y = max(max2D.y,vertices2D[i].y);
486  vertices[i] = p;
487  normals2D[i] = (vertices2D[(i+1)%N]-vertices2D[i]).perp().norm();
488  offsets2D[i] = -normals2D[i].dot(vertices2D[i]);
489  if(normals2D[i].dot(vertices2D[(i+2)%N])+offsets2D[i]<0.0){
490  normals2D[i] = -normals2D[i];
491  offsets2D[i] = -offsets2D[i];
492  }
493  }
494  corners[0] = p0 + b1*min2D.x + b2*min2D.y;
495  corners[1] = p0 + b1*max2D.x + b2*max2D.y;
496  corners[2] = p0 + b1*max2D.x + b2*min2D.y;
497  corners[3] = p0 + b1*min2D.x + b2*max2D.y;
498  width = 0.5*(max2D.x - min2D.x);
499  height = 0.5*(max2D.y - min2D.y);
500 
501  if(normals2D.size() != offsets2D.size() || offsets2D.size() != vertices2D.size()){
502  printf("normals2D.size():%d offsets2D.size():%d vertices2D.size():%d\n",int(normals2D.size()), int(offsets2D.size()), int(vertices2D.size()));
503  exit(3);
504  }
505 }
506 
507 void PlanePolygon::transform(vector3f translation, Quaternionf rotation)
508 {
510  GVector::transformMatrix<float>(rotation, translation, M);
511  transform(M);
512 }
513 
515 {
516  static const bool debug = false;
517  Eigen::Matrix3d R;
518  Eigen::Vector3d t(M.m14,M.m24,M.m34),p(p0.x,p0.y,p0.z);
519 
520  if(debug){
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);
526  //exit(0);
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);
533  }
534  // transform points
535  for(unsigned int i=0; i<vertices.size(); i++){
536  vertices[i] = vertices[i].transform(M);
537  }
538 
539  // transform normals, basis vectors and centroid
540  p0 = p0.transform(M);
541  normal.w=0.0;
542  normal = normal.transform(M);
543  b1 = b1.transform(M);
544  b2 = b2.transform(M);
545 
546  // transform scatter matrix elements
547  R(0,0) = M.m11;
548  R(0,1) = M.m12;
549  R(0,2) = M.m13;
550  R(1,0) = M.m21;
551  R(1,1) = M.m22;
552  R(1,2) = M.m23;
553  R(2,0) = M.m31;
554  R(2,1) = M.m32;
555  R(2,2) = M.m33;
556 
557  m(0,0) = sum_xx;
558  m(0,1) = sum_xy;
559  m(0,2) = sum_xz;
560  m(1,0) = sum_xy;
561  m(1,1) = sum_yy;
562  m(1,2) = sum_yz;
563  m(2,0) = sum_xz;
564  m(2,1) = sum_yz;
565  m(2,2) = sum_zz;
566 
567  m = R*m*R.transpose() + t*p.transpose()*R.transpose() + R*p*t.transpose() + t*t.transpose();
568 
569  sum_xx = m(0,0);
570  sum_xy = m(0,1);
571  sum_xz = m(0,2);
572  sum_yy = m(1,1);
573  sum_yz = m(1,2);
574  sum_zz = m(2,2);
575 
576  if(debug){
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);
583  }
584 }
585 
587 {
588  //Implemented from:
589  // http://en.wikipedia.org/w/index.php?title=Line-plane_intersection&oldid=458252030#Algebraic_form
590  float d = (p0-l0).dot(normal)/l.dot(normal);
591  return d*l+l0;
592 }
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.
Definition: plane_polygon.h:98
bool constructConvexPoly(vector< vector3f > &points)
Construct boindary points to make a convex polygon.
float width
Rectangular dimensions of the polygon.
Definition: plane_polygon.h:91
vector2f min2D
Rectangular extents of the polygon in 2D.
Definition: plane_polygon.h:93
vector< double > offsets2D
Offsets to the edges such that for an interior point p, normals2D[i].dot(p)+offsets2D[i]> 0 for all i...
Definition: plane_polygon.h:57
SelfAdjointEigenSolver< Matrix3d > solver
Solver to solve for optimal plane parameters.
Definition: plane_polygon.h:66
void setAll(num nx)
set the components of the vector to the same value
Definition: gvector.h:771
Matrix3d m
Matrices for computing optimal plane parameters.
Definition: plane_polygon.h:62
Vector3d eigenValues
Eigenvectors of the plane scatter matrix.
Definition: plane_polygon.h:64
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.
Definition: plane_polygon.h:81
double offset
Perpendicular offset of the plane from the origin.
Definition: plane_polygon.h:83
vector< double > edgeLengths
Length of the edge (vertices2D[i], vertices2D[i+1])
Definition: plane_polygon.h:55
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.
Definition: plane_polygon.h:74
C++ Interfaces: PlanePolygon.
vector< vector2f > vertices2D
Vertices projected onto the 2D basis vectors.
Definition: plane_polygon.h:76
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.
Definition: plane_polygon.h:85
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.
Definition: plane_polygon.h:60
vector3f corners[4]
Rectangular extents of the polygon in 3D.
Definition: plane_polygon.h:95
~PlanePolygon()
Destructor.
vector< vector2i > pixelLocs
Pixel locations of the points sampled from the depth image used to construct the polygon.
Definition: plane_polygon.h:72
vector< vector2d > normals2D
Normals to the edges. normals2D[i] is normal to the edge (vertices2D[i], vertices2D[i+1]) ...
Definition: plane_polygon.h:51
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.
Definition: plane_polygon.h:70
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])
Definition: plane_polygon.h:53
double sum_xx
Coefficients of the moments of the points.
Definition: plane_polygon.h:89
vector3f normal
Normal to the plane.
Definition: plane_polygon.h:79