Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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.