1 /****************************************************************************
2 **
3 ** Copyright (p) 2009-2012 C.B. Barber. All rights reserved.
4 ** $Id: //main/2011/qhull/src/qhulltest/QhullPoints_test.cpp#6 $$Change: 1490 $
5 ** $DateTime: 2012/02/19 20:27:01 $$Author: bbarber $
6 **
7 ****************************************************************************/
8
9 //pre-compiled header
10 #include <iostream>
11 #include "RoadTest.h" // QT_VERSION
12
13 #include "QhullPoints.h"
14 #include "RboxPoints.h"
15 #include "Qhull.h"
16
17 using std::cout;
18 using std::endl;
19 using std::ostringstream;
20
21 namespace orgQhull {
22
23 class QhullPoints_test : public RoadTest
24 {
25 Q_OBJECT
26
27 #//Test slots
28 private slots:
29 void cleanup();
30 void t_construct();
31 void t_convert();
32 void t_getset();
33 void t_element();
34 void t_iterator();
35 void t_const_iterator();
36 void t_search();
37 void t_points_iterator();
38 void t_io();
39 };//QhullPoints_test
40
41 void
add_QhullPoints_test()42 add_QhullPoints_test()
43 {
44 new QhullPoints_test();
45 }
46
47 //Executed after each testcase
48 void QhullPoints_test::
cleanup()49 cleanup()
50 {
51 UsingLibQhull::checkQhullMemoryEmpty();
52 RoadTest::cleanup();
53 }
54
55 void QhullPoints_test::
t_construct()56 t_construct()
57 {
58 QhullPoints ps;
59 QCOMPARE(ps.dimension(), 0);
60 QVERIFY(ps.isEmpty());
61 QVERIFY(ps.empty());
62 QCOMPARE(ps.count(), 0);
63 QCOMPARE(ps.size(), 0u);
64 QCOMPARE(ps.coordinateCount(), 0);
65 coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
66 QhullPoints ps2;
67 ps2.defineAs(2, 6, c);
68 QCOMPARE(ps2.dimension(), 2);
69 QVERIFY(!ps2.isEmpty());
70 QVERIFY(!ps2.empty());
71 QCOMPARE(ps2.count(), 3);
72 QCOMPARE(ps2.size(), 3u);
73 QCOMPARE(ps2.coordinates(), c);
74 QhullPoints ps7(3);
75 QCOMPARE(ps7.dimension(), 3);
76 QVERIFY(ps7.isEmpty());
77 QhullPoints ps3(2, 6, c);
78 QCOMPARE(ps3.dimension(), 2);
79 QVERIFY(!ps3.isEmpty());
80 QCOMPARE(ps3.coordinates(), ps2.coordinates());
81 QVERIFY(ps3==ps2);
82 QVERIFY(ps3!=ps);
83 QhullPoints ps4= ps3;
84 QVERIFY(ps4==ps3);
85 // ps4= ps3; //compiler error
86 QhullPoints ps5(ps4);
87 QVERIFY(ps5==ps4);
88 QVERIFY(!(ps5!=ps4));
89 coordT c2[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
90 QhullPoints ps6(2, 6, c2);
91 QVERIFY(ps6==ps2);
92 }//t_construct
93
94 void QhullPoints_test::
t_convert()95 t_convert()
96 {
97 //defineAs tested above
98 coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
99 QhullPoints ps(3, 6, c);
100 QCOMPARE(ps.dimension(), 3);
101 QCOMPARE(ps.size(), 2u);
102 const coordT *c2= ps.constData();
103 QCOMPARE(c, c2);
104 const coordT *c3= ps.data();
105 QCOMPARE(c, c3);
106 coordT *c4= ps.data();
107 QCOMPARE(c, c4);
108 std::vector<QhullPoint> vs= ps.toStdVector();
109 QCOMPARE(vs.size(), 2u);
110 QhullPoint p= vs[1];
111 QCOMPARE(p[2], 5.0);
112 QList<QhullPoint> qs= ps.toQList();
113 QCOMPARE(qs.size(), 2);
114 QhullPoint p2= qs[1];
115 QCOMPARE(p2[2], 5.0);
116 }//t_convert
117
118 void QhullPoints_test::
t_getset()119 t_getset()
120 {
121 //See t_construct for coordinates, count, defineAs, dimension, empty, isempty, ==, !=, size
122 coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
123 QhullPoints ps(3, 6, c);
124 QhullPoints ps2(3, 6, c);
125 QCOMPARE(ps2.dimension(), 3);
126 QCOMPARE(ps2.coordinates(), c);
127 QCOMPARE(ps2.count(), 2);
128 QCOMPARE(ps2.coordinateCount(), 6);
129 coordT c2[]= {-1.0, -2.0, -3.0, -4.0, -5.0, -6.0};
130 ps2.defineAs(6, c2);
131 QCOMPARE(ps2.coordinates(), c2);
132 QCOMPARE(ps2.count(), 2);
133 QCOMPARE(ps2.size(), 2u);
134 QCOMPARE(ps2.dimension(), 3);
135 QVERIFY(!ps2.isEmpty());
136 QVERIFY(ps!=ps2);
137 // ps2= ps; // assignment not available, compiler error
138 ps2.defineAs(ps);
139 QVERIFY(ps==ps2);
140 ps2.setDimension(2);
141 QCOMPARE(ps2.dimension(), 2);
142 QCOMPARE(ps2.coordinates(), c);
143 QVERIFY(!ps2.isEmpty());
144 QCOMPARE(ps2.count(), 3);
145 QCOMPARE(ps2.size(), 3u);
146 QVERIFY(ps!=ps2);
147 QhullPoints ps3(3);
148 ps3.defineAs(5, c2);
149 QCOMPARE(ps3.count(), 1);
150 QCOMPARE(ps3.extraCoordinatesCount(), 2);
151 QCOMPARE(ps3.extraCoordinates()[0], -4.0);
152 QVERIFY(ps3.includesCoordinates(ps3.data()));
153 QVERIFY(ps3.includesCoordinates(ps3.data()+ps3.count()-1));
154 QVERIFY(!ps3.includesCoordinates(ps3.data()-1));
155 QVERIFY(!ps3.includesCoordinates(ps3.data()+ps3.coordinateCount()));
156 }//t_getset
157
158
159 void QhullPoints_test::
t_element()160 t_element()
161 {
162 coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
163 QhullPoints ps(2, 6, c);
164 QhullPoint p(2, c);
165 QCOMPARE(ps[0], p);
166 QCOMPARE(ps.at(1), ps[1]);
167 QCOMPARE(ps.first(), p);
168 QCOMPARE(ps.front(), ps.first());
169 QCOMPARE(ps.last(), ps.at(2));
170 QCOMPARE(ps.back(), ps.last());
171 QhullPoints ps2= ps.mid(2);
172 QCOMPARE(ps2.count(), 1);
173 QhullPoints ps3= ps.mid(3);
174 QVERIFY(ps3.isEmpty());
175 QVERIFY(ps3.empty());
176 QhullPoints ps4= ps.mid(10);
177 QVERIFY(ps4.isEmpty());
178 QhullPoints ps5= ps.mid(-1);
179 QVERIFY(ps5.isEmpty());
180 QhullPoints ps6= ps.mid(1, 1);
181 QCOMPARE(ps6.count(), 1);
182 QCOMPARE(ps6[0], ps[1]);
183 QhullPoints ps7= ps.mid(1, 10);
184 QCOMPARE(ps7.count(), 2);
185 QCOMPARE(ps7[1], ps[2]);
186 QhullPoint p8;
187 QCOMPARE(ps.value(2), ps[2]);
188 QCOMPARE(ps.value(-1), p8);
189 QCOMPARE(ps.value(3), p8);
190 QCOMPARE(ps.value(3, p), p);
191 QVERIFY(ps.value(1, p)!=p);
192 foreach(QhullPoint p9, ps){ // Qt only
193 QCOMPARE(p9.dimension(), 2);
194 QVERIFY(p9[0]==0.0 || p9[0]==2.0 || p9[0]==4.0);
195 }
196 }//t_element
197
198 void QhullPoints_test::
t_iterator()199 t_iterator()
200 {
201 coordT c[]= {0.0, 1.0, 2.0};
202 QhullPoints ps(1, 3, c);
203 QhullPoints::Iterator i(ps);
204 QhullPoints::iterator i2= ps.begin();
205 QVERIFY(i==i2);
206 QVERIFY(i>=i2);
207 QVERIFY(i<=i2);
208 i= ps.begin();
209 QVERIFY(i==i2);
210 i2= ps.end();
211 QVERIFY(i!=i2);
212 QhullPoint p(i); // QhullPoint is the base class for QhullPoints::iterator
213 QCOMPARE(p.dimension(), ps.dimension());
214 QCOMPARE(p.coordinates(), ps.coordinates());
215 i2--;
216 QhullPoint p2= *i2;
217 QCOMPARE(p[0], 0.0);
218 QCOMPARE(p2[0], 2.0);
219 QhullPoints::Iterator i5(i2);
220 QCOMPARE(*i2, *i5);
221 coordT c3[]= {0.0, -1.0, -2.0};
222 QhullPoints::Iterator i3(1, c3);
223 QVERIFY(i!=i3);
224 QCOMPARE(*i, *i3);
225
226 (i3= i)++;
227 QCOMPARE((*i3)[0], 1.0);
228 QCOMPARE(i3->dimension(), 1);
229 QCOMPARE(i3[0][0], 1.0);
230 QCOMPARE(i3[0], ps[1]);
231
232 QVERIFY(i==i);
233 QVERIFY(i!=i2);
234 QVERIFY(i<i2);
235 QVERIFY(i<=i2);
236 QVERIFY(i2>i);
237 QVERIFY(i2>=i);
238
239 QhullPoints::ConstIterator i4(1, c);
240 QVERIFY(i==i4); // iterator COMP const_iterator
241 QVERIFY(i<=i4);
242 QVERIFY(i>=i4);
243 QVERIFY(i4==i); // const_iterator COMP iterator
244 QVERIFY(i4<=i);
245 QVERIFY(i4>=i);
246 QVERIFY(i>=i4);
247 QVERIFY(i4<=i);
248 QVERIFY(i2!=i4);
249 QVERIFY(i2>i4);
250 QVERIFY(i2>=i4);
251 QVERIFY(i4!=i2);
252 QVERIFY(i4<i2);
253 QVERIFY(i4<=i2);
254 ++i4;
255 QVERIFY(i<i4);
256 QVERIFY(i<=i4);
257 QVERIFY(i4>i);
258 QVERIFY(i4>=i);
259
260 i= ps.begin();
261 i2= ps.begin();
262 QCOMPARE(i, i2++);
263 QCOMPARE(*i2, ps[1]);
264 QCOMPARE(++i, i2);
265 QCOMPARE(i, i2--);
266 QCOMPARE(i2, ps.begin());
267 QCOMPARE(--i, i2);
268 QCOMPARE(i2+=3, ps.end());
269 QCOMPARE(i2-=3, ps.begin());
270 QCOMPARE(i2+0, ps.begin());
271 QCOMPARE(i2+3, ps.end());
272 i2 += 3;
273 i= i2-0;
274 QCOMPARE(i, i2);
275 i= i2-3;
276 QCOMPARE(i, ps.begin());
277 QCOMPARE(i2-i, 3);
278
279 //ps.begin end tested above
280
281 // QhullPoints is const-only
282 }//t_iterator
283
284 void QhullPoints_test::
t_const_iterator()285 t_const_iterator()
286 {
287 coordT c[]= {0.0, 1.0, 2.0};
288 const QhullPoints ps(1, 3, c);
289 QhullPoints::ConstIterator i(ps);
290 QhullPoints::const_iterator i2= ps.begin();
291 QVERIFY(i==i2);
292 QVERIFY(i>=i2);
293 QVERIFY(i<=i2);
294 i= ps.begin();
295 QVERIFY(i==i2);
296 i2= ps.end();
297 QVERIFY(i!=i2);
298 QhullPoint p(i);
299 QCOMPARE(p.dimension(), ps.dimension());
300 QCOMPARE(p.coordinates(), ps.coordinates());
301 i2--;
302 QhullPoint p2= *i2;
303 QCOMPARE(p[0], 0.0);
304 QCOMPARE(p2[0], 2.0);
305 QhullPoints::ConstIterator i5(i2);
306 QCOMPARE(*i2, *i5);
307 coordT c3[]= {0.0, -1.0, -2.0};
308 QhullPoints::ConstIterator i3(1, c3);
309 QVERIFY(i!=i3);
310 QCOMPARE(*i, *i3);
311
312 (i3= i)++;
313 QCOMPARE((*i3)[0], 1.0);
314 QCOMPARE(i3->dimension(), 1);
315 QCOMPARE(i3[0][0], 1.0);
316 QCOMPARE(i3[0][0], 1.0);
317 QCOMPARE(i3[0], ps[1]);
318
319 QVERIFY(i==i);
320 QVERIFY(i!=i2);
321 QVERIFY(i<i2);
322 QVERIFY(i<=i2);
323 QVERIFY(i2>i);
324 QVERIFY(i2>=i);
325
326 // See t_iterator for const_iterator COMP iterator
327
328 i= ps.begin();
329 i2= ps.constBegin();
330 QCOMPARE(i, i2++);
331 QCOMPARE(*i2, ps[1]);
332 QCOMPARE(++i, i2);
333 QCOMPARE(i, i2--);
334 QCOMPARE(i2, ps.constBegin());
335 QCOMPARE(--i, i2);
336 QCOMPARE(i2+=3, ps.constEnd());
337 QCOMPARE(i2-=3, ps.constBegin());
338 QCOMPARE(i2+0, ps.constBegin());
339 QCOMPARE(i2+3, ps.constEnd());
340 i2 += 3;
341 i= i2-0;
342 QCOMPARE(i, i2);
343 i= i2-3;
344 QCOMPARE(i, ps.constBegin());
345 QCOMPARE(i2-i, 3);
346
347 // QhullPoints is const-only
348 }//t_const_iterator
349
350
351 void QhullPoints_test::
t_search()352 t_search()
353 {
354 coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 0, 1};
355 QhullPoints ps(2, 8, c); //2-d array of 4 points
356 QhullPoint p= ps.first();
357 QhullPoint p2= ps.last();
358 QVERIFY(ps.contains(p));
359 QVERIFY(ps.contains(p2));
360 QVERIFY(p==p2);
361 QhullPoint p5= ps[2];
362 QVERIFY(p!=p5);
363 QVERIFY(ps.contains(p5));
364 coordT c2[]= {0.0, 1.0, 2.0, 3.0};
365 QhullPoint p3(2, c2); //2-d point
366 QVERIFY(ps.contains(p3));
367 QhullPoint p4(3, c2); //3-d point
368 QVERIFY(!ps.contains(p4));
369 p4.defineAs(2, c); //2-d point
370 QVERIFY(ps.contains(p4));
371 p4.defineAs(2, c+1); //2-d point
372 QVERIFY(!ps.contains(p4));
373 QhullPoint p6(2, c2+2); //2-d point
374 QCOMPARE(ps.count(p), 2);
375 QCOMPARE(ps.count(p2), 2);
376 QCOMPARE(ps.count(p3), 2);
377 QCOMPARE(ps.count(p4), 0);
378 QCOMPARE(ps.count(p6), 1);
379 QCOMPARE(ps.indexOf(&ps[0][0]), 0);
380 //QCOMPARE(ps.indexOf(ps.end()), -1); //ps.end() is a QhullPoint which may match
381 QCOMPARE(ps.indexOf(0), -1);
382 QCOMPARE(ps.indexOf(&ps[3][0]), 3);
383 QCOMPARE(ps.indexOf(&ps[3][1], QhullError::NOthrow), 3);
384 QCOMPARE(ps.indexOf(ps.data()+ps.coordinateCount(), QhullError::NOthrow), -1);
385 QCOMPARE(ps.indexOf(p), 0);
386 QCOMPARE(ps.indexOf(p2), 0);
387 QCOMPARE(ps.indexOf(p3), 0);
388 QCOMPARE(ps.indexOf(p4), -1);
389 QCOMPARE(ps.indexOf(p5), 2);
390 QCOMPARE(ps.indexOf(p6), 1);
391 QCOMPARE(ps.lastIndexOf(p), 3);
392 QCOMPARE(ps.lastIndexOf(p4), -1);
393 QCOMPARE(ps.lastIndexOf(p6), 1);
394 QhullPoints ps2(3);
395 QCOMPARE(ps2.indexOf(ps2.data()), -1);
396 QCOMPARE(ps2.indexOf(ps2.data()+1, QhullError::NOthrow), -1);
397 QCOMPARE(ps2.indexOf(p), -1);
398 QCOMPARE(ps2.lastIndexOf(p), -1);
399 QhullPoints ps3;
400 QCOMPARE(ps3.indexOf(ps3.data()), -1);
401 QCOMPARE(ps3.indexOf(ps3.data()+1, QhullError::NOthrow), -1);
402 QCOMPARE(ps3.indexOf(p), -1);
403 QCOMPARE(ps3.lastIndexOf(p), -1);
404 QhullPoints ps4(2, 0, c);
405 QCOMPARE(ps4.indexOf(p), -1);
406 QCOMPARE(ps4.lastIndexOf(p), -1);
407 }//t_search
408
409 void QhullPoints_test::
t_points_iterator()410 t_points_iterator()
411 {
412 coordT c2[]= {0.0};
413 QhullPoints ps2(0, 0, c2); // 0-dimensional
414 QhullPointsIterator i2= ps2;
415 QVERIFY(!i2.hasNext());
416 QVERIFY(!i2.hasPrevious());
417 i2.toBack();
418 QVERIFY(!i2.hasNext());
419 QVERIFY(!i2.hasPrevious());
420
421 coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
422 QhullPoints ps(3, 6, c); // 3-dimensional
423 QhullPointsIterator i(ps);
424 i2= ps;
425 QVERIFY(i2.hasNext());
426 QVERIFY(!i2.hasPrevious());
427 QVERIFY(i.hasNext());
428 QVERIFY(!i.hasPrevious());
429 i2.toBack();
430 i.toFront();
431 QVERIFY(!i2.hasNext());
432 QVERIFY(i2.hasPrevious());
433 QVERIFY(i.hasNext());
434 QVERIFY(!i.hasPrevious());
435
436 QhullPoint p= ps[0];
437 QhullPoint p2(ps[0]);
438 QCOMPARE(p, p2);
439 QVERIFY(p==p2);
440 QhullPoint p3(ps[1]);
441 // p2[0]= 0.0;
442 QVERIFY(p==p2);
443 QCOMPARE(i2.peekPrevious(), p3);
444 QCOMPARE(i2.previous(), p3);
445 QCOMPARE(i2.previous(), p);
446 QVERIFY(!i2.hasPrevious());
447 QCOMPARE(i.peekNext(), p);
448 // i.peekNext()= 1.0; // compiler error
449 QCOMPARE(i.next(), p);
450 QCOMPARE(i.peekNext(), p3);
451 QCOMPARE(i.next(), p3);
452 QVERIFY(!i.hasNext());
453 i.toFront();
454 QCOMPARE(i.next(), p);
455 }//t_points_iterator
456
457 void QhullPoints_test::
t_io()458 t_io()
459 {
460 QhullPoints ps;
461 ostringstream os;
462 os << "Empty QhullPoints\n" << ps << endl;
463 coordT c[]= {0.0, 1.0, 2.0, 3.0, 4.0, 5.0};
464 QhullPoints ps2(3, 6, c); // 3-dimensional explicit
465 os << "QhullPoints from c[]\n" << ps2 << endl;
466 RboxPoints rcube("c");
467 Qhull q(rcube,"Qt QR0"); // triangulation of rotated unit cube
468 QhullPoints ps3= q.points();
469 os << "QhullPoints\n" << ps3;
470 os << "RunId\n" << ps3.print(q.runId());
471 os << ps3.print(q.runId(), "RunId w/ message\n");
472 os << ps3.printWithIdentifier(q.runId(), "RunId w/ identifiers\n");
473 cout << os.str();
474 QString s= QString::fromStdString(os.str());
475 QCOMPARE(s.count("p"), 3*8+3);
476 // QCOMPARE(s.count(QRegExp("f\\d")), 3*7 + 13*3*2);
477 }//t_io
478
479 }//orgQhull
480
481 #include "moc/QhullPoints_test.moc"
482