diff options
Diffstat (limited to 'src/qhull/src/qhulltest/QhullFacet_test.cpp')
-rw-r--r-- | src/qhull/src/qhulltest/QhullFacet_test.cpp | 283 |
1 files changed, 283 insertions, 0 deletions
diff --git a/src/qhull/src/qhulltest/QhullFacet_test.cpp b/src/qhull/src/qhulltest/QhullFacet_test.cpp new file mode 100644 index 000000000..271f63753 --- /dev/null +++ b/src/qhull/src/qhulltest/QhullFacet_test.cpp @@ -0,0 +1,283 @@ +/**************************************************************************** +** +** Copyright (c) 2008-2015 C.B. Barber. All rights reserved. +** $Id: //main/2015/qhull/src/qhulltest/QhullFacet_test.cpp#4 $$Change: 2062 $ +** $DateTime: 2016/01/17 13:13:18 $$Author: bbarber $ +** +****************************************************************************/ + +//pre-compiled headers +#include <iostream> +#include "qhulltest/RoadTest.h" // QT_VERSION + +#include "libqhullcpp/QhullFacet.h" +#include "libqhullcpp/QhullError.h" +#include "libqhullcpp/Coordinates.h" +#include "libqhullcpp/RboxPoints.h" +#include "libqhullcpp/QhullFacetList.h" +#include "libqhullcpp/QhullFacetSet.h" +#include "libqhullcpp/QhullPointSet.h" +#include "libqhullcpp/QhullRidge.h" +#include "libqhullcpp/Qhull.h" + +using std::cout; +using std::endl; +using std::ostringstream; +using std::ostream; +using std::string; + +namespace orgQhull { + +class QhullFacet_test : public RoadTest +{ + Q_OBJECT + +#//!\name Test slots +private slots: + void cleanup(); + void t_construct_qh(); + void t_constructConvert(); + void t_getSet(); + void t_value(); + void t_foreach(); + void t_io(); +};//QhullFacet_test + +void +add_QhullFacet_test() +{ + new QhullFacet_test(); // RoadTest::s_testcases +} + +//Executed after each testcase +void QhullFacet_test:: +cleanup() +{ + RoadTest::cleanup(); +} + +void QhullFacet_test:: +t_construct_qh() +{ + // Qhull.runQhull() constructs QhullFacets as facetT + QhullQh qh; + QhullFacet f(&qh); + QVERIFY(!f.isValid()); + QCOMPARE(f.dimension(),0); +}//t_construct_qh + +void QhullFacet_test:: +t_constructConvert() +{ + // Qhull.runQhull() constructs QhullFacets as facetT + Qhull q2; + QhullFacet f(q2); + QVERIFY(!f.isValid()); + QCOMPARE(f.dimension(),0); + RboxPoints rcube("c"); + Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube + QhullFacet f2(q.beginFacet()); + QCOMPARE(f2.dimension(),3); + f= f2; // copy assignment + QVERIFY(f.isValid()); + QCOMPARE(f.dimension(),3); + QhullFacet f5= f2; + QVERIFY(f5==f2); + QVERIFY(f5==f); + QhullFacet f3(q, f2.getFacetT()); + QCOMPARE(f,f3); + QhullFacet f4(q, f2.getBaseT()); + QCOMPARE(f,f4); +}//t_constructConvert + +void QhullFacet_test:: +t_getSet() +{ + RboxPoints rcube("c"); + { + Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube + cout << " rbox c | qhull Qt QR0 QR" << q.rotateRandom() << " distanceEpsilon " << q.distanceEpsilon() << endl; + QCOMPARE(q.facetCount(), 12); + QCOMPARE(q.vertexCount(), 8); + QhullFacetListIterator i(q.facetList()); + while(i.hasNext()){ + const QhullFacet f= i.next(); + cout << f.id() << endl; + QCOMPARE(f.dimension(),3); + QVERIFY(f.id()>0 && f.id()<=39); + QVERIFY(f.isValid()); + if(i.hasNext()){ + QCOMPARE(f.next(), i.peekNext()); + QVERIFY(f.next()!=f); + } + QVERIFY(i.hasPrevious()); + QCOMPARE(f, i.peekPrevious()); + } + + // test tricoplanarOwner + QhullFacet facet = q.beginFacet(); + QhullFacet tricoplanarOwner = facet.tricoplanarOwner(); + int tricoplanarCount= 0; + i.toFront(); + while(i.hasNext()){ + const QhullFacet f= i.next(); + if(f.tricoplanarOwner()==tricoplanarOwner){ + tricoplanarCount++; + } + } + QCOMPARE(tricoplanarCount, 2); + int tricoplanarCount2= 0; + foreach (QhullFacet f, q.facetList()){ // Qt only + QhullHyperplane h= f.hyperplane(); + cout << "Hyperplane: " << h; + QCOMPARE(h.count(), 3); + QCOMPARE(h.offset(), -0.5); + double n= h.norm(); + QCOMPARE(n, 1.0); + QhullHyperplane hi= f.innerplane(); + QCOMPARE(hi.count(), 3); + double innerOffset= hi.offset()+0.5; + cout << "InnerPlane: " << hi << " innerOffset+0.5 " << innerOffset << endl; + QVERIFY(innerOffset >= 0.0-(2*q.distanceEpsilon())); // A guessed epsilon. It needs to account for roundoff due to rotation of the vertices + QhullHyperplane ho= f.outerplane(); + QCOMPARE(ho.count(), 3); + double outerOffset= ho.offset()+0.5; + cout << "OuterPlane: " << ho << " outerOffset+0.5 " << outerOffset << endl; + QVERIFY(outerOffset <= 0.0+(2*q.distanceEpsilon())); // A guessed epsilon. It needs to account for roundoff due to rotation of the vertices + QVERIFY(outerOffset-innerOffset < 1e-7); + for(int k= 0; k<3; k++){ + QVERIFY(ho[k]==hi[k]); + QVERIFY(ho[k]==h[k]); + } + QhullPoint center= f.getCenter(); + cout << "Center: " << center; + double d= f.distance(center); + QVERIFY(d < innerOffset-outerOffset); + QhullPoint center2= f.getCenter(qh_PRINTcentrums); + QCOMPARE(center, center2); + if(f.tricoplanarOwner()==tricoplanarOwner){ + tricoplanarCount2++; + } + cout << endl; + } + QCOMPARE(tricoplanarCount2, 2); + Qhull q2(rcube,"d Qz Qt QR0"); // 3-d triangulation of Delaunay triangulation (the cube) + cout << " rbox c | qhull d Qz Qt QR0 QR" << q2.rotateRandom() << " distanceEpsilon " << q2.distanceEpsilon() << endl; + QhullFacet f2= q2.firstFacet(); + QhullPoint center3= f2.getCenter(qh_PRINTtriangles); + QCOMPARE(center3.dimension(), 3); + QhullPoint center4= f2.getCenter(); + QCOMPARE(center4.dimension(), 4); + for(int k= 0; k<3; k++){ + QVERIFY(center4[k]==center3[k]); + } + Qhull q3(rcube,"v Qz QR0"); // Voronoi diagram of a cube (one vertex) + cout << " rbox c | qhull v Qz QR0 QR" << q3.rotateRandom() << " distanceEpsilon " << q3.distanceEpsilon() << endl; + + q3.setFactorEpsilon(400); // Voronoi vertices are not necessarily within distance episilon + QhullPoint origin= q3.inputOrigin(); + int voronoiCount= 0; + foreach(QhullFacet f, q3.facetList()){ //Qt only + if(f.isGood()){ + ++voronoiCount; + QhullPoint p= f.voronoiVertex(); + cout << p.print("Voronoi vertex: ") + << " Is it within " << q3.factorEpsilon() << " * distanceEpsilon (" << q3.distanceEpsilon() << ") of the origin?" << endl; + QCOMPARE(p, origin); + } + } + QCOMPARE(voronoiCount, 1); + } +}//t_getSet + +void QhullFacet_test:: +t_value() +{ + RboxPoints rcube("c"); + { + Qhull q(rcube, ""); + coordT c[]= {0.0, 0.0, 0.0}; + foreach (QhullFacet f, q.facetList()){ // Qt only + double d= f.distance(q.origin()); + QCOMPARE(d, -0.5); + double d0= f.distance(c); + QCOMPARE(d0, -0.5); + double facetArea= f.facetArea(); + QCOMPARE(facetArea, 1.0); + #if qh_MAXoutside + double maxoutside= f.getFacetT()->maxoutside; + QVERIFY(maxoutside<1e-7); + #endif + } + } +}//t_value + +void QhullFacet_test:: +t_foreach() +{ + RboxPoints rcube("c W0 300"); // cube plus 300 points on its surface + { + Qhull q(rcube, "QR0 Qc"); // keep coplanars, thick facet, and rotate the cube + int coplanarCount= 0; + foreach(const QhullFacet f, q.facetList()){ + QhullPointSet coplanars= f.coplanarPoints(); + coplanarCount += coplanars.count(); + QhullFacetSet neighbors= f.neighborFacets(); + QCOMPARE(neighbors.count(), 4); + QhullPointSet outsides= f.outsidePoints(); + QCOMPARE(outsides.count(), 0); + QhullRidgeSet ridges= f.ridges(); + QCOMPARE(ridges.count(), 4); + QhullVertexSet vertices= f.vertices(); + QCOMPARE(vertices.count(), 4); + int ridgeCount= 0; + QhullRidge r= ridges.first(); + for(int r0= r.id(); ridgeCount==0 || r.id()!=r0; r= r.nextRidge3d(f)){ + ++ridgeCount; + if(!r.hasNextRidge3d(f)){ + QFAIL("Unexpected simplicial facet. They only have ridges to non-simplicial neighbors."); + } + } + QCOMPARE(ridgeCount, 4); + } + QCOMPARE(coplanarCount, 300); + } +}//t_foreach + +void QhullFacet_test:: +t_io() +{ + RboxPoints rcube("c"); + { + Qhull q(rcube, ""); + QhullFacet f= q.beginFacet(); + cout << f; + ostringstream os; + os << f.print("\nWith a message\n"); + os << "\nPrint header for the same facet\n"; + os << f.printHeader(); + os << "\nPrint each component\n"; + os << f.printFlags(" - flags:"); + os << f.printCenter(qh_PRINTfacets, " - center: "); + os << f.printRidges(); + cout << os.str(); + ostringstream os2; + os2 << f; + QString facetString2= QString::fromStdString(os2.str()); + facetString2.replace(QRegExp("\\s\\s+"), " "); + ostringstream os3; + q.qh()->setOutputStream(&os3); + q.outputQhull("f"); + QString facetsString= QString::fromStdString(os3.str()); + QString facetString3= facetsString.mid(facetsString.indexOf("- f1\n")); + facetString3= facetString3.left(facetString3.indexOf("\n- f")+1); + facetString3.replace(QRegExp("\\s\\s+"), " "); + QCOMPARE(facetString2, facetString3); + } +}//t_io + +// toQhullFacet is static_cast only + +}//orgQhull + +#include "moc/QhullFacet_test.moc" |