MINT2
HyperCuboid.cpp
Go to the documentation of this file.
1 #include "Mint/HyperCuboid.h"
2 #include <math.h>
3 
6 HyperCuboid::HyperCuboid(int dimension) :
7  _dimension ( dimension ),
8  _lowCorner ( dimension ),
9  _highCorner( dimension )
10 {
11 }
12 
15 HyperCuboid::HyperCuboid(const HyperPoint& lowCorner, const HyperPoint& highCorner) :
16  _dimension( lowCorner.size() ),
17  _lowCorner ( _dimension ), //note this assignment sets the dimension of this variable forever, so if
18  _highCorner( _dimension ) //low and high corners are a different size, an error will be thrown inside HyperPoint
19 {
20 
21  if (lowCorner.allLT(highCorner)){
22  _lowCorner = lowCorner;
23  _highCorner = highCorner;
24  }
25  else{
26  ERROR_LOG << "Your lowCorner isn't lower than your highCorner"<< std::endl;
27  _lowCorner .print();
29  }
30 
31 }
32 
35 HyperCuboid::HyperCuboid(int dimension, double low, double high) :
36  _dimension ( dimension ),
37  _lowCorner ( dimension ), //note this assignment sets the dimension of this variable forever, so if
38  _highCorner( dimension ) //low and high corners are a different size, an error will be thrown inside HyperPoint
39 {
40 
41  for (int i = 0; i < _dimension; i++){
42  _lowCorner.at(i) = low ;
43  _highCorner.at(i) = high;
44  }
45 
46  if (low > high) {
47  ERROR_LOG << "Your lowCorner isn't lower than your highCorner" << std::endl;
48  }
49 }
50 
53 bool HyperCuboid::operator ==(const HyperCuboid& other) const{
54  if (other.getDimension() != this->getDimension()) {
55  ERROR_LOG << "Trying to compare HyperCuboids of different dimensions, returning false";
56  return false;
57  }
58  if (getLowCorner() != other.getLowCorner() ) return false;
59  if (getHighCorner() != other.getHighCorner()) return false;
60  return true;
61 }
62 
65 bool HyperCuboid::operator !=(const HyperCuboid& other) const{
66  if (other.getDimension() != this->getDimension()) {
67  ERROR_LOG << "Trying to compare HyperCuboids of different dimensions, returning false";
68  return false;
69  }
70  if (getLowCorner() != other.getLowCorner() ) return true;
71  if (getHighCorner() != other.getHighCorner()) return true;
72  return false;
73 }
74 
80 const HyperCuboid& HyperCuboid::inflateCuboid(double percent){
81 
82  for (int i = 0; i < getDimension(); i++){
83  double diff = getHighCorner().at(i) - getLowCorner().at(i);
84  double increase = diff*percent;
85  getHighCorner().at(i) = getHighCorner().at(i) + increase;
86  getLowCorner() .at(i) = getLowCorner() .at(i) - increase;
87  }
88  return *this;
89 }
90 
94  return (_lowCorner + _highCorner)*0.5;
95 }
96 
99 void HyperCuboid::print(std::ostream& os, int endline) const{
100 
101  os << "Lower Corner: ";
102  _lowCorner.print(os, 0);
103  os << " High Corner: ";
104  _highCorner.print(os, 0);
105  if (endline) os << std::endl;
106 
107 }
108 
113 HyperCuboid HyperCuboid::project(std::vector<int> dims) const{
114 
115  int newdim = (int)dims.size();
116  HyperPoint lowCorner (newdim);
117  HyperPoint highCorner(newdim);
118 
119  for (int i = 0; i < newdim; i++){
120  lowCorner .at(i) = getLowCorner ().at( dims.at(i) );
121  highCorner.at(i) = getHighCorner().at( dims.at(i) );
122  }
123 
124  return HyperCuboid(lowCorner, highCorner);
125 
126 }
127 
132 HyperCuboid HyperCuboid::projectOpposite(std::vector<int> dims) const{
133 
134  int currentDim = getDimension();
135  int newdim = (int)dims.size();
136 
137  std::vector<int> projdims;
138 
139  for (int i = 0; i < currentDim; i++){
140  bool doesExist = false;
141  for (int j = 0; j < newdim; j++){
142  int dim = dims.at(j);
143  if (i == dim) doesExist = true;
144  }
145 
146  if (doesExist == false) projdims.push_back(i);
147  }
148 
149  return project(projdims);
150 
151 }
152 
159 
160  HyperPoint shift = point - _lowCorner;
161  HyperPoint opposite = _highCorner - shift;
162 
163  return opposite;
164 }
165 
169 
170  HyperPoint point(getDimension());
171  for (int i = 0; i < getDimension(); i++){
172  point.at(i) = random->Uniform(getLowCorner().at(i), getHighCorner().at(i));
173  }
174  return point;
175 
176 }
177 
180 HyperPointSet HyperCuboid::getRandomPoints(int nPoints, TRandom* random) const{
181 
182  HyperPointSet points(getDimension());
183  for (int i = 0; i < nPoints; i++){
184  points.push_back( getRandomPoint(random) );
185  }
186  return points;
187 
188 }
189 
190 
191 
197 std::vector<HyperPlane> HyperCuboid::getConnectedHyperPlanes(const HyperPoint& point) const{
198 
199  std::vector<HyperPlane> connectedHyperPlanes;
200 
201  //First find all the verticies that are connected to this one by an edge.
202  //There will be nDim such verticies
203  int dim = getDimension();
204  HyperPointSet connectedVerticies = getConnectedVerticies(point);
205 
206  //We now have the vertex given, and an additional nDim connected
207  //verticies. There is therefore nDim possible Hyperplanes one can form.
208  for (int i = 0; i < dim; i++){
209  HyperPointSet pointsInPlane(dim);
210  pointsInPlane.push_back(point);
211  for(int j = 0; j < dim; j++){
212  if (i != j) pointsInPlane.push_back(connectedVerticies.at(j));
213  }
214  pointsInPlane.sort();
215  HyperPlane plane(pointsInPlane);
216  connectedHyperPlanes.push_back(plane);
217  }
218 
219  return connectedHyperPlanes;
220 
221 }
222 
223 
231 std::vector<HyperPlane> HyperCuboid::getConnectedHyperPlanes(const HyperPointSet& point) const{
232 
233  std::vector<HyperPlane> connectedHyperPlanes;
234 
235  for(unsigned i = 0; i < point.size(); i++){
236  std::vector<HyperPlane> someHyperPlanes = getConnectedHyperPlanes(point.at(i));
237  for(unsigned j = 0; j < someHyperPlanes.size(); j++){
238  connectedHyperPlanes.push_back(someHyperPlanes.at(j));
239  }
240  }
241 
242  return connectedHyperPlanes;
243 
244 }
245 
252 std::vector<HyperPlane> HyperCuboid::getBoundaryHyperPlanes() const{
253 
254  //Get all the verticies of the HyperCuboid, then find all the HyperPlanes
255  //that are conected to these verticies.
256  std::vector<HyperPlane> planes = getConnectedHyperPlanes(getVertices());
257  std::vector<int> isUnique(planes.size(), 1);
258 
259 
260  //remove all the duplicates.
261 
262  VERBOSE_LOG << "There are " << planes.size() << " planes before removing doubles";
263 
264 
265  for(unsigned j = 0; j < planes.size(); j++){
266 
267  if (isUnique.at(j) == 0){ VERBOSE_LOG << " Skippied"; continue; }
268 
269  for(unsigned i = j+1; i < planes.size(); i++){
270 
271  if (isUnique.at(i) == 0) continue;
272  if (planes.at(i) == planes.at(j)) isUnique.at(i) = 0;
273 
274  }
275  }
276 
277  std::vector<HyperPlane> faces;
278  for(unsigned j = 0; j < planes.size(); j++){
279  if (isUnique.at(j) == 1) faces.push_back(planes.at(j));
280  }
281 
282 
283  VERBOSE_LOG << "There are " << faces.size() << " planes after removing doubles";
284 
285 
286  return faces;
287 
288 }
289 
294 
295  if(_faces.size() == 0) _faces = getBoundaryHyperPlanes();
296 
297 }
298 
302 
303  updateFaceCash();
304 
305  int foundSolution = 0;
306  double negativeLineParam = 0.0;
307 
308  for(unsigned i = 0; i < _faces.size(); i++){
309  HyperPoint LineParam = _faces.at(i).findLineIntersectionParameter(line);
310  HyperPoint PlaneParam = _faces.at(i).findPlaneIntersectionParameters(line);
311 
312  VERBOSE_LOG << "-----------------------" << i << "--------------------------";
313  VERBOSE_LOG << "Get the parameters for the line and the plane";
314 
315  if (LineParam.getDimension()==0){
316  VERBOSE_LOG << "Matrix is singular...";
317  continue;
318  }
319 
320  if (PlaneParam <= 1.0 && PlaneParam >= 0.0) {
321  VERBOSE_LOG << "This intersection is within the cuboid";
322  if(LineParam > 0 && foundSolution == 1){
323  double otherPoint = LineParam.at(0);
324  double diff = otherPoint - negativeLineParam;
325  if (fabs(diff)>10e-2) ERROR_LOG << "Somehow there are two distinct negative intercepts";
326  else ERROR_LOG << "Already have this solution... weird";
327  }
328  else if(LineParam > 0) {
329  VERBOSE_LOG << "This positive intersection point " << LineParam.at(0);
330 
331  negativeLineParam = LineParam.at(0);
332  foundSolution = 1;
333  }
334  else{
335  VERBOSE_LOG << "This positive intersection point" << LineParam.at(0);
336  }
337  }
338  else{
339  VERBOSE_LOG << "This intersection is not within the cuboid";
340  }
341 
342  }
343 
344  if (foundSolution == 0) ERROR_LOG << "Found no intercept in cuboid.";
345 
346  return negativeLineParam;
347 
348 }
349 
353 
354  updateFaceCash();
355 
356  int foundSolution = 0;
357  double negativeLineParam = 0.0;
358 
359  for(unsigned i = 0; i < _faces.size(); i++){
360  HyperPoint LineParam = _faces.at(i).findLineIntersectionParameter(line);
361  HyperPoint PlaneParam = _faces.at(i).findPlaneIntersectionParameters(line);
362 
363  VERBOSE_LOG << "-----------------------" << i << "--------------------------";
364  VERBOSE_LOG << "Get the parameters for the line and the plane";
365 
366  if (LineParam.getDimension()==0){
367  VERBOSE_LOG << "Matrix is singular...";
368  continue;
369  }
370 
371  if (PlaneParam <= 1.0 && PlaneParam >= 0.0) {
372  VERBOSE_LOG << "This intersection is within the cuboid";
373  if(LineParam < 0 && foundSolution == 1){
374  double otherPoint = LineParam.at(0);
375  double diff = otherPoint - negativeLineParam;
376  if (fabs(diff)>10e-2) ERROR_LOG << "Somehow there are two distinct negative intercepts";
377  else ERROR_LOG << "Already have this solution... weird";
378  }
379  else if(LineParam < 0) {
380  VERBOSE_LOG << "This positive intersection point " << LineParam.at(0);
381 
382  negativeLineParam = LineParam.at(0);
383  foundSolution = 1;
384  }
385  else{
386  VERBOSE_LOG << "This positive intersection point" << LineParam.at(0);
387  }
388  }
389  else{
390  VERBOSE_LOG << "This intersection is not within the cuboid";
391  }
392 
393  }
394 
395  if (foundSolution == 0) ERROR_LOG << "Found no intercept in cuboid.";
396 
397  return negativeLineParam;
398 }
399 
403 
405 
406 }
407 
411 
413 
414 }
415 
417 
418  int ndim = getDimension();
419 
420  std::bitset< 15 > binary( 0 );
421 
422  HyperPoint center = getCenter();
423  HyperPoint vectorToHighCorner = _highCorner - center;
424 
425  int nVertices = pow(2, ndim);
426 
427  HyperPointSet verticies(ndim);
428 
429  for (int dimToIgnore = 0; dimToIgnore < ndim; dimToIgnore++){
430 
431  for (int i = 0; i < nVertices; i++){
432  HyperPoint vectorToVertex(vectorToHighCorner);
433  binary = i;
434  for (int dim = 0; dim < ndim; dim++){
435  if (binary[dim] == 0){
436  vectorToVertex.at(dim) = -vectorToVertex.at(dim);
437  }
438  if (dimToIgnore == dim){
439  vectorToVertex.at(dim) = 0.0;
440  }
441  }
442  verticies.push_back(vectorToVertex + center);
443  }
444  }
445 
446  verticies.sort();
447  verticies.removeDuplicates();
448 
449  return verticies;
450 
451 }
452 
453 
454 
455 
462 
463  //New faster method. We know the number of verticies, so just
464  //loop from 0 -> nVertex-1 and convert this number to binary.
465  //Imagine the binary number is a vector V.
466  //Also have the center of the cube, C, and a vector to the top right
467  //corner T.
468  //
469  //
470 
471  int ndim = getDimension();
472 
473  std::bitset< 15 > binary( 0 );
474 
475  HyperPoint center = getCenter();
476  HyperPoint vectorToHighCorner = _highCorner - center;
477 
478  int nVertices = pow(2, ndim);
479 
480  HyperPointSet verticies(ndim);
481 
482  for (int i = 0; i < nVertices; i++){
483  HyperPoint vectorToVertex(vectorToHighCorner);
484  binary = i;
485  for (int dim = 0; dim < ndim; dim++){
486  if (binary[dim] == 0){
487  vectorToVertex.at(dim) = -vectorToVertex.at(dim);
488  }
489  }
490  verticies.push_back(vectorToVertex + center);
491  }
492 
493  return verticies;
494 
495  //OLD method
496  //HyperPointSet hyperPointSet(getDimension());
497  //hyperPointSet.push_back(_lowCorner);
498  //
499  //HyperPointSet previousHyperPointSet = hyperPointSet;
500 
501  //for(int i = 1; i < getDimension(); i++){
502  // previousHyperPointSet = getConnectedVerticies(previousHyperPointSet);
503  // hyperPointSet.addHyperPointSet(previousHyperPointSet);
504  // hyperPointSet.sort();
505  // hyperPointSet.removeDuplicates();
506  //}
507  //
508  //hyperPointSet.push_back(_highCorner);
509 
510 
511  //return hyperPointSet;
512 
513 }
514 
522 
523  HyperPointSet hyperPointSet(getDimension());
524 
525  for (unsigned int i = 0; i < pointSet.size(); i++){
526  hyperPointSet.addHyperPointSet ( getConnectedVerticies(pointSet.at(i)) );
527  VERBOSE_LOG << "Sorting....";
528  hyperPointSet.sort();
529  VERBOSE_LOG << "Removing Duplicates....";
530  hyperPointSet.removeDuplicates();
531  }
532 
533  return hyperPointSet;
534 }
535 
542 
543  int dim = getDimension();
544 
545  HyperPointSet hyperPointSet(dim);
546 
547  HyperPoint oppositePoint = getOppositePoint(point);
548  HyperPoint vectorToOpposite = oppositePoint - point;
549 
550  for (int i = 0; i < dim; i++){
551  HyperPoint translation(dim);
552  translation.at(i) = vectorToOpposite.at(i);
553  HyperPoint newCorner = point + translation;
554  hyperPointSet.push_back(newCorner);
555  }
556 
557  return hyperPointSet;
558 
559 }
560 
563 bool HyperCuboid::setCorners(const HyperPoint& lowCorner, const HyperPoint& highCorner){
564 
565  if (lowCorner.allLTOE(highCorner)){
566  _lowCorner = lowCorner;
567  _highCorner = highCorner;
568  }
569  else{
570  ERROR_LOG << "Your lowCorner isn't lower than your highCorner" <<std::endl;
571  return 0;
572  }
573  return 1;
574 }
575 
578 bool HyperCuboid::inVolume(const HyperPoint& coords) const{
579 
580  if (_lowCorner.allLT(coords) && _highCorner.allGTOE(coords)) return 1;
581  return 0;
582 
583 }
584 
587 bool HyperCuboid::inVolume(const HyperPoint& coords, std::vector<int> dims) const{
588 
589  for (unsigned i = 0; i < dims.size(); i++){
590  int dim = dims.at(i);
591  double minEdge = getLowCorner ().at(dim);
592  double maxEdge = getHighCorner().at(dim);
593  double val = coords.at(dim);
594  if ( ( minEdge < val && val <= maxEdge ) == false ) return false;
595  }
596 
597  return true;
598 
599 }
600 
603 double HyperCuboid::volume() const{
604 
605  return (_highCorner - _lowCorner).multiplyElements();
606 
607 }
608 
612  return _highCorner - _lowCorner;
613 }
614 
617 double HyperCuboid::getWidth(int dim) const{
618  return _highCorner.at(dim) - _lowCorner.at(dim);
619 }
620 
621 
625 HyperCuboid HyperCuboid::splitBelow(int dimension, double fractionalSplitPoint) const{
626 
627  if (dimension < 0 || dimension >= getDimension()){
628  ERROR_LOG << "You cannot split in a dimension that doesn't exist!!" << std::endl;
629  return HyperCuboid(*this);
630  }
631  if (fractionalSplitPoint <= 0.0 || fractionalSplitPoint >= 1.0){
632  ERROR_LOG << "Your fractional split point must be between 0.0 and 1.0" << std::endl;
633  return HyperCuboid(*this);
634  }
635 
636  HyperPoint lowCorner1 (_lowCorner );
637  HyperPoint highCorner1(_highCorner);
638 
639  double low = _lowCorner .at(dimension);
640  double high = _highCorner.at(dimension);
641  double width = high - low;
642 
643  double splitCoord = low + width*fractionalSplitPoint;
644 
645  highCorner1.at(dimension) = splitCoord;
646 
647  HyperCuboid lowCuboid (lowCorner1, highCorner1);
648 
649  return lowCuboid;
650 
651 }
652 
656 HyperCuboid HyperCuboid::splitAbove(int dimension, double fractionalSplitPoint) const{
657 
658  if (dimension < 0 || dimension >= getDimension()){
659  ERROR_LOG << "You cannot split in a dimension that doesn't exist!!" << std::endl;
660  return HyperCuboid(*this);
661  }
662  if (fractionalSplitPoint <= 0.0 || fractionalSplitPoint >= 1.0){
663  ERROR_LOG << "Your fractional split point must be between 0.0 and 1.0" << std::endl;
664  return HyperCuboid(*this);
665  }
666 
667  HyperPoint lowCorner2 (_lowCorner );
668  HyperPoint highCorner2(_highCorner);
669 
670  double low = _lowCorner .at(dimension);
671  double high = _highCorner.at(dimension);
672  double width = high - low;
673 
674  double splitCoord = low + width*fractionalSplitPoint;
675 
676  lowCorner2 .at(dimension) = splitCoord;
677 
678  HyperCuboid highCuboid(lowCorner2, highCorner2);
679 
680  return highCuboid;
681 
682 }
683 
687 HyperVolume HyperCuboid::split(int dimension, double fractionalSplitPoint) const{
688 
689  return HyperVolume(
690  splitBelow(dimension,fractionalSplitPoint),
691  splitAbove(dimension,fractionalSplitPoint)
692  );
693 
694 }
695 
699 void HyperCuboid::split(int dimension, double fractionalSplitPoint, HyperVolume& set) const{
700 
701  set.push_back( splitBelow(dimension,fractionalSplitPoint) );
702  set.push_back( splitAbove(dimension,fractionalSplitPoint) );
703 
704 }
705 
709 }
710 
711 
bool allLTOE(const HyperPoint &other) const
Definition: HyperPoint.cpp:358
HyperPointSet getVertices() const
HyperPoint getRandomPoint(TRandom *random=gRandom) const
virtual void print(std::ostream &os=std::cout, int endline=1) const
Definition: HyperPoint.cpp:453
HyperPoint getOppositePoint(const HyperPoint &point) const
void push_back(const HyperCuboid &hyperCuboid)
HyperCuboid splitAbove(int dimension, double fractionalSplitPoint) const
bool allLT(const HyperPoint &other) const
Definition: HyperPoint.cpp:336
HyperPoint _lowCorner
Definition: HyperCuboid.h:34
HyperPointSet getConnectedVerticies(const HyperPointSet &pointSet) const
#define ERROR_LOG
double volume() const
HyperPoint getNegativeIntersectionPoint(const HyperLine &line) const
double getNegativeIntersectionParameter(const HyperLine &line) const
int _dimension
Definition: HyperCuboid.h:32
HyperPointSet getEdgeCenters() const
HyperCuboid(int dimension)
Definition: HyperCuboid.cpp:6
bool setCorners(const HyperPoint &lowCorner, const HyperPoint &highCorner)
#define VERBOSE_LOG
bool operator !=(const HyperCuboid &other) const
Definition: HyperCuboid.cpp:65
const int & getDimension() const
Definition: HyperCuboid.h:45
HyperPointSet getRandomPoints(int nPoints=100, TRandom *random=gRandom) const
void updateFaceCash() const
const HyperPoint & at(int i) const
HyperPoint getCenter() const
Definition: HyperCuboid.cpp:93
const HyperPoint & getHighCorner() const
Definition: HyperCuboid.h:89
std::vector< HyperPlane > _faces
Definition: HyperCuboid.h:39
double getPositiveIntersectionParameter(const HyperLine &line) const
HyperPoint getWidth() const
void print(std::ostream &os=std::cout, int endline=1) const
Definition: HyperCuboid.cpp:99
const double & at(int i) const
Definition: HyperPoint.cpp:433
HyperPoint getPositiveIntersectionPoint(const HyperLine &line) const
bool operator==(const HyperCuboid &other) const
Definition: HyperCuboid.cpp:53
const HyperPoint & getLowCorner() const
Definition: HyperCuboid.h:87
unsigned int size() const
std::vector< HyperPlane > getBoundaryHyperPlanes() const
HyperCuboid splitBelow(int dimension, double fractionalSplitPoint) const
HyperCuboid projectOpposite(std::vector< int > dims) const
std::vector< HyperPlane > getConnectedHyperPlanes(const HyperPoint &point) const
void addHyperPointSet(const HyperPointSet &other)
HyperPoint _highCorner
Definition: HyperCuboid.h:35
int getDimension() const
Definition: HyperPoint.h:99
HyperVolume split(int dimension, double fractionalSplitPoint) const
void removeDuplicates()
const HyperCuboid & inflateCuboid(double percent)
Definition: HyperCuboid.cpp:80
HyperCuboid project(std::vector< int > dims) const
void push_back(const HyperPoint &point)
bool allGTOE(const HyperPoint &other) const
Definition: HyperPoint.cpp:369
HyperPoint getParametricPoint(const HyperPoint &t) const
Definition: NPlane.cpp:40
bool inVolume(const HyperPoint &coords) const