Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkPlaneGeometryTest.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
17 #include "mitkAffineTransform3D.h"
18 #include "mitkBaseGeometry.h"
19 #include "mitkGeometry3D.h"
20 #include "mitkInteractionConst.h"
21 #include "mitkLine.h"
22 #include "mitkPlaneGeometry.h"
23 #include "mitkRotationOperation.h"
24 #include "mitkSlicedGeometry3D.h"
26 
27 #include <mitkTestFixture.h>
28 #include <mitkTestingMacros.h>
29 
30 #include <vnl/vnl_quaternion.h>
31 #include <vnl/vnl_quaternion.txx>
32 
33 #include <fstream>
34 #include <iomanip>
35 
36 static const mitk::ScalarType testEps = 1E-9; // the epsilon used in this test == at least float precision.
37 
38 class mitkPlaneGeometryTestSuite : public mitk::TestFixture
39 {
40  CPPUNIT_TEST_SUITE(mitkPlaneGeometryTestSuite);
41  MITK_TEST(TestInitializeStandardPlane);
42  MITK_TEST(TestProjectPointOntoPlane);
43  MITK_TEST(TestPlaneGeometryCloning);
44  MITK_TEST(TestInheritance);
45  MITK_TEST(TestSetExtendInMM);
46  MITK_TEST(TestRotate);
47  MITK_TEST(TestClone);
48  MITK_TEST(TestPlaneComparison);
49  MITK_TEST(TestAxialInitialization);
50  MITK_TEST(TestFrontalInitialization);
51  MITK_TEST(TestSaggitalInitialization);
52  MITK_TEST(TestLefthandedCoordinateSystem);
53 
54  // Currently commented out, see See bug 15990
55  // MITK_TEST(testPlaneGeometryInitializeOrder);
56  MITK_TEST(TestIntersectionPoint);
57  MITK_TEST(TestCase1210);
58 
59  CPPUNIT_TEST_SUITE_END();
60 
61 private:
62  // private test members that are initialized by setUp()
63  mitk::PlaneGeometry::Pointer planegeometry;
64  mitk::Point3D origin;
65  mitk::Vector3D right, bottom, normal, spacing;
66  mitk::ScalarType width, height;
67  mitk::ScalarType widthInMM, heightInMM, thicknessInMM;
68 
69 public:
70  void setUp() override
71  {
72  planegeometry = mitk::PlaneGeometry::New();
73  width = 100;
74  widthInMM = width;
75  height = 200;
76  heightInMM = height;
77  thicknessInMM = 1.0;
78  mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
79  mitk::FillVector3D(right, widthInMM, 0, 0);
80  mitk::FillVector3D(bottom, 0, heightInMM, 0);
81  mitk::FillVector3D(normal, 0, 0, thicknessInMM);
82  mitk::FillVector3D(spacing, 1.0, 1.0, thicknessInMM);
83 
84  planegeometry->InitializeStandardPlane(right, bottom);
85  planegeometry->SetOrigin(origin);
86  planegeometry->SetSpacing(spacing);
87  }
88 
89  void tearDown() override {}
90  // This test verifies inheritance behaviour, this test will fail if the behaviour changes in the future
91  void TestInheritance()
92  {
94  mitk::Geometry3D::Pointer g3d = dynamic_cast<mitk::Geometry3D *>(plane.GetPointer());
95  CPPUNIT_ASSERT_MESSAGE("Planegeometry should not be castable to Geometry 3D", g3d.IsNull());
96 
97  mitk::BaseGeometry::Pointer base = dynamic_cast<mitk::BaseGeometry *>(plane.GetPointer());
98  CPPUNIT_ASSERT_MESSAGE("Planegeometry should be castable to BaseGeometry", base.IsNotNull());
99 
100  g3d = mitk::Geometry3D::New();
101  base = dynamic_cast<mitk::BaseGeometry *>(g3d.GetPointer());
102  CPPUNIT_ASSERT_MESSAGE("Geometry3D should be castable to BaseGeometry", base.IsNotNull());
103 
105  g3d = dynamic_cast<mitk::Geometry3D *>(sliced.GetPointer());
106  CPPUNIT_ASSERT_MESSAGE("SlicedGeometry3D should not be castable to Geometry3D", g3d.IsNull());
107 
109  plane = dynamic_cast<mitk::PlaneGeometry *>(thin.GetPointer());
110  CPPUNIT_ASSERT_MESSAGE("AbstractTransformGeometry should be castable to PlaneGeometry", plane.IsNotNull());
111 
112  plane = mitk::PlaneGeometry::New();
113  mitk::AbstractTransformGeometry::Pointer atg = dynamic_cast<mitk::AbstractTransformGeometry *>(plane.GetPointer());
114  CPPUNIT_ASSERT_MESSAGE("PlaneGeometry should not be castable to AbstractTransofrmGeometry", atg.IsNull());
115  }
116 
117  void TestLefthandedCoordinateSystem()
118  {
126  planegeometry = mitk::PlaneGeometry::New();
127  width = 100;
128  widthInMM = 5;
129  height = 200;
130  heightInMM = 3;
131  thicknessInMM = 1.0;
132  mitk::FillVector3D(right, widthInMM, 0, 0);
133  mitk::FillVector3D(bottom, 0, heightInMM, 0);
134  // This one negative sign results in lefthanded coordinate orientation and det(matrix) < 0.
135  mitk::FillVector3D(normal, 0, 0, -thicknessInMM);
136 
138 
139  mitk::AffineTransform3D::MatrixType matrix;
140  mitk::AffineTransform3D::MatrixType::InternalMatrixType &vnl_matrix = matrix.GetVnlMatrix();
141 
142  vnl_matrix.set_column(0, right);
143  vnl_matrix.set_column(1, bottom);
144  vnl_matrix.set_column(2, normal);
145 
146  // making sure that we didn't screw up this special test case or else fail deadly:
147  assert(vnl_determinant(vnl_matrix) < 0.0);
148 
149  transform->SetIdentity();
150  transform->SetMatrix(matrix);
151 
152  planegeometry->InitializeStandardPlane(width, height, transform); // Crux of the matter.
153  CPPUNIT_ASSERT_MESSAGE(
154  "Testing if IndexToWorldMatrix is correct after InitializeStandardPlane( width, height, transform ) ",
155  mitk::MatrixEqualElementWise(planegeometry->GetIndexToWorldTransform()->GetMatrix(), matrix));
156 
157  mitk::Point3D p_index;
158  p_index[0] = 10.;
159  p_index[1] = 10.;
160  p_index[2] = 0.;
161  mitk::Point3D p_world;
162  mitk::Point3D p_expectedResult;
163  p_expectedResult[0] = 50.;
164  p_expectedResult[1] = 30.;
165  p_expectedResult[2] = 0.;
166 
167  ((mitk::BaseGeometry::Pointer)planegeometry)->IndexToWorld(p_index, p_world); // Crux of the matter.
168  CPPUNIT_ASSERT_MESSAGE("Testing if IndexToWorld(a,b) function works correctly with lefthanded matrix ",
169  mitk::Equal(p_world, p_expectedResult, testEps));
170  }
171 
172  // See bug 1210
173  // Test does not use standard Parameters
174  void TestCase1210()
175  {
177 
178  mitk::Point3D origin;
179  mitk::Vector3D right, down, spacing;
180 
181  mitk::FillVector3D(origin, 4.5, 7.3, 11.2);
182  mitk::FillVector3D(right, 1.015625, 1.015625, 1.1999969482421875);
183 
184  mitk::FillVector3D(down, 1.4012984643248170709237295832899161312802619418765e-45, 0, 0);
185  mitk::FillVector3D(spacing,
186  0,
187  1.4713633875410579244699160624544119378442750389703e-43,
188  9.2806360452222355258639080851310540729807238879469e-32);
189 
190  std::cout << "Testing InitializeStandardPlane(rightVector, downVector, spacing = NULL): " << std::endl;
191  CPPUNIT_ASSERT_NO_THROW(planegeometry->InitializeStandardPlane(right, down, &spacing));
192  /*
193  std::cout << "Testing width, height and thickness (in units): ";
194  if((mitk::Equal(planegeometry->GetExtent(0),width)==false) ||
195  (mitk::Equal(planegeometry->GetExtent(1),height)==false) ||
196  (mitk::Equal(planegeometry->GetExtent(2),1)==false)
197  )
198  {
199  std::cout<<"[FAILED]"<<std::endl;
200  return EXIT_FAILURE;
201  }
202  std::cout<<"[PASSED]"<<std::endl;
203 
204  std::cout << "Testing width, height and thickness (in mm): ";
205  if((mitk::Equal(planegeometry->GetExtentInMM(0),widthInMM)==false) ||
206  (mitk::Equal(planegeometry->GetExtentInMM(1),heightInMM)==false) ||
207  (mitk::Equal(planegeometry->GetExtentInMM(2),thicknessInMM)==false)
208  )
209  {
210  std::cout<<"[FAILED]"<<std::endl;
211  return EXIT_FAILURE;
212  }
213  */
214  }
215 
232  // Test does not use standard Parameters
233  void TestIntersectionPoint()
234  {
235  // init plane with its parameter
237 
238  mitk::Point3D origin;
239  origin[0] = 0.0;
240  origin[1] = 2.0;
241  origin[2] = 0.0;
242 
243  mitk::Vector3D normal;
244  normal[0] = 0.0;
245  normal[1] = 1.0;
246  normal[2] = 0.0;
247 
248  myPlaneGeometry->InitializePlane(origin, normal);
249 
250  // generate points and line for intersection testing
251  // point distance of given line > 1
252  mitk::Point3D pointP1;
253  pointP1[0] = 2.0;
254  pointP1[1] = 1.0;
255  pointP1[2] = 0.0;
256 
257  mitk::Point3D pointP2;
258  pointP2[0] = 2.0;
259  pointP2[1] = 4.0;
260  pointP2[2] = 0.0;
261 
262  mitk::Vector3D lineDirection;
263  lineDirection[0] = pointP2[0] - pointP1[0];
264  lineDirection[1] = pointP2[1] - pointP1[1];
265  lineDirection[2] = pointP2[2] - pointP1[2];
266 
267  mitk::Line3D xingline(pointP1, lineDirection);
268  mitk::Point3D calcXingPoint;
269  myPlaneGeometry->IntersectionPoint(xingline, calcXingPoint);
270 
271  // point distance of given line < 1
272  mitk::Point3D pointP3;
273  pointP3[0] = 2.0;
274  pointP3[1] = 2.2;
275  pointP3[2] = 0.0;
276 
277  mitk::Point3D pointP4;
278  pointP4[0] = 2.0;
279  pointP4[1] = 1.7;
280  pointP4[2] = 0.0;
281 
282  mitk::Vector3D lineDirection2;
283  lineDirection2[0] = pointP4[0] - pointP3[0];
284  lineDirection2[1] = pointP4[1] - pointP3[1];
285  lineDirection2[2] = pointP4[2] - pointP3[2];
286 
287  mitk::Line3D xingline2(pointP3, lineDirection2);
288  mitk::Point3D calcXingPoint2;
289  myPlaneGeometry->IntersectionPoint(xingline2, calcXingPoint2);
290 
291  // intersection points must be the same
292  CPPUNIT_ASSERT_MESSAGE("Failed to calculate Intersection Point", calcXingPoint == calcXingPoint2);
293  }
294 
300  // Test does not use standard Parameters
301  void TestProjectPointOntoPlane()
302  {
304 
305  // create normal
306  mitk::Vector3D normal;
307  normal[0] = 0.0;
308  normal[1] = 0.0;
309  normal[2] = 1.0;
310 
311  // create origin
312  mitk::Point3D origin;
313  origin[0] = -27.582859;
314  origin[1] = 50;
315  origin[2] = 200.27742;
316 
317  // initialize plane geometry
318  myPlaneGeometry->InitializePlane(origin, normal);
319 
320  // output to descripe the test
321  std::cout << "Testing PlaneGeometry according to bug #3409" << std::endl;
322  std::cout << "Our normal is: " << normal << std::endl;
323  std::cout << "So ALL projected points should have exactly the same z-value!" << std::endl;
324 
325  // create a number of points
326  mitk::Point3D myPoints[5];
327  myPoints[0][0] = -27.582859;
328  myPoints[0][1] = 50.00;
329  myPoints[0][2] = 200.27742;
330 
331  myPoints[1][0] = -26.58662;
332  myPoints[1][1] = 50.00;
333  myPoints[1][2] = 200.19026;
334 
335  myPoints[2][0] = -26.58662;
336  myPoints[2][1] = 50.00;
337  myPoints[2][2] = 200.33124;
338 
339  myPoints[3][0] = 104.58662;
340  myPoints[3][1] = 452.12313;
341  myPoints[3][2] = 866.41236;
342 
343  myPoints[4][0] = -207.58662;
344  myPoints[4][1] = 312.00;
345  myPoints[4][2] = -300.12346;
346 
347  // project points onto plane
348  mitk::Point3D myProjectedPoints[5];
349  for (unsigned int i = 0; i < 5; ++i)
350  {
351  myProjectedPoints[i] = myPlaneGeometry->ProjectPointOntoPlane(myPoints[i]);
352  }
353 
354  // compare z-values with z-value of plane (should be equal)
355  bool allPointsOnPlane = true;
356  for (auto &myProjectedPoint : myProjectedPoints)
357  {
358  if (fabs(myProjectedPoint[2] - origin[2]) > mitk::sqrteps)
359  {
360  allPointsOnPlane = false;
361  }
362  }
363  CPPUNIT_ASSERT_MESSAGE("All points lie not on the same plane", allPointsOnPlane);
364  }
365 
366  void TestPlaneGeometryCloning()
367  {
369 
370  try
371  {
372  mitk::PlaneGeometry::Pointer clone = geometry2D->Clone();
373  itk::Matrix<mitk::ScalarType, 3, 3> matrix = clone->GetIndexToWorldTransform()->GetMatrix();
374  CPPUNIT_ASSERT_MESSAGE("Test if matrix element exists...", matrix[0][0] == 31);
375 
376  double origin = geometry2D->GetOrigin()[0];
377  CPPUNIT_ASSERT_MESSAGE("First Point of origin as expected...", mitk::Equal(origin, 8));
378 
379  double spacing = geometry2D->GetSpacing()[0];
380  CPPUNIT_ASSERT_MESSAGE("First Point of spacing as expected...", mitk::Equal(spacing, 31));
381  }
382  catch (...)
383  {
384  CPPUNIT_FAIL("Error during access on a member of cloned geometry");
385  }
386  // direction [row] [coloum]
387  MITK_TEST_OUTPUT(<< "Casting a rotated 2D ITK Image to a MITK Image and check if Geometry is still same");
388  }
389 
390  void TestPlaneGeometryInitializeOrder()
391  {
392  mitk::Vector3D mySpacing;
393  mySpacing[0] = 31;
394  mySpacing[1] = 0.1;
395  mySpacing[2] = 5.4;
396  mitk::Point3D myOrigin;
397  myOrigin[0] = 8;
398  myOrigin[1] = 9;
399  myOrigin[2] = 10;
401  itk::Matrix<mitk::ScalarType, 3, 3> transMatrix;
402  transMatrix.Fill(0);
403  transMatrix[0][0] = 1;
404  transMatrix[1][1] = 2;
405  transMatrix[2][2] = 4;
406 
407  myTransform->SetMatrix(transMatrix);
408 
410  geometry2D1->SetIndexToWorldTransform(myTransform);
411  geometry2D1->SetSpacing(mySpacing);
412  geometry2D1->SetOrigin(myOrigin);
413 
415  geometry2D2->SetSpacing(mySpacing);
416  geometry2D2->SetOrigin(myOrigin);
417  geometry2D2->SetIndexToWorldTransform(myTransform);
418 
420  geometry2D3->SetIndexToWorldTransform(myTransform);
421  geometry2D3->SetSpacing(mySpacing);
422  geometry2D3->SetOrigin(myOrigin);
423  geometry2D3->SetIndexToWorldTransform(myTransform);
424 
425  CPPUNIT_ASSERT_MESSAGE("Origin of Geometry 1 matches that of Geometry 2.",
426  mitk::Equal(geometry2D1->GetOrigin(), geometry2D2->GetOrigin()));
427  CPPUNIT_ASSERT_MESSAGE("Origin of Geometry 1 match those of Geometry 3.",
428  mitk::Equal(geometry2D1->GetOrigin(), geometry2D3->GetOrigin()));
429  CPPUNIT_ASSERT_MESSAGE("Origin of Geometry 2 match those of Geometry 3.",
430  mitk::Equal(geometry2D2->GetOrigin(), geometry2D3->GetOrigin()));
431 
432  CPPUNIT_ASSERT_MESSAGE("Spacing of Geometry 1 match those of Geometry 2.",
433  mitk::Equal(geometry2D1->GetSpacing(), geometry2D2->GetSpacing()));
434  CPPUNIT_ASSERT_MESSAGE("Spacing of Geometry 1 match those of Geometry 3.",
435  mitk::Equal(geometry2D1->GetSpacing(), geometry2D3->GetSpacing()));
436  CPPUNIT_ASSERT_MESSAGE("Spacing of Geometry 2 match those of Geometry 3.",
437  mitk::Equal(geometry2D2->GetSpacing(), geometry2D3->GetSpacing()));
438 
439  CPPUNIT_ASSERT_MESSAGE("Transformation of Geometry 1 match those of Geometry 2.",
440  compareMatrix(geometry2D1->GetIndexToWorldTransform()->GetMatrix(),
441  geometry2D2->GetIndexToWorldTransform()->GetMatrix()));
442  CPPUNIT_ASSERT_MESSAGE("Transformation of Geometry 1 match those of Geometry 3.",
443  compareMatrix(geometry2D1->GetIndexToWorldTransform()->GetMatrix(),
444  geometry2D3->GetIndexToWorldTransform()->GetMatrix()));
445  CPPUNIT_ASSERT_MESSAGE("Transformation of Geometry 2 match those of Geometry 3.",
446  compareMatrix(geometry2D2->GetIndexToWorldTransform()->GetMatrix(),
447  geometry2D3->GetIndexToWorldTransform()->GetMatrix()));
448  }
449 
450  void TestInitializeStandardPlane()
451  {
452  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: width",
453  mitk::Equal(planegeometry->GetExtent(0), width, testEps));
454  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: height",
455  mitk::Equal(planegeometry->GetExtent(1), height, testEps));
456  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: depth",
457  mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
458 
459  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: width in mm",
460  mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
461  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: heght in mm",
462  mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps));
463  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: depth in mm",
464  mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps));
465 
466  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: AxisVectorRight",
467  mitk::Equal(planegeometry->GetAxisVector(0), right, testEps));
468  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: AxisVectorBottom",
469  mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps));
470  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with default Spacing: AxisVectorNormal",
471  mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps));
472 
473  mitk::Vector3D spacing;
474  thicknessInMM = 1.5;
475  normal.Normalize();
476  normal *= thicknessInMM;
477  mitk::FillVector3D(spacing, 1.0, 1.0, thicknessInMM);
478  planegeometry->InitializeStandardPlane(right.GetVnlVector(), bottom.GetVnlVector(), &spacing);
479 
480  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: width",
481  mitk::Equal(planegeometry->GetExtent(0), width, testEps));
482  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: height",
483  mitk::Equal(planegeometry->GetExtent(1), height, testEps));
484  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: depth",
485  mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
486 
487  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: width in mm",
488  mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
489  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: height in mm",
490  mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps));
491  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: depth in mm",
492  mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps));
493 
494  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: AxisVectorRight",
495  mitk::Equal(planegeometry->GetAxisVector(0), right, testEps));
496  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: AxisVectorBottom",
497  mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps));
498  CPPUNIT_ASSERT_MESSAGE("Testing correct Standard Plane initialization with custom Spacing: AxisVectorNormal",
499  mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps));
500 
501  ;
502  }
503 
504  void TestSetExtendInMM()
505  {
506  normal.Normalize();
507  normal *= thicknessInMM;
508  planegeometry->SetExtentInMM(2, thicknessInMM);
509  CPPUNIT_ASSERT_MESSAGE("Testing SetExtentInMM(2, ...), querying by GetExtentInMM(2): ",
510  mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps));
511  CPPUNIT_ASSERT_MESSAGE("Testing SetExtentInMM(2, ...), querying by GetAxisVector(2) and comparing to normal: ",
512  mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps));
513 
514  planegeometry->SetOrigin(origin);
515  CPPUNIT_ASSERT_MESSAGE("Testing SetOrigin", mitk::Equal(planegeometry->GetOrigin(), origin, testEps));
516 
517  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() after SetOrigin: Right",
518  mitk::Equal(planegeometry->GetAxisVector(0), right, testEps));
519  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() after SetOrigin: Bottom",
520  mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps));
521  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() after SetOrigin: Normal",
522  mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps));
523 
524  mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
525  }
526 
527  void TestRotate()
528  {
529  // Changing the IndexToWorldTransform to a rotated version by SetIndexToWorldTransform() (keep origin):
531  mitk::AffineTransform3D::MatrixType::InternalMatrixType vnlmatrix;
532  vnlmatrix = planegeometry->GetIndexToWorldTransform()->GetMatrix().GetVnlMatrix();
533  mitk::VnlVector axis(3);
534  mitk::FillVector3D(axis, 1.0, 1.0, 1.0);
535  axis.normalize();
536  vnl_quaternion<mitk::ScalarType> rotation(axis, 0.223);
537  vnlmatrix = rotation.rotation_matrix_transpose() * vnlmatrix;
538  mitk::Matrix3D matrix;
539  matrix = vnlmatrix;
540  transform->SetMatrix(matrix);
541  transform->SetOffset(planegeometry->GetIndexToWorldTransform()->GetOffset());
542 
543  right.SetVnlVector(rotation.rotation_matrix_transpose() * right.GetVnlVector());
544  bottom.SetVnlVector(rotation.rotation_matrix_transpose() * bottom.GetVnlVector());
545  normal.SetVnlVector(rotation.rotation_matrix_transpose() * normal.GetVnlVector());
546  planegeometry->SetIndexToWorldTransform(transform);
547 
548  // The origin changed,because m_Origin=m_IndexToWorldTransform->GetOffset()+GetAxisVector(2)*0.5
549  // and the AxisVector changes due to the rotation. In other words: the rotation was done around
550  // the corner of the box, not around the planes origin. Now change it to a rotation around
551  // the origin, simply by re-setting the origin to the original one:
552  planegeometry->SetOrigin(origin);
553 
554  CPPUNIT_ASSERT_MESSAGE("Testing whether SetIndexToWorldTransform kept origin: ",
555  mitk::Equal(planegeometry->GetOrigin(), origin, testEps));
556 
557  mitk::Point2D point;
558  point[0] = 4;
559  point[1] = 3;
560  mitk::Point2D dummy;
561  planegeometry->WorldToIndex(point, dummy);
562  planegeometry->IndexToWorld(dummy, dummy);
563  CPPUNIT_ASSERT_MESSAGE("Testing consistency of index and world coordinates.", dummy == point);
564 
565  CPPUNIT_ASSERT_MESSAGE("Testing width of rotated version: ",
566  mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
567  CPPUNIT_ASSERT_MESSAGE("Testing height of rotated version: ",
568  mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps));
569  CPPUNIT_ASSERT_MESSAGE("Testing thickness of rotated version: ",
570  mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps));
571 
572  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of rotated version: right ",
573  mitk::Equal(planegeometry->GetAxisVector(0), right, testEps));
574  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of rotated version: bottom",
575  mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps));
576  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of rotated version: normal",
577  mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps));
578 
579  CPPUNIT_ASSERT_MESSAGE(
580  "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ",
581  mitk::Equal(planegeometry->GetAxisVector(0).GetNorm(), planegeometry->GetExtentInMM(0), testEps));
582  CPPUNIT_ASSERT_MESSAGE(
583  "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ",
584  mitk::Equal(planegeometry->GetAxisVector(1).GetNorm(), planegeometry->GetExtentInMM(1), testEps));
585  CPPUNIT_ASSERT_MESSAGE(
586  "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ",
587  mitk::Equal(planegeometry->GetAxisVector(2).GetNorm(), planegeometry->GetExtentInMM(2), testEps));
588 
589  mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
590 
591  width *= 2;
592  height *= 3;
593  planegeometry->SetSizeInUnits(width, height);
594  CPPUNIT_ASSERT_MESSAGE("Testing SetSizeInUnits() of rotated version: ",
595  mitk::Equal(planegeometry->GetExtent(0), width, testEps));
596  CPPUNIT_ASSERT_MESSAGE("Testing SetSizeInUnits() of rotated version: ",
597  mitk::Equal(planegeometry->GetExtent(1), height, testEps));
598  CPPUNIT_ASSERT_MESSAGE("Testing SetSizeInUnits() of rotated version: ",
599  mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
600 
601  CPPUNIT_ASSERT_MESSAGE("Testing width (in mm) of version with changed size in units: ",
602  mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
603  CPPUNIT_ASSERT_MESSAGE("Testing height (in mm) of version with changed size in units: ",
604  mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps));
605  CPPUNIT_ASSERT_MESSAGE("Testing thickness (in mm) of version with changed size in units: ",
606  mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps));
607 
608  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of version with changed size in units: right ",
609  mitk::Equal(planegeometry->GetAxisVector(0), right, testEps));
610  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of version with changed size in units: bottom",
611  mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps));
612  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of version with changed size in units: normal",
613  mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps));
614 
615  CPPUNIT_ASSERT_MESSAGE(
616  "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ",
617  mitk::Equal(planegeometry->GetAxisVector(0).GetNorm(), planegeometry->GetExtentInMM(0), testEps));
618  CPPUNIT_ASSERT_MESSAGE(
619  "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ",
620  mitk::Equal(planegeometry->GetAxisVector(1).GetNorm(), planegeometry->GetExtentInMM(1), testEps));
621  CPPUNIT_ASSERT_MESSAGE(
622  "Testing GetAxisVector(direction).GetNorm() != planegeometry->GetExtentInMM(direction) of rotated version: ",
623  mitk::Equal(planegeometry->GetAxisVector(2).GetNorm(), planegeometry->GetExtentInMM(2), testEps));
624 
625  mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
626  }
627 
628  void TestClone()
629  {
630  mitk::PlaneGeometry::Pointer clonedplanegeometry =
631  dynamic_cast<mitk::PlaneGeometry *>(planegeometry->Clone().GetPointer());
632  // Cave: Statement below is negated!
633  CPPUNIT_ASSERT_MESSAGE("Testing Clone(): ",
634  !((clonedplanegeometry.IsNull()) || (clonedplanegeometry->GetReferenceCount() != 1)));
635  CPPUNIT_ASSERT_MESSAGE("Testing origin of cloned version: ",
636  mitk::Equal(clonedplanegeometry->GetOrigin(), origin, testEps));
637 
638  CPPUNIT_ASSERT_MESSAGE("Testing width (in units) of cloned version: ",
639  mitk::Equal(clonedplanegeometry->GetExtent(0), width, testEps));
640  CPPUNIT_ASSERT_MESSAGE("Testing height (in units) of cloned version: ",
641  mitk::Equal(clonedplanegeometry->GetExtent(1), height, testEps));
642  CPPUNIT_ASSERT_MESSAGE("Testing extent (in units) of cloned version: ",
643  mitk::Equal(clonedplanegeometry->GetExtent(2), 1, testEps));
644 
645  CPPUNIT_ASSERT_MESSAGE("Testing width (in mm) of cloned version: ",
646  mitk::Equal(clonedplanegeometry->GetExtentInMM(0), widthInMM, testEps));
647  CPPUNIT_ASSERT_MESSAGE("Testing height (in mm) of cloned version: ",
648  mitk::Equal(clonedplanegeometry->GetExtentInMM(1), heightInMM, testEps));
649  CPPUNIT_ASSERT_MESSAGE("Testing thickness (in mm) of cloned version: ",
650  mitk::Equal(clonedplanegeometry->GetExtentInMM(2), thicknessInMM, testEps));
651 
652  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of cloned version: right",
653  mitk::Equal(clonedplanegeometry->GetAxisVector(0), right, testEps));
654  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of cloned version: bottom",
655  mitk::Equal(clonedplanegeometry->GetAxisVector(1), bottom, testEps));
656  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of cloned version: normal",
657  mitk::Equal(clonedplanegeometry->GetAxisVector(2), normal, testEps));
658 
659  mappingTests2D(clonedplanegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
660  }
661 
662  void TestSaggitalInitialization()
663  {
664  mitk::Point3D cornerpoint0 = planegeometry->GetCornerPoint(0);
665  mitk::PlaneGeometry::Pointer clonedplanegeometry = planegeometry->Clone();
666 
667  // Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Sagittal, zPosition = 0, frontside=true):
668  planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Sagittal);
669 
670  mitk::Vector3D newright, newbottom, newnormal;
671  mitk::ScalarType newthicknessInMM;
672 
673  newright = bottom;
674  newthicknessInMM = widthInMM / width * 1.0; // extent in normal direction is 1;
675  newnormal = right;
676  newnormal.Normalize();
677  newnormal *= newthicknessInMM;
678  newbottom = normal;
679  newbottom.Normalize();
680  newbottom *= thicknessInMM;
681 
682  CPPUNIT_ASSERT_MESSAGE("Testing GetCornerPoint(0) of sagitally initialized version:",
683  mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0, testEps));
684 
685  // ok, corner was fine, so we can dare to believe the origin is ok.
686  origin = planegeometry->GetOrigin();
687 
688  CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of sagitally initialized version: ",
689  mitk::Equal(planegeometry->GetExtent(0), height, testEps));
690  CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of sagitally initialized version: ",
691  mitk::Equal(planegeometry->GetExtent(1), 1, testEps));
692  CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of sagitally initialized version: ",
693  mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
694 
695  CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of sagitally initialized version: ",
696  mitk::Equal(planegeometry->GetExtentInMM(0), heightInMM, testEps));
697  CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of sagitally initialized version: ",
698  mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps));
699  CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of sagitally initialized version: ",
700  mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM, testEps));
701 
702  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of sagitally initialized version: ",
703  mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps));
704  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of sagitally initialized version: ",
705  mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps));
706  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of sagitally initialized version: ",
707  mitk::Equal(planegeometry->GetAxisVector(2), newnormal, testEps));
708 
709  mappingTests2D(planegeometry, height, 1, heightInMM, thicknessInMM, origin, newright, newbottom);
710 
711  // set origin back to the one of the axial slice:
712  origin = clonedplanegeometry->GetOrigin();
713  // Testing backside initialization: InitializeStandardPlane(clonedplanegeometry, planeorientation = Axial, zPosition
714  // = 0, frontside=false, rotated=true):
715  planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Axial, 0, false, true);
716  mitk::Point3D backsideorigin;
717  backsideorigin = origin + clonedplanegeometry->GetAxisVector(1); //+clonedplanegeometry->GetAxisVector(2);
718 
719  CPPUNIT_ASSERT_MESSAGE("Testing origin of backsidedly, axially initialized version: ",
720  mitk::Equal(planegeometry->GetOrigin(), backsideorigin, testEps));
721 
722  mitk::Point3D backsidecornerpoint0;
723  backsidecornerpoint0 =
724  cornerpoint0 + clonedplanegeometry->GetAxisVector(1); //+clonedplanegeometry->GetAxisVector(2);
725  CPPUNIT_ASSERT_MESSAGE("Testing GetCornerPoint(0) of sagitally initialized version: ",
726  mitk::Equal(planegeometry->GetCornerPoint(0), backsidecornerpoint0, testEps));
727 
728  CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of backsidedly, axially initialized version "
729  "(should be same as in mm due to unit spacing, except for thickness, which is always 1): ",
730  mitk::Equal(planegeometry->GetExtent(0), width, testEps));
731  CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of backsidedly, axially initialized version "
732  "(should be same as in mm due to unit spacing, except for thickness, which is always 1): ",
733  mitk::Equal(planegeometry->GetExtent(1), height, testEps));
734  CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in units) of backsidedly, axially initialized version "
735  "(should be same as in mm due to unit spacing, except for thickness, which is always 1): ",
736  mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
737 
738  CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of backsidedly, axially initialized version: ",
739  mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
740  CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of backsidedly, axially initialized version: ",
741  mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps));
742  CPPUNIT_ASSERT_MESSAGE("Testing width, height and thickness (in mm) of backsidedly, axially initialized version: ",
743  mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps));
744 
745  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of backsidedly, axially initialized version: ",
746  mitk::Equal(planegeometry->GetAxisVector(0), right, testEps));
747  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of backsidedly, axially initialized version: ",
748  mitk::Equal(planegeometry->GetAxisVector(1), -bottom, testEps));
749  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of backsidedly, axially initialized version: ",
750  mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps)); // T22254: Flipped sign
751 
752  mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, backsideorigin, right, -bottom);
753  }
754 
755  void TestFrontalInitialization()
756  {
757  mitk::Point3D cornerpoint0 = planegeometry->GetCornerPoint(0);
758 
759  mitk::PlaneGeometry::Pointer clonedplanegeometry =
760  dynamic_cast<mitk::PlaneGeometry *>(planegeometry->Clone().GetPointer());
761  //--------
762 
763  mitk::Vector3D newright, newbottom, newnormal;
764  mitk::ScalarType newthicknessInMM;
765 
766  // Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Frontal, zPosition = 0, frontside=true)
767  planegeometry->InitializeStandardPlane(clonedplanegeometry, mitk::PlaneGeometry::Frontal);
768  newright = right;
769  newbottom = normal;
770  newbottom.Normalize();
771  newbottom *= thicknessInMM;
772  newthicknessInMM = heightInMM / height * 1.0 /*extent in normal direction is 1*/;
773  newnormal = -bottom;
774  newnormal.Normalize();
775  newnormal *= newthicknessInMM;
776 
777  CPPUNIT_ASSERT_MESSAGE("Testing GetCornerPoint(0) of frontally initialized version: ",
778  mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0, testEps));
779 
780  // ok, corner was fine, so we can dare to believe the origin is ok.
781  origin = planegeometry->GetOrigin();
782 
783  CPPUNIT_ASSERT_MESSAGE("Testing width (in units) of frontally initialized version: ",
784  mitk::Equal(planegeometry->GetExtent(0), width, testEps));
785  CPPUNIT_ASSERT_MESSAGE("Testing height (in units) of frontally initialized version: ",
786  mitk::Equal(planegeometry->GetExtent(1), 1, testEps));
787  CPPUNIT_ASSERT_MESSAGE("Testing thickness (in units) of frontally initialized version: ",
788  mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
789 
790  CPPUNIT_ASSERT_MESSAGE("Testing width (in mm) of frontally initialized version: ",
791  mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
792  CPPUNIT_ASSERT_MESSAGE("Testing height (in mm) of frontally initialized version: ",
793  mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps));
794  CPPUNIT_ASSERT_MESSAGE("Testing thickness (in mm) of frontally initialized version: ",
795  mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM, testEps));
796 
797  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of frontally initialized version: ",
798  mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps));
799  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of frontally initialized version: ",
800  mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps));
801  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of frontally initialized version: ",
802  mitk::Equal(planegeometry->GetAxisVector(2), -newnormal, testEps)); // T22254: Flipped sign
803 
804  mappingTests2D(planegeometry, width, 1, widthInMM, thicknessInMM, origin, newright, newbottom);
805 
806  // Changing plane to in-plane unit spacing using SetSizeInUnits:
807  planegeometry->SetSizeInUnits(planegeometry->GetExtentInMM(0), planegeometry->GetExtentInMM(1));
808 
809  CPPUNIT_ASSERT_MESSAGE("Testing origin of unit spaced, frontally initialized version: ",
810  mitk::Equal(planegeometry->GetOrigin(), origin, testEps));
811 
812  CPPUNIT_ASSERT_MESSAGE(
813  "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ",
814  mitk::Equal(planegeometry->GetExtent(0), widthInMM, testEps));
815  CPPUNIT_ASSERT_MESSAGE(
816  "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ",
817  mitk::Equal(planegeometry->GetExtent(1), thicknessInMM, testEps));
818  CPPUNIT_ASSERT_MESSAGE(
819  "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ",
820  mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
821 
822  CPPUNIT_ASSERT_MESSAGE(
823  "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ",
824  mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
825  CPPUNIT_ASSERT_MESSAGE(
826  "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ",
827  mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps));
828  CPPUNIT_ASSERT_MESSAGE(
829  "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ",
830  mitk::Equal(planegeometry->GetExtentInMM(2), newthicknessInMM, testEps));
831 
832  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ",
833  mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps));
834  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ",
835  mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps));
836  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ",
837  mitk::Equal(planegeometry->GetAxisVector(2), -newnormal, testEps)); // T22254: Flipped sign
838 
839  mappingTests2D(planegeometry, widthInMM, thicknessInMM, widthInMM, thicknessInMM, origin, newright, newbottom);
840 
841  // Changing plane to unit spacing also in normal direction using SetExtentInMM(2, 1.0):
842  planegeometry->SetExtentInMM(2, 1.0);
843  newnormal.Normalize();
844 
845  CPPUNIT_ASSERT_MESSAGE("Testing origin of unit spaced, frontally initialized version: ",
846  mitk::Equal(planegeometry->GetOrigin(), origin, testEps));
847 
848  CPPUNIT_ASSERT_MESSAGE(
849  "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ",
850  mitk::Equal(planegeometry->GetExtent(0), widthInMM, testEps));
851  CPPUNIT_ASSERT_MESSAGE(
852  "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ",
853  mitk::Equal(planegeometry->GetExtent(1), thicknessInMM, testEps));
854  CPPUNIT_ASSERT_MESSAGE(
855  "Testing width, height and thickness (in units) of unit spaced, frontally initialized version: ",
856  mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
857 
858  CPPUNIT_ASSERT_MESSAGE(
859  "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ",
860  mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
861  CPPUNIT_ASSERT_MESSAGE(
862  "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ",
863  mitk::Equal(planegeometry->GetExtentInMM(1), thicknessInMM, testEps));
864  CPPUNIT_ASSERT_MESSAGE(
865  "Testing width, height and thickness (in mm) of unit spaced, frontally initialized version: ",
866  mitk::Equal(planegeometry->GetExtentInMM(2), 1.0, testEps));
867 
868  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ",
869  mitk::Equal(planegeometry->GetAxisVector(0), newright, testEps));
870  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ",
871  mitk::Equal(planegeometry->GetAxisVector(1), newbottom, testEps));
872  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of unit spaced, frontally initialized version: ",
873  mitk::Equal(planegeometry->GetAxisVector(2), -newnormal, testEps)); // T22254: Flipped sign
874  mappingTests2D(planegeometry, widthInMM, thicknessInMM, widthInMM, thicknessInMM, origin, newright, newbottom);
875  }
876 
877  void TestAxialInitialization()
878  {
879  mitk::Point3D cornerpoint0 = planegeometry->GetCornerPoint(0);
880 
881  // Clone, move, rotate and test for 'IsParallel' and 'IsOnPlane'
882  mitk::PlaneGeometry::Pointer clonedplanegeometry =
883  dynamic_cast<mitk::PlaneGeometry *>(planegeometry->Clone().GetPointer());
884 
885  CPPUNIT_ASSERT_MESSAGE("Testing Clone(): ",
886  !((clonedplanegeometry.IsNull()) || (clonedplanegeometry->GetReferenceCount() != 1)));
887 
888  std::cout << "Testing InitializeStandardPlane(clonedplanegeometry, planeorientation = Axial, zPosition = 0, "
889  "frontside=true): "
890  << std::endl;
891  planegeometry->InitializeStandardPlane(clonedplanegeometry);
892 
893  CPPUNIT_ASSERT_MESSAGE("Testing origin of axially initialized version: ",
894  mitk::Equal(planegeometry->GetOrigin(), origin));
895 
896  CPPUNIT_ASSERT_MESSAGE("Testing GetCornerPoint(0) of axially initialized version: ",
897  mitk::Equal(planegeometry->GetCornerPoint(0), cornerpoint0));
898 
899  CPPUNIT_ASSERT_MESSAGE("Testing width (in units) of axially initialized version (should be same as in mm due to "
900  "unit spacing, except for thickness, which is always 1): ",
901  mitk::Equal(planegeometry->GetExtent(0), width, testEps));
902  CPPUNIT_ASSERT_MESSAGE("Testing height (in units) of axially initialized version (should be same as in mm due to "
903  "unit spacing, except for thickness, which is always 1): ",
904  mitk::Equal(planegeometry->GetExtent(1), height, testEps));
905  CPPUNIT_ASSERT_MESSAGE("Testing thickness (in units) of axially initialized version (should be same as in mm due "
906  "to unit spacing, except for thickness, which is always 1): ",
907  mitk::Equal(planegeometry->GetExtent(2), 1, testEps));
908 
909  CPPUNIT_ASSERT_MESSAGE("Testing width (in mm) of axially initialized version: ",
910  mitk::Equal(planegeometry->GetExtentInMM(0), widthInMM, testEps));
911  CPPUNIT_ASSERT_MESSAGE("Testing height (in mm) of axially initialized version: ",
912  mitk::Equal(planegeometry->GetExtentInMM(1), heightInMM, testEps));
913  CPPUNIT_ASSERT_MESSAGE("Testing thickness (in mm) of axially initialized version: ",
914  mitk::Equal(planegeometry->GetExtentInMM(2), thicknessInMM, testEps));
915 
916  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of axially initialized version: ",
917  mitk::Equal(planegeometry->GetAxisVector(0), right, testEps));
918  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of axially initialized version: ",
919  mitk::Equal(planegeometry->GetAxisVector(1), bottom, testEps));
920  CPPUNIT_ASSERT_MESSAGE("Testing GetAxisVector() of axially initialized version: ",
921  mitk::Equal(planegeometry->GetAxisVector(2), normal, testEps));
922 
923  mappingTests2D(planegeometry, width, height, widthInMM, heightInMM, origin, right, bottom);
924  }
925 
926  void TestPlaneComparison()
927  {
928  // Clone, move, rotate and test for 'IsParallel' and 'IsOnPlane'
929  mitk::PlaneGeometry::Pointer clonedplanegeometry2 =
930  dynamic_cast<mitk::PlaneGeometry *>(planegeometry->Clone().GetPointer());
931 
932  CPPUNIT_ASSERT_MESSAGE("Testing Clone(): ",
933  !((clonedplanegeometry2.IsNull()) || (clonedplanegeometry2->GetReferenceCount() != 1)));
934  CPPUNIT_ASSERT_MESSAGE("Testing wheter original and clone are at the same position",
935  clonedplanegeometry2->IsOnPlane(planegeometry.GetPointer()));
936  CPPUNIT_ASSERT_MESSAGE(" Asserting that origin is on the plane cloned plane:",
937  clonedplanegeometry2->IsOnPlane(origin));
938 
939  mitk::VnlVector newaxis(3);
940  mitk::FillVector3D(newaxis, 1.0, 1.0, 1.0);
941  newaxis.normalize();
942  vnl_quaternion<mitk::ScalarType> rotation2(newaxis, 0.0);
943 
944  mitk::Vector3D clonednormal = clonedplanegeometry2->GetNormal();
945  mitk::Point3D clonedorigin = clonedplanegeometry2->GetOrigin();
946 
947  auto planerot = new mitk::RotationOperation(mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector(0), 180.0);
948 
949  clonedplanegeometry2->ExecuteOperation(planerot);
950  CPPUNIT_ASSERT_MESSAGE(" Asserting that a flipped plane is still on the original plane: ",
951  clonedplanegeometry2->IsOnPlane(planegeometry.GetPointer()));
952 
953  clonedorigin += clonednormal;
954  clonedplanegeometry2->SetOrigin(clonedorigin);
955 
956  CPPUNIT_ASSERT_MESSAGE("Testing if the translated (cloned, flipped) plane is parallel to its origin plane: ",
957  clonedplanegeometry2->IsParallel(planegeometry));
958  delete planerot;
959 
960  planerot = new mitk::RotationOperation(mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector(0), 0.5);
961  clonedplanegeometry2->ExecuteOperation(planerot);
962 
963  CPPUNIT_ASSERT_MESSAGE("Testing if a non-paralell plane gets recognized as not paralell [rotation +0.5 degree] : ",
964  !clonedplanegeometry2->IsParallel(planegeometry));
965  delete planerot;
966 
967  planerot = new mitk::RotationOperation(mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector(0), -1.0);
968  clonedplanegeometry2->ExecuteOperation(planerot);
969 
970  CPPUNIT_ASSERT_MESSAGE("Testing if a non-paralell plane gets recognized as not paralell [rotation -0.5 degree] : ",
971  !clonedplanegeometry2->IsParallel(planegeometry));
972  delete planerot;
973 
974  planerot = new mitk::RotationOperation(mitk::OpROTATE, origin, clonedplanegeometry2->GetAxisVector(0), 360.5);
975  clonedplanegeometry2->ExecuteOperation(planerot);
976 
977  CPPUNIT_ASSERT_MESSAGE("Testing if a non-paralell plane gets recognized as paralell [rotation 360 degree] : ",
978  clonedplanegeometry2->IsParallel(planegeometry));
979  }
980 
981 private:
982  // helper Methods for the Tests
983 
985  {
986  mitk::Vector3D mySpacing;
987  mySpacing[0] = 31;
988  mySpacing[1] = 0.1;
989  mySpacing[2] = 5.4;
990  mitk::Point3D myOrigin;
991  myOrigin[0] = 8;
992  myOrigin[1] = 9;
993  myOrigin[2] = 10;
995  itk::Matrix<mitk::ScalarType, 3, 3> transMatrix;
996  transMatrix.Fill(0);
997  transMatrix[0][0] = 1;
998  transMatrix[1][1] = 2;
999  transMatrix[2][2] = 4;
1000 
1001  myTransform->SetMatrix(transMatrix);
1002 
1004  geometry2D->SetIndexToWorldTransform(myTransform);
1005  geometry2D->SetSpacing(mySpacing);
1006  geometry2D->SetOrigin(myOrigin);
1007  return geometry2D;
1008  }
1009 
1010  bool compareMatrix(itk::Matrix<mitk::ScalarType, 3, 3> left, itk::Matrix<mitk::ScalarType, 3, 3> right)
1011  {
1012  bool equal = true;
1013  for (int i = 0; i < 3; ++i)
1014  for (int j = 0; j < 3; ++j)
1015  equal &= mitk::Equal(left[i][j], right[i][j]);
1016  return equal;
1017  }
1018 
1022  void mappingTests2D(const mitk::PlaneGeometry *planegeometry,
1023  const mitk::ScalarType &width,
1024  const mitk::ScalarType &height,
1025  const mitk::ScalarType &widthInMM,
1026  const mitk::ScalarType &heightInMM,
1027  const mitk::Point3D &origin,
1028  const mitk::Vector3D &right,
1029  const mitk::Vector3D &bottom)
1030  {
1031  std::cout << "Testing mapping Map(pt2d_mm(x=widthInMM/2.3,y=heightInMM/2.5), pt3d_mm) and compare with expected: ";
1032  mitk::Point2D pt2d_mm;
1033  mitk::Point3D pt3d_mm, expected_pt3d_mm;
1034  pt2d_mm[0] = widthInMM / 2.3;
1035  pt2d_mm[1] = heightInMM / 2.5;
1036  expected_pt3d_mm = origin + right * (pt2d_mm[0] / right.GetNorm()) + bottom * (pt2d_mm[1] / bottom.GetNorm());
1037  planegeometry->Map(pt2d_mm, pt3d_mm);
1038  CPPUNIT_ASSERT_MESSAGE(
1039  "Testing mapping Map(pt2d_mm(x=widthInMM/2.3,y=heightInMM/2.5), pt3d_mm) and compare with expected",
1040  mitk::Equal(pt3d_mm, expected_pt3d_mm, testEps));
1041 
1042  std::cout << "Testing mapping Map(pt3d_mm, pt2d_mm) and compare with expected: ";
1043  mitk::Point2D testpt2d_mm;
1044  planegeometry->Map(pt3d_mm, testpt2d_mm);
1045  std::cout << std::setprecision(12) << "Expected pt2d_mm " << pt2d_mm << std::endl;
1046  std::cout << std::setprecision(12) << "Result testpt2d_mm " << testpt2d_mm << std::endl;
1047  std::cout << std::setprecision(12) << "10*mitk::eps " << 10 * mitk::eps << std::endl;
1048  // This eps is temporarily set to 10*mitk::eps. See bug #15037 for details.
1049  CPPUNIT_ASSERT_MESSAGE("Testing mapping Map(pt3d_mm, pt2d_mm) and compare with expected",
1050  mitk::Equal(pt2d_mm, testpt2d_mm, 10 * mitk::eps));
1051 
1052  std::cout << "Testing IndexToWorld(pt2d_units, pt2d_mm) and compare with expected: ";
1053  mitk::Point2D pt2d_units;
1054  pt2d_units[0] = width / 2.0;
1055  pt2d_units[1] = height / 2.0;
1056  pt2d_mm[0] = widthInMM / 2.0;
1057  pt2d_mm[1] = heightInMM / 2.0;
1058  planegeometry->IndexToWorld(pt2d_units, testpt2d_mm);
1059  std::cout << std::setprecision(12) << "Expected pt2d_mm " << pt2d_mm << std::endl;
1060  std::cout << std::setprecision(12) << "Result testpt2d_mm " << testpt2d_mm << std::endl;
1061  std::cout << std::setprecision(12) << "10*mitk::eps " << 10 * mitk::eps << std::endl;
1062  // This eps is temporarily set to 10*mitk::eps. See bug #15037 for details.
1063  CPPUNIT_ASSERT_MESSAGE("Testing IndexToWorld(pt2d_units, pt2d_mm) and compare with expected: ",
1064  mitk::Equal(pt2d_mm, testpt2d_mm, 10 * mitk::eps));
1065 
1066  std::cout << "Testing WorldToIndex(pt2d_mm, pt2d_units) and compare with expected: ";
1067  mitk::Point2D testpt2d_units;
1068  planegeometry->WorldToIndex(pt2d_mm, testpt2d_units);
1069 
1070  std::cout << std::setprecision(12) << "Expected pt2d_units " << pt2d_units << std::endl;
1071  std::cout << std::setprecision(12) << "Result testpt2d_units " << testpt2d_units << std::endl;
1072  std::cout << std::setprecision(12) << "10*mitk::eps " << 10 * mitk::eps << std::endl;
1073  // This eps is temporarily set to 10*mitk::eps. See bug #15037 for details.
1074  CPPUNIT_ASSERT_MESSAGE("Testing WorldToIndex(pt2d_mm, pt2d_units) and compare with expected:",
1075  mitk::Equal(pt2d_units, testpt2d_units, 10 * mitk::eps));
1076  }
1077 };
1078 MITK_TEST_SUITE_REGISTRATION(mitkPlaneGeometry)
Descibes a line.
Definition: mitkLine.h:32
itk::SmartPointer< Self > Pointer
Standard implementation of BaseGeometry.
MITK_TEST_SUITE_REGISTRATION(mitkImageToItk)
bool MatrixEqualElementWise(const vnl_matrix_fixed< TCoordRep, NRows, NCols > &matrix1, const vnl_matrix_fixed< TCoordRep, NRows, NCols > &matrix2, mitk::ScalarType epsilon=mitk::eps)
Check for element-wise matrix equality with a user defined accuracy.
Definition: mitkMatrix.h:144
static Pointer New()
virtual bool Map(const mitk::Point3D &pt3d_mm, mitk::Point2D &pt2d_mm) const
Project a 3D point given in mm (pt3d_mm) onto the 2D geometry. The result is a 2D point in mm (pt2d_m...
vnl_vector< ScalarType > VnlVector
Definition: mitkVector.h:138
double ScalarType
#define MITK_TEST(TESTMETHOD)
Adds a test to the current test suite.
static Pointer New()
Constants for most interaction classes, due to the generic StateMachines.
static Matrix3D rotation
virtual void WorldToIndex(const Point2D &pt_mm, Point2D &pt_units) const
virtual void IndexToWorld(const Point2D &pt_units, Point2D &pt_mm) const
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
Definition: mitkArray.h:110
itk::SmartPointer< Self > Pointer
#define MITK_TEST_OUTPUT(x)
Output some text.
static void clone(T *&dst, S *src, int n)
Definition: svm.cpp:73
Test fixture for parameterized tests.
Describes a geometry defined by an vtkAbstractTransform and a plane.
static mitk::PlaneGeometry::Pointer createPlaneGeometry()
static const mitk::ScalarType testEps
MITKCORE_EXPORT const ScalarType sqrteps
MITKNEWMODULE_EXPORT bool Equal(mitk::ExampleDataStructure *leftHandSide, mitk::ExampleDataStructure *rightHandSide, mitk::ScalarType eps, bool verbose)
Returns true if the example data structures are considered equal.
static Pointer New()
MITKCORE_EXPORT const ScalarType eps
Describes a two-dimensional, rectangular plane.
Operation, that holds everything necessary for an rotation operation on mitk::BaseData.
BaseGeometry Describes the geometry of a data object.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.