1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    TestQuadraticPolygon.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 
16 #include "vtkMath.h"
17 #include "vtkNew.h"
18 #include "vtkObjectFactory.h"
19 #include "vtkPoints.h"
20 #include "vtkPolygon.h"
21 #include "vtkQuadraticPolygon.h"
22 
23 class vtkQuadraticPolygonTest : public vtkQuadraticPolygon
24 {
25 public:
26   static vtkQuadraticPolygonTest *New();
27   vtkTypeMacro(vtkQuadraticPolygonTest, vtkQuadraticPolygon);
28 
29   bool IsClose(double d1, double d2);
30   bool IsClose(double *point1, double *point2);
31 
32   void InitializeCircle();
33   void InitializeSquare();
34   void InitializeSquareWithQuadraticEdge();
35 
36   int TestGetSet();
37   int TestGetPermutations();
38   int TestInitializePolygon();
39   int TestIntersectWithLine();
40   int TestInterpolateFunctions();
41   int TestInterpolateFunctionsUsingMVC();
42 
43   int TestAll();
44 
45 protected:
vtkQuadraticPolygonTest()46   vtkQuadraticPolygonTest() : Tolerance(0.000001) {}
47 private:
48   double Tolerance;
49 };
50 
51 vtkStandardNewMacro(vtkQuadraticPolygonTest);
52 
TestQuadraticPolygon(int,char * [])53 int TestQuadraticPolygon(int, char *[])
54 {
55   vtkNew<vtkQuadraticPolygonTest> test;
56   int result = test->TestAll();
57   cout << ((result == EXIT_SUCCESS) ? "SUCCESS" : "FAILURE") << endl;
58   return result;
59 }
60 
TestAll()61 int vtkQuadraticPolygonTest::TestAll()
62 {
63   int result = EXIT_SUCCESS;
64 
65   this->InitializeSquareWithQuadraticEdge();
66   result |= this->TestGetSet();
67   result |= this->TestGetPermutations();
68   result |= this->TestInitializePolygon();
69   result |= this->TestIntersectWithLine();
70   this->InitializeSquare();
71   result |= this->TestInterpolateFunctions();
72   result |= this->TestInterpolateFunctionsUsingMVC();
73 
74   return result;
75 }
76 
IsClose(double v1,double v2)77 bool vtkQuadraticPolygonTest::IsClose(double v1, double v2)
78 {
79   return (v1 < v2 ? (v2-v1 < this->Tolerance) : (v1-v2 < this->Tolerance));
80 }
81 
IsClose(double * point1,double * point2)82 bool vtkQuadraticPolygonTest::IsClose(double *point1, double *point2)
83 {
84   return (vtkMath::Distance2BetweenPoints(point1, point2) <
85     this->Tolerance * this->Tolerance);
86 }
87 
InitializeSquare()88 void vtkQuadraticPolygonTest::InitializeSquare()
89 {
90   this->GetPointIds()->SetNumberOfIds(8);
91   this->GetPointIds()->SetId(0,0);
92   this->GetPointIds()->SetId(1,1);
93   this->GetPointIds()->SetId(2,2);
94   this->GetPointIds()->SetId(3,3);
95   this->GetPointIds()->SetId(4,4);
96   this->GetPointIds()->SetId(5,5);
97   this->GetPointIds()->SetId(6,6);
98   this->GetPointIds()->SetId(7,7);
99 
100   this->GetPoints()->SetNumberOfPoints(8);
101   this->GetPoints()->SetPoint(0, 0.0, 0.0, 0.0);
102   this->GetPoints()->SetPoint(1, 2.0, 0.0, 0.0);
103   this->GetPoints()->SetPoint(2, 2.0, 2.0, 0.0);
104   this->GetPoints()->SetPoint(3, 0.0, 2.0, 0.0);
105   this->GetPoints()->SetPoint(4, 1.0, 0.0, 0.0);
106   this->GetPoints()->SetPoint(5, 2.0, 1.0, 0.0);
107   this->GetPoints()->SetPoint(6, 1.0, 2.0, 0.0);
108   this->GetPoints()->SetPoint(7, 0.0, 1.0, 0.0);
109 }
110 
InitializeSquareWithQuadraticEdge()111 void vtkQuadraticPolygonTest::InitializeSquareWithQuadraticEdge()
112 {
113   this->InitializeSquare();
114   this->GetPoints()->SetPoint(5, 3.0, 1.0, 0.0);
115 }
116 
TestGetSet()117 int vtkQuadraticPolygonTest::TestGetSet()
118 {
119   if (this->GetCellType() != VTK_QUADRATIC_POLYGON)
120   {
121     cerr << "ERROR:  quadratic polygon type is " << this->GetCellType()
122          << ", should be " << VTK_QUADRATIC_POLYGON << endl;
123     return EXIT_FAILURE;
124   }
125 
126   if (this->GetCellDimension() != 2)
127   {
128     cerr << "ERROR:  quadratic polygon dim is "
129          << this->GetCellDimension()
130          << ", should be 2" << endl;
131     return EXIT_FAILURE;
132   }
133 
134   if (this->GetNumberOfEdges() != 4)
135   {
136     cerr << "ERROR:  quadratic polygon edges number is "
137          << this->GetNumberOfEdges()
138          << ", should be 4" << endl;
139     return EXIT_FAILURE;
140   }
141 
142   if (this->GetNumberOfFaces() != 0)
143   {
144     cerr << "ERROR:  quadratic polygon faces number is "
145          << this->GetNumberOfFaces()
146          << ", should be 0" << endl;
147     return EXIT_FAILURE;
148   }
149 
150   if (this->GetFace(0) != nullptr)
151   {
152     cerr << "ERROR:  quadratic polygon face is " << this->GetFace(0)
153          << ", should be 0" << endl;
154     return EXIT_FAILURE;
155   }
156 
157   if (this->GetEdge(0)->PointIds->GetId(0) != 0)
158   {
159     cerr << "ERROR:  quadratic polygon edge[0] point[0] id is "
160          << this->GetEdge(0)->PointIds->GetId(0)
161          << ", should be 0" << endl;
162     return EXIT_FAILURE;
163   }
164   if (this->GetEdge(0)->PointIds->GetId(1) != 1)
165   {
166     cerr << "ERROR:  quadratic polygon edge[0] point[1] id is "
167          << this->GetEdge(0)->PointIds->GetId(1)
168          << ", should be 1" << endl;
169     return EXIT_FAILURE;
170   }
171   if (this->GetEdge(0)->PointIds->GetId(2) != 4)
172   {
173     cerr << "ERROR:  quadratic polygon edge[0] point[2] id is "
174          << this->GetEdge(0)->PointIds->GetId(2)
175          << ", should be 4" << endl;
176     return EXIT_FAILURE;
177   }
178 
179   if (this->IsPrimaryCell() != 0)
180   {
181     cerr << "ERROR:  quadratic polygon primary boolean is "
182          << this->IsPrimaryCell()
183          << ", should be 0" << endl;
184     return EXIT_FAILURE;
185   }
186 
187   if (!this->GetUseMVCInterpolation())
188   {
189     cerr << "ERROR:  quadratic polygon MVC boolean is "
190          << this->GetUseMVCInterpolation()
191          << ", should be 1" << endl;
192     return EXIT_FAILURE;
193   }
194 
195   this->SetUseMVCInterpolation(false);
196   if (this->GetUseMVCInterpolation())
197   {
198     cerr << "ERROR:  quadratic polygon MVC boolean is "
199          << this->GetUseMVCInterpolation()
200          << ", should be 0" << endl;
201     return EXIT_FAILURE;
202   }
203 
204   return EXIT_SUCCESS;
205 }
206 
TestGetPermutations()207 int vtkQuadraticPolygonTest::TestGetPermutations()
208 {
209   // reference permutation
210   vtkIdType temp[] = { 0, 2, 4, 6, 1, 3, 5, 7 };
211   vtkNew<vtkIdList> permutationToPolygonRef;
212   permutationToPolygonRef->SetNumberOfIds(8);
213   for (vtkIdType i = 0; i < 8; i++)
214   {
215     permutationToPolygonRef->SetId(i, temp[i]);
216   }
217 
218   // computed permutation
219   vtkNew<vtkIdList> permutationToPolygon;
220   vtkQuadraticPolygon::GetPermutationToPolygon(8, permutationToPolygon);
221 
222   // reference permutation
223   vtkIdType temp2[] = { 0, 4, 1, 5, 2, 6, 3, 7 };
224   vtkNew<vtkIdList> permutationFromPolygonRef;
225   permutationFromPolygonRef->SetNumberOfIds(8);
226   for (vtkIdType i = 0; i < 8; i++)
227   {
228     permutationFromPolygonRef->SetId(i, temp2[i]);
229   }
230 
231   // computed permutation
232   vtkNew<vtkIdList> permutationFromPolygon;
233   vtkQuadraticPolygon::GetPermutationFromPolygon(8,
234     permutationFromPolygon);
235 
236   for (vtkIdType i = 0; i < 8; i++)
237   {
238     if (permutationToPolygonRef->GetId(i) != permutationToPolygon->GetId(i))
239     {
240       cerr << "ERROR:  permutation to polygon is wrong" << endl;
241       return EXIT_FAILURE;
242     }
243     if (permutationFromPolygonRef->GetId(i) != permutationFromPolygon->GetId(i))
244     {
245       cerr << "ERROR:  permutation from polygon is wrong" << endl;
246       return EXIT_FAILURE;
247     }
248   }
249 
250   return EXIT_SUCCESS;
251 }
252 
TestInitializePolygon()253 int vtkQuadraticPolygonTest::TestInitializePolygon()
254 {
255   // reference permutation
256   vtkIdType temp[] = { 0, 2, 4, 6, 1, 3, 5, 7 };
257   vtkNew<vtkIdList> permutationToPolygonRef;
258   permutationToPolygonRef->SetNumberOfIds(8);
259   for (vtkIdType i = 0; i < 8; i++)
260   {
261     permutationToPolygonRef->SetId(i, temp[i]);
262   }
263 
264   this->InitializePolygon();
265   vtkPolygon *polygon = this->Polygon;
266 
267   for (vtkIdType i = 0; i < 8; i++)
268   {
269     if (this->GetPointIds()->GetId(i) !=
270          polygon->GetPointIds()->GetId(permutationToPolygonRef->GetId(i)))
271     {
272       cerr << "ERROR:  quadratic polygon point id at index " << i
273            << " is " << this->GetPointIds()->GetId(i)
274            << ", should be "
275            << polygon->GetPointIds()->GetId(permutationToPolygonRef->GetId(i))
276            << endl;
277       return EXIT_FAILURE;
278     }
279     for (int j = 0; j < 3; j++)
280     {
281       if (!this->IsClose( this->GetPoints()->GetPoint(i)[j] ,
282                            polygon->GetPoints()->GetPoint(permutationToPolygonRef->GetId(i))[j]
283                         ))
284       {
285         cerr << "ERROR:  quadratic polygon point at index " << i
286              << " (coord " << j << ") is " << this->GetPoints()->GetPoint(i)[j]
287              << ", should be "
288              << polygon->GetPoints()->GetPoint(permutationToPolygonRef->GetId(i))[j]
289              << endl;
290         return EXIT_FAILURE;
291       }
292     }
293   }
294 
295   return EXIT_SUCCESS;
296 }
297 
TestIntersectWithLine()298 int vtkQuadraticPolygonTest::TestIntersectWithLine()
299 {
300   double t, x[3], pcoords[3];
301   int subId;
302 
303   double p1[3] = { 2.5, 1.0, -1.0 };
304   double p2[3] = { 2.5, 1.0, 1.0 };
305   int intersect = this->IntersectWithLine(p1, p2, 0.0, t, x, pcoords, subId);
306 
307   if (x[0] != 2.5 || x[1] != 1.0 || x[2] != 0.0)
308   {
309     cerr << "ERROR:  vtkQuadraticPolygon::IntersectWithLine returns point ("
310          << x[0] << "," << x[1] << "," << x[2] << ")"
311          << ", should return point (2.5,1.0,0.0)" << endl;
312     return EXIT_FAILURE;
313   }
314 
315   if (!intersect)
316   {
317     cerr << "ERROR:  vtkQuadraticPolygon::IntersectWithLine returns " << intersect
318          << ", should return 1" << endl;
319     return EXIT_FAILURE;
320   }
321 
322   p1[0] = 3.5;
323   p2[0] = 3.5;
324   intersect = this->IntersectWithLine(p1, p2, 0.0, t, x, pcoords, subId);
325 
326   if (intersect)
327   {
328     cerr << "ERROR:  vtkQuadraticPolygon::IntersectWithLine returns " << intersect
329          << ", should return 0" << endl;
330     return EXIT_FAILURE;
331   }
332 
333   return EXIT_SUCCESS;
334 }
335 
TestInterpolateFunctions()336 int vtkQuadraticPolygonTest::TestInterpolateFunctions()
337 {
338   int nbPoints = this->GetNumberOfPoints();
339 
340   double x[3] = { 1.0, 1.0, 0.0 };
341   double *weights = new double[nbPoints];
342   double w1 = 1. / 12.;
343   double w2 = 1. / 6.;
344   this->SetUseMVCInterpolation(false);
345   this->InterpolateFunctions(x, weights);
346 
347   int i;
348   for (i = 0; i < nbPoints/2; i++)
349   {
350     if (!this->IsClose(weights[i],w1))
351     {
352       cerr << "ERROR:  quadratic polygon weights is " << weights[i]
353            << ", should be " << w1 << endl;
354       delete [] weights;
355       return EXIT_FAILURE;
356     }
357   }
358   for ( ; i < nbPoints; i++)
359   {
360     if (!this->IsClose(weights[i],w2))
361     {
362       cerr << "ERROR:  quadratic polygon weights is " << weights[i]
363            << ", should be " << w2 << endl;
364       delete [] weights;
365       return EXIT_FAILURE;
366     }
367   }
368 
369   delete [] weights;
370   return EXIT_SUCCESS;
371 }
372 
TestInterpolateFunctionsUsingMVC()373 int vtkQuadraticPolygonTest::TestInterpolateFunctionsUsingMVC()
374 {
375   int nbPoints = this->GetNumberOfPoints();
376 
377   double x[3] = { 1.0, 1.0, 0.0 };
378   double *weights = new double[nbPoints];
379   double w1 = (sqrt(2.) - 1.) / 4.;
380   double w2 = (sqrt(2.) - 1.) / (2. * sqrt(2.));
381   this->SetUseMVCInterpolation(true);
382   this->InterpolateFunctions(x, weights);
383 
384   int i;
385   for (i = 0; i < nbPoints/2; i++)
386   {
387     if (!this->IsClose(weights[i],w1))
388     {
389       cerr << "ERROR:  quadratic polygon weights is " << weights[i]
390            << ", should be " << w1 << endl;
391       delete [] weights;
392       return EXIT_FAILURE;
393     }
394   }
395   for ( ; i < nbPoints; i++)
396   {
397     if (!this->IsClose(weights[i],w2))
398     {
399       cerr << "ERROR:  quadratic polygon weights is " << weights[i]
400            << ", should be " << w2 << endl;
401       delete [] weights;
402       return EXIT_FAILURE;
403     }
404   }
405 
406   delete [] weights;
407   return EXIT_SUCCESS;
408 }
409