QhullFacet_test.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (c) 2008-2015 C.B. Barber. All rights reserved.
4 ** $Id: //main/2015/qhull/src/qhulltest/QhullFacet_test.cpp#4 $$Change: 2062 $
5 ** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $
6 **
7 ****************************************************************************/
8 
9 //pre-compiled headers
10 #include <iostream>
11 #include "qhulltest/RoadTest.h" // QT_VERSION
12 
13 #include "libqhullcpp/QhullFacet.h"
14 #include "libqhullcpp/QhullError.h"
16 #include "libqhullcpp/RboxPoints.h"
20 #include "libqhullcpp/QhullRidge.h"
21 #include "libqhullcpp/Qhull.h"
22 
23 using std::cout;
24 using std::endl;
25 using std::ostringstream;
26 using std::ostream;
27 using std::string;
28 
29 namespace orgQhull {
30 
31 class QhullFacet_test : public RoadTest
32 {
33  Q_OBJECT
34 
35 #
36 private slots:
37  void cleanup();
38  void t_construct_qh();
39  void t_constructConvert();
40  void t_getSet();
41  void t_value();
42  void t_foreach();
43  void t_io();
44 };//QhullFacet_test
45 
46 void
48 {
49  new QhullFacet_test(); // RoadTest::s_testcases
50 }
51 
52 //Executed after each testcase
55 {
57 }
58 
61 {
62  // Qhull.runQhull() constructs QhullFacets as facetT
63  QhullQh qh;
64  QhullFacet f(&qh);
65  QVERIFY(!f.isValid());
66  QCOMPARE(f.dimension(),0);
67 }//t_construct_qh
68 
71 {
72  // Qhull.runQhull() constructs QhullFacets as facetT
73  Qhull q2;
74  QhullFacet f(q2);
75  QVERIFY(!f.isValid());
76  QCOMPARE(f.dimension(),0);
77  RboxPoints rcube("c");
78  Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
79  QhullFacet f2(q.beginFacet());
80  QCOMPARE(f2.dimension(),3);
81  f= f2; // copy assignment
82  QVERIFY(f.isValid());
83  QCOMPARE(f.dimension(),3);
84  QhullFacet f5= f2;
85  QVERIFY(f5==f2);
86  QVERIFY(f5==f);
87  QhullFacet f3(q, f2.getFacetT());
88  QCOMPARE(f,f3);
89  QhullFacet f4(q, f2.getBaseT());
90  QCOMPARE(f,f4);
91 }//t_constructConvert
92 
95 {
96  RboxPoints rcube("c");
97  {
98  Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
99  cout << " rbox c | qhull Qt QR0 QR" << q.rotateRandom() << " distanceEpsilon " << q.distanceEpsilon() << endl;
100  QCOMPARE(q.facetCount(), 12);
101  QCOMPARE(q.vertexCount(), 8);
103  while(i.hasNext()){
104  const QhullFacet f= i.next();
105  cout << f.id() << endl;
106  QCOMPARE(f.dimension(),3);
107  QVERIFY(f.id()>0 && f.id()<=39);
108  QVERIFY(f.isValid());
109  if(i.hasNext()){
110  QCOMPARE(f.next(), i.peekNext());
111  QVERIFY(f.next()!=f);
112  }
113  QVERIFY(i.hasPrevious());
114  QCOMPARE(f, i.peekPrevious());
115  }
116 
117  // test tricoplanarOwner
118  QhullFacet facet = q.beginFacet();
119  QhullFacet tricoplanarOwner = facet.tricoplanarOwner();
120  int tricoplanarCount= 0;
121  i.toFront();
122  while(i.hasNext()){
123  const QhullFacet f= i.next();
124  if(f.tricoplanarOwner()==tricoplanarOwner){
125  tricoplanarCount++;
126  }
127  }
128  QCOMPARE(tricoplanarCount, 2);
129  int tricoplanarCount2= 0;
130  foreach (QhullFacet f, q.facetList()){ // Qt only
132  cout << "Hyperplane: " << h;
133  QCOMPARE(h.count(), 3);
134  QCOMPARE(h.offset(), -0.5);
135  double n= h.norm();
136  QCOMPARE(n, 1.0);
137  QhullHyperplane hi= f.innerplane();
138  QCOMPARE(hi.count(), 3);
139  double innerOffset= hi.offset()+0.5;
140  cout << "InnerPlane: " << hi << " innerOffset+0.5 " << innerOffset << endl;
141  QVERIFY(innerOffset >= 0.0-(2*q.distanceEpsilon())); // A guessed epsilon. It needs to account for roundoff due to rotation of the vertices
142  QhullHyperplane ho= f.outerplane();
143  QCOMPARE(ho.count(), 3);
144  double outerOffset= ho.offset()+0.5;
145  cout << "OuterPlane: " << ho << " outerOffset+0.5 " << outerOffset << endl;
146  QVERIFY(outerOffset <= 0.0+(2*q.distanceEpsilon())); // A guessed epsilon. It needs to account for roundoff due to rotation of the vertices
147  QVERIFY(outerOffset-innerOffset < 1e-7);
148  for(int k= 0; k<3; k++){
149  QVERIFY(ho[k]==hi[k]);
150  QVERIFY(ho[k]==h[k]);
151  }
152  QhullPoint center= f.getCenter();
153  cout << "Center: " << center;
154  double d= f.distance(center);
155  QVERIFY(d < innerOffset-outerOffset);
157  QCOMPARE(center, center2);
158  if(f.tricoplanarOwner()==tricoplanarOwner){
159  tricoplanarCount2++;
160  }
161  cout << endl;
162  }
163  QCOMPARE(tricoplanarCount2, 2);
164  Qhull q2(rcube,"d Qz Qt QR0"); // 3-d triangulation of Delaunay triangulation (the cube)
165  cout << " rbox c | qhull d Qz Qt QR0 QR" << q2.rotateRandom() << " distanceEpsilon " << q2.distanceEpsilon() << endl;
166  QhullFacet f2= q2.firstFacet();
168  QCOMPARE(center3.dimension(), 3);
169  QhullPoint center4= f2.getCenter();
170  QCOMPARE(center4.dimension(), 4);
171  for(int k= 0; k<3; k++){
172  QVERIFY(center4[k]==center3[k]);
173  }
174  Qhull q3(rcube,"v Qz QR0"); // Voronoi diagram of a cube (one vertex)
175  cout << " rbox c | qhull v Qz QR0 QR" << q3.rotateRandom() << " distanceEpsilon " << q3.distanceEpsilon() << endl;
176 
177  q3.setFactorEpsilon(400); // Voronoi vertices are not necessarily within distance episilon
178  QhullPoint origin= q3.inputOrigin();
179  int voronoiCount= 0;
180  foreach(QhullFacet f, q3.facetList()){ //Qt only
181  if(f.isGood()){
182  ++voronoiCount;
183  QhullPoint p= f.voronoiVertex();
184  cout << p.print("Voronoi vertex: ")
185  << " Is it within " << q3.factorEpsilon() << " * distanceEpsilon (" << q3.distanceEpsilon() << ") of the origin?" << endl;
186  QCOMPARE(p, origin);
187  }
188  }
189  QCOMPARE(voronoiCount, 1);
190  }
191 }//t_getSet
192 
195 {
196  RboxPoints rcube("c");
197  {
198  Qhull q(rcube, "");
199  coordT c[]= {0.0, 0.0, 0.0};
200  foreach (QhullFacet f, q.facetList()){ // Qt only
201  double d= f.distance(q.origin());
202  QCOMPARE(d, -0.5);
203  double d0= f.distance(c);
204  QCOMPARE(d0, -0.5);
205  double facetArea= f.facetArea();
206  QCOMPARE(facetArea, 1.0);
207  #if qh_MAXoutside
208  double maxoutside= f.getFacetT()->maxoutside;
209  QVERIFY(maxoutside<1e-7);
210  #endif
211  }
212  }
213 }//t_value
214 
217 {
218  RboxPoints rcube("c W0 300"); // cube plus 300 points on its surface
219  {
220  Qhull q(rcube, "QR0 Qc"); // keep coplanars, thick facet, and rotate the cube
221  int coplanarCount= 0;
222  foreach(const QhullFacet f, q.facetList()){
223  QhullPointSet coplanars= f.coplanarPoints();
224  coplanarCount += coplanars.count();
225  QhullFacetSet neighbors= f.neighborFacets();
226  QCOMPARE(neighbors.count(), 4);
227  QhullPointSet outsides= f.outsidePoints();
228  QCOMPARE(outsides.count(), 0);
229  QhullRidgeSet ridges= f.ridges();
230  QCOMPARE(ridges.count(), 4);
231  QhullVertexSet vertices= f.vertices();
232  QCOMPARE(vertices.count(), 4);
233  int ridgeCount= 0;
234  QhullRidge r= ridges.first();
235  for(int r0= r.id(); ridgeCount==0 || r.id()!=r0; r= r.nextRidge3d(f)){
236  ++ridgeCount;
237  if(!r.hasNextRidge3d(f)){
238  QFAIL("Unexpected simplicial facet. They only have ridges to non-simplicial neighbors.");
239  }
240  }
241  QCOMPARE(ridgeCount, 4);
242  }
243  QCOMPARE(coplanarCount, 300);
244  }
245 }//t_foreach
246 
249 {
250  RboxPoints rcube("c");
251  {
252  Qhull q(rcube, "");
253  QhullFacet f= q.beginFacet();
254  cout << f;
255  ostringstream os;
256  os << f.print("\nWith a message\n");
257  os << "\nPrint header for the same facet\n";
258  os << f.printHeader();
259  os << "\nPrint each component\n";
260  os << f.printFlags(" - flags:");
261  os << f.printCenter(qh_PRINTfacets, " - center: ");
262  os << f.printRidges();
263  cout << os.str();
264  ostringstream os2;
265  os2 << f;
266  QString facetString2= QString::fromStdString(os2.str());
267  facetString2.replace(QRegExp("\\s\\s+"), " ");
268  ostringstream os3;
269  q.qh()->setOutputStream(&os3);
270  q.outputQhull("f");
271  QString facetsString= QString::fromStdString(os3.str());
272  QString facetString3= facetsString.mid(facetsString.indexOf("- f1\n"));
273  facetString3= facetString3.left(facetString3.indexOf("\n- f")+1);
274  facetString3.replace(QRegExp("\\s\\s+"), " ");
275  QCOMPARE(facetString2, facetString3);
276  }
277 }//t_io
278 
279 // toQhullFacet is static_cast only
280 
281 }//orgQhull
282 
283 #include "moc/QhullFacet_test.moc"
QhullRidgeSet ridges() const
Definition: QhullFacet.cpp:192
QhullHyperplane hyperplane() const
Definition: QhullFacet.h:72
QhullHyperplane innerplane() const
Definition: QhullFacet.cpp:104
QhullPoint inputOrigin()
Return origin point for qh.input_dim.
Definition: Qhull.cpp:133
QhullRidge – Qhull&#39;s ridge structure, ridgeT, as a C++ class.
Definition: Coordinates.cpp:21
q
bool isValid() const
Definition: QhullFacet.h:75
POD type equivalent to qhT. No virtual members.
Definition: QhullQh.h:58
int dimension() const
Definition: QhullPoint.h:89
A QhullFacet is the C++ equivalent to Qhull&#39;s facetT*.
Definition: QhullFacet.h:37
QhullPointSet coplanarPoints() const
Definition: QhullFacet.cpp:174
QhullFacet firstFacet() const
Definition: Qhull.h:108
countT id() const
Definition: QhullFacet.h:73
QhullPoint voronoiVertex()
Definition: QhullFacet.cpp:146
QhullPoint getCenter()
Definition: QhullFacet.h:67
void outputQhull()
Definition: Qhull.cpp:211
double facetArea()
Disables tricoplanarOwner()
Definition: QhullFacet.cpp:158
facetT * getFacetT() const
Definition: QhullFacet.h:71
QhullVertexSet vertices() const
Definition: QhullFacet.cpp:198
c
#define coordT
Definition: libqhull.h:80
QhullFacetList facetList() const
Definition: Qhull.cpp:186
QhullRidge nextRidge3d(const QhullFacet &f) const
Definition: QhullRidge.h:95
countT vertexCount() const
Definition: Qhull.h:86
int dimension() const
Definition: QhullFacet.h:66
#define qh
Definition: libqhull.h:457
QhullFacet beginFacet() const
Definition: Qhull.h:102
countT count() const
Filtered by facet.isGood(). May be 0 when !isEmpty().
QhullFacetSet neighborFacets() const
Definition: QhullFacet.cpp:180
Interface to Qhull from C++.
Definition: Qhull.h:43
countT id() const
Definition: QhullRidge.h:86
coordT maxoutside
Definition: libqhull.h:267
int rotateRandom() const
Return QRn for repeating QR0 runs.
Definition: Qhull.h:84
bool hasNextRidge3d(const QhullFacet &f) const
Definition: QhullRidge.cpp:49
QhullQh * qh() const
Definition: Qhull.h:81
q2
QhullHyperplane outerplane() const
Definition: QhullFacet.cpp:119
QhullPoint origin()
non-const due to QhullPoint
Definition: Qhull.h:80
double distance(const Coordinates &c) const
Undefined if c.size() != dimension()
Definition: QhullFacet.h:92
void setFactorEpsilon(double a)
Definition: Qhull.h:98
void add_QhullFacet_test()
void setOutputStream(std::ostream *os)
Updates use_output_stream.
Definition: QhullQh.cpp:180
PrintPoint print(const char *message) const
Definition: QhullPoint.h:123
PrintFacet print(const char *message)
Definition: QhullFacet.h:119
QhullPointSet outsidePoints() const
Definition: QhullFacet.cpp:186
QhullFacet next() const
Definition: QhullFacet.h:81
void cleanup()
Executed after each test.
Definition: RoadTest.cpp:38
countT count(const T &t) const
Definition: QhullSet.h:389
double distanceEpsilon() const
Epsilon for distance to hyperplane.
Definition: Qhull.h:92
bool isGood() const
Definition: QhullFacet.h:76
countT facetCount() const
Definition: Qhull.h:72
QhullFacet tricoplanarOwner() const
Definition: QhullFacet.cpp:134
double factorEpsilon() const
Factor for angleEpsilon and distanceEpsilon.
Definition: Qhull.h:93


hpp-fcl
Author(s):
autogenerated on Fri Jun 2 2023 02:39:02