Medical Imaging Interaction Toolkit  2018.4.99-12ad79a3
Medical Imaging Interaction Toolkit
mitkPlanarCrossTest.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 (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
13 #include "mitkPlanarCross.h"
14 #include "mitkPlaneGeometry.h"
15 #include "mitkTestingMacros.h"
16 
17 class mitkPlanarCrossTestClass
18 {
19 public:
20  static void TestPlanarCrossPlacement(mitk::PlanarCross::Pointer planarCross)
21  {
22  // Test for correct minimum number of control points in cross-mode
23  MITK_TEST_CONDITION(planarCross->GetMinimumNumberOfControlPoints() == 4, "Minimum number of control points");
24 
25  // Test for correct maximum number of control points in cross-mode
26  MITK_TEST_CONDITION(planarCross->GetMaximumNumberOfControlPoints() == 4, "Maximum number of control points");
27 
28  // Initial placement of PlanarCross
29  mitk::Point2D p0;
30  p0[0] = 20.0;
31  p0[1] = 20.0;
32  planarCross->PlaceFigure(p0);
33 
34  // Add second control point
35  mitk::Point2D p1;
36  p1[0] = 80.0;
37  p1[1] = 80.0;
38  planarCross->SetCurrentControlPoint(p1);
39 
40  // Add third control point
41  mitk::Point2D p2;
42  p2[0] = 90.0;
43  p2[1] = 10.0;
44  planarCross->AddControlPoint(p2);
45 
46  // Test if helper polyline is generated
47  const mitk::PlanarFigure::PolyLineType helperPolyLine = planarCross->GetHelperPolyLine(0, 1.0, 100);
48  MITK_TEST_CONDITION(planarCross->GetHelperPolyLinesSize() == 1,
49  "Number of helper polylines after placing 3 points");
50 
51  // Test if helper polyline is marked as "to be painted"
52  MITK_TEST_CONDITION(planarCross->IsHelperToBePainted(0), "Helper line to be painted after placing 3 points");
53 
54  // Test if helper polyline is orthogonal to first line
55  mitk::Vector2D v0 = p1 - p0;
56  v0.Normalize();
57 
58  // TODO: make it work again
59 
60  // mitk::Vector2D hv = helperPolyLine->ElementAt( 1 ) - helperPolyLine->ElementAt( 0 );
61  // hv.Normalize();
62  // MITK_TEST_CONDITION( fabs(v0 * hv) < mitk::eps, "Helper line is orthogonal to first line" );
63 
65  // mitk::Vector2D hv1 = helperPolyLine->ElementAt( 1 ) - p2;
66  // hv1.Normalize();
67  // MITK_TEST_CONDITION( fabs(hv * hv1 - 1.0) < mitk::eps, "Helper line is aligned to third point" );
68 
69  // Add fourth control point
70  mitk::Point2D p3;
71  p3[0] = 10.0;
72  p3[1] = 90.0;
73  planarCross->AddControlPoint(p3);
74 
75  // Test for number of control points
76  MITK_TEST_CONDITION(planarCross->GetNumberOfControlPoints() == 4, "Number of control points after placement");
77 
78  // Test if PlanarFigure is closed
79  MITK_TEST_CONDITION(!planarCross->IsClosed(), "Is PlanarFigure closed?");
80 
81  // Test if helper polyline is no longer marked as "to be painted"
82  MITK_TEST_CONDITION(planarCross->IsHelperToBePainted(0),
83  "Helper line no longer to be painted after placement of all 4 points");
84 
85  // Test for number of polylines
86  const mitk::PlanarFigure::PolyLineType polyLine0 = planarCross->GetPolyLine(0);
87  const mitk::PlanarFigure::PolyLineType polyLine1 = planarCross->GetPolyLine(1);
88  MITK_TEST_CONDITION(planarCross->GetPolyLinesSize() == 2, "Number of polylines after placement");
89 
90  auto iter0 = polyLine0.begin();
91  auto iter1 = polyLine1.begin();
92 
93  // Get polylines and check if the generated coordinates are OK
94  const mitk::Point2D &pp0 = *iter0;
95  iter0++;
96  const mitk::Point2D &pp1 = *iter0;
97  MITK_TEST_CONDITION(((pp0 == p0) && (pp1 == p1)) || ((pp0 == p1) && (pp1 == p0)), "Correct polyline 1");
98 
99  const mitk::Point2D &pp2 = *iter1;
100  iter1++;
101  const mitk::Point2D &pp3 = *iter1;
102  MITK_TEST_CONDITION(((pp2 == p2) && (pp3 == p3)) || ((pp2 == p3) && (pp3 == p2)), "Correct polyline 2");
103 
104  // Test for number of measurement features
105  planarCross->EvaluateFeatures();
106  MITK_TEST_CONDITION(planarCross->GetNumberOfFeatures() == 2, "Number of measurement features");
107 
108  // Test for correct feature evaluation
109  double length0 = sqrt(80.0 * 80.0 * 2.0);
110  MITK_TEST_CONDITION(fabs(planarCross->GetQuantity(0) - length0) < mitk::eps, "Size of longest diameter");
111 
112  double length1 = sqrt(60.0 * 60.0 * 2.0);
113  MITK_TEST_CONDITION(fabs(planarCross->GetQuantity(1) - length1) < mitk::eps, "Size of short axis diameter");
114  }
115 
116  static void TestPlanarCrossPlacementSingleLine(mitk::PlanarCross::Pointer planarCross)
117  {
118  // Test for correct minimum number of control points in cross-mode
119  MITK_TEST_CONDITION(planarCross->GetMinimumNumberOfControlPoints() == 2, "Minimum number of control points");
120 
121  // Test for correct maximum number of control points in cross-mode
122  MITK_TEST_CONDITION(planarCross->GetMaximumNumberOfControlPoints() == 2, "Maximum number of control points");
123 
124  // Initial placement of PlanarCross
125  mitk::Point2D p0;
126  p0[0] = 25.0;
127  p0[1] = 10.0;
128  planarCross->PlaceFigure(p0);
129 
130  // Add second control point
131  mitk::Point2D p1;
132  p1[0] = 30.0;
133  p1[1] = 60.0;
134  planarCross->SetCurrentControlPoint(p1);
135 
136  // Verify that no helper line is drawn
137  MITK_TEST_CONDITION(planarCross->IsHelperToBePainted(0) == false,
138  "No helper line to be painted in single-line mode");
139 
140  // Test for number of control points
141  MITK_TEST_CONDITION(planarCross->GetNumberOfControlPoints() == 2, "Number of control points after placement");
142 
143  // Test if PlanarFigure is closed
144  MITK_TEST_CONDITION(!planarCross->IsClosed(), "Is PlanarFigure closed?");
145 
146  // Test for number of polylines
147  const mitk::PlanarFigure::PolyLineType polyLine0 = planarCross->GetPolyLine(0);
148  auto iter = polyLine0.begin();
149  MITK_TEST_CONDITION(planarCross->GetPolyLinesSize() == 1, "Number of polylines after placement");
150 
151  // Get polylines and check if the generated coordinates are OK
152  const mitk::Point2D &pp0 = *iter;
153  iter++;
154  const mitk::Point2D &pp1 = *iter;
155  MITK_TEST_CONDITION(((pp0 == p0) && (pp1 == p1)) || ((pp0 == p1) && (pp1 == p0)), "Correct polyline 1");
156 
157  // Test for number of measurement features
158  planarCross->EvaluateFeatures();
159  MITK_TEST_CONDITION(planarCross->GetNumberOfFeatures() == 1, "Number of measurement features");
160 
161  // Test for correct feature evaluation
162  double length0 = sqrt(5.0 * 5.0 + 50.0 * 50.0);
163  MITK_TEST_CONDITION(fabs(planarCross->GetQuantity(0) - length0) < mitk::eps, "Size of diameter");
164 
165  // Test if reset called on single-line PlanarCross returns false (nothing to reset)
166  MITK_TEST_CONDITION(planarCross->ResetOnPointSelect() == false,
167  "Single-line PlanarCross should not be reset on point edit");
168  }
169 
170  static void TestPlanarCrossPlacementConstrained(mitk::PlanarCross::Pointer planarCross)
171  {
172  // **************************************************************************
173  // Place first control point out of bounds (to the left of the image bounds)
174  mitk::Point2D p0;
175  p0[0] = -20.0;
176  p0[1] = 20.0;
177  planarCross->PlaceFigure(p0);
178 
179  // Test if constraint has been applied correctly
180  mitk::Point2D cp0 = planarCross->GetControlPoint(0);
181  MITK_TEST_CONDITION((fabs(cp0[0]) < mitk::eps) && (fabs(cp0[1] - 20.0) < mitk::eps),
182  "Point1 placed and constrained correctly");
183 
184  // **************************************************************************
185  // Add second control point out of bounds (to the top of the image bounds)
186  mitk::Point2D p1;
187  p1[0] = 80.0;
188  p1[1] = 120.0;
189  planarCross->SetCurrentControlPoint(p1);
190 
191  // Test if constraint has been applied correctly
192  mitk::Point2D cp1 = planarCross->GetControlPoint(1);
193  MITK_TEST_CONDITION((fabs(cp1[0] - 80.0) < mitk::eps) && (fabs(cp1[1] - 100.0) < mitk::eps),
194  "Point2 placed and constrained correctly");
195 
196  // **************************************************************************
197  // Add third control point out of bounds (outside of channel defined by first line)
198  mitk::Point2D p2;
199  p2[0] = 100.0;
200  p2[1] = 100.0;
201  planarCross->AddControlPoint(p2);
202 
203  // Test if constraint has been applied correctly (100.0, 100.0) must be projected to (90.0, 90.0)
204  mitk::Point2D cp2 = planarCross->GetControlPoint(2);
205  MITK_TEST_CONDITION((fabs(cp2[0] - 90.0) < mitk::eps) && (fabs(cp2[1] - 90.0) < mitk::eps),
206  "Point3 placed and constrained correctly");
207 
208  // Move third control point (within channel defined by first line)
209  p2[0] = 40.0;
210  p2[1] = 20.0;
211  planarCross->SetControlPoint(2, p2);
212 
213  // Test if point is still at this position (no constrained should be applied)
214  cp2 = planarCross->GetControlPoint(2);
215  MITK_TEST_CONDITION((fabs(cp2[0] - 40.0) < mitk::eps) && (fabs(cp2[1] - 20.0) < mitk::eps),
216  "Point3 moved correctly");
217 
218  // **************************************************************************
219  // Add fourth control point out of bounds (outside of line defined by first line and third point)
220  mitk::Point2D p3;
221  p3[0] = 20.0;
222  p3[1] = 60.0;
223  planarCross->AddControlPoint(p3);
224 
225  // Test if constraint has been applied correctly (20.0, 60.0) must be projected to (10.0, 50.0)
226  mitk::Point2D cp3 = planarCross->GetControlPoint(3);
227  MITK_TEST_CONDITION((fabs(cp3[0] - 10.0) < mitk::eps) && (fabs(cp3[1] - 50.0) < mitk::eps),
228  "Point4 placed and constrained correctly");
229 
230  // Move fourth control point (to a position which would result in two non-intersecting line
231  // without the constraint that lines have to intersect)
232  p3[0] = 40.0;
233  p3[1] = 30.0;
234  planarCross->SetControlPoint(3, p3);
235 
236  // Test if constrained point is on the projected intersection point of both lines (20.0/40.0)
237  cp3 = planarCross->GetControlPoint(3);
238  MITK_TEST_CONDITION((fabs(cp3[0] - 20.0) < mitk::eps) && (fabs(cp3[1] - 40.0) < mitk::eps),
239  "Point4 placed and constrained correctly");
240  }
241 
242  static void TestPlanarCrossEdit(mitk::PlanarCross::Pointer planarCross)
243  {
244  // * point move (different points)
245  // --> reset
246  // --> test which point is where / evaluation
247  mitk::Point2D p0 = planarCross->GetControlPoint(0);
248  mitk::Point2D p1 = planarCross->GetControlPoint(1);
249  mitk::Point2D p2 = planarCross->GetControlPoint(2);
250  mitk::Point2D p3 = planarCross->GetControlPoint(3);
251 
252  // **************************************************************************
253  // Edit control point 0
254  planarCross->SelectControlPoint(0);
255 
256  // Request reset and check if it is done
257  MITK_TEST_CONDITION(planarCross->ResetOnPointSelect(),
258  "Editing control point 0: Double-line PlanarCross should be reset");
259 
260  // Check number of control points
261  MITK_TEST_CONDITION(planarCross->GetNumberOfControlPoints() == 2, "Two control points are left");
262 
263  // Check if correct control points have been left
264  MITK_TEST_CONDITION((planarCross->GetControlPoint(0).EuclideanDistanceTo(p1) < mitk::eps) &&
265  (planarCross->GetControlPoint(1).EuclideanDistanceTo(p0) < mitk::eps),
266  "Reset to expected control points (p1, p0)");
267 
268  // Reset planar cross to original values
269  ResetPlanarCross(planarCross, p0, p1, p2, p3);
270 
271  // **************************************************************************
272  // Edit control point 1
273  planarCross->SelectControlPoint(1);
274 
275  // Request reset and check if it is done
276  MITK_TEST_CONDITION(planarCross->ResetOnPointSelect(),
277  "Editing control point 1: Double-line PlanarCross should be reset");
278 
279  // Check number of control points
280  MITK_TEST_CONDITION(planarCross->GetNumberOfControlPoints() == 2, "Two control points are left");
281 
282  // Check if correct control points have been left
283  MITK_TEST_CONDITION((planarCross->GetControlPoint(0).EuclideanDistanceTo(p0) < mitk::eps) &&
284  (planarCross->GetControlPoint(1).EuclideanDistanceTo(p1) < mitk::eps),
285  "Reset to expected control points (p0, p1)");
286 
287  // Reset planar cross to original values
288  ResetPlanarCross(planarCross, p0, p1, p2, p3);
289 
290  // **************************************************************************
291  // Edit control point 2
292  planarCross->SelectControlPoint(2);
293 
294  // Request reset and check if it is done
295  MITK_TEST_CONDITION(planarCross->ResetOnPointSelect(),
296  "Editing control point 2: Double-line PlanarCross should be reset");
297 
298  // Check number of control points
299  MITK_TEST_CONDITION(planarCross->GetNumberOfControlPoints() == 2, "Two control points are left");
300 
301  // Check if correct control points have been left
302  MITK_TEST_CONDITION((planarCross->GetControlPoint(0).EuclideanDistanceTo(p3) < mitk::eps) &&
303  (planarCross->GetControlPoint(1).EuclideanDistanceTo(p2) < mitk::eps),
304  "Reset to expected control points (p3, p2)");
305 
306  // Reset planar cross to original values
307  ResetPlanarCross(planarCross, p0, p1, p2, p3);
308 
309  // **************************************************************************
310  // Edit control point 3
311  planarCross->SelectControlPoint(3);
312 
313  // Request reset and check if it is done
314  MITK_TEST_CONDITION(planarCross->ResetOnPointSelect(),
315  "Editing control point 3: Double-line PlanarCross should be reset");
316 
317  // Check number of control points
318  MITK_TEST_CONDITION(planarCross->GetNumberOfControlPoints() == 2, "Two control points are left");
319 
320  // Check if correct control points have been left
321  MITK_TEST_CONDITION((planarCross->GetControlPoint(0).EuclideanDistanceTo(p2) < mitk::eps) &&
322  (planarCross->GetControlPoint(1).EuclideanDistanceTo(p3) < mitk::eps),
323  "Reset to expected control points (p2, p3)");
324  }
325 
326  static void ResetPlanarCross(
328  {
329  planarCross->SetControlPoint(0, p0, true);
330  planarCross->SetControlPoint(1, p1, true);
331  planarCross->SetControlPoint(2, p2, true);
332  planarCross->SetControlPoint(3, p3, true);
333  }
334 };
335 
345 int mitkPlanarCrossTest(int /* argc */, char * /*argv*/ [])
346 {
347  // always start with this!
348  MITK_TEST_BEGIN("PlanarCross")
349 
350  // create PlaneGeometry on which to place the PlanarCross
352  planeGeometry->InitializeStandardPlane(100.0, 100.0);
353 
354  // **************************************************************************
355  // 1. Double-line mode instantiation and basic tests
357  planarCross->SetPlaneGeometry(planeGeometry);
358 
359  // first test: did this work?
360  MITK_TEST_CONDITION_REQUIRED(planarCross.IsNotNull(), "Testing instantiation");
361 
362  // test: default cross-mode (not single-line-mode)?
363  MITK_TEST_CONDITION_REQUIRED(!planarCross->GetSingleLineMode(), "Testing default cross mode");
364 
365  // Test placement of PlanarCross by control points
366  mitkPlanarCrossTestClass::TestPlanarCrossPlacement(planarCross);
367 
368  // **************************************************************************
369  // 2. Single-line mode instantiation and basic tests
370  planarCross = mitk::PlanarCross::New();
371  planarCross->SingleLineModeOn();
372  planarCross->SetPlaneGeometry(planeGeometry);
373 
374  // test: single-line mode?
375  MITK_TEST_CONDITION_REQUIRED(planarCross->GetSingleLineMode(), "Testing activation of single-line mode");
376 
377  // Test placement of single-line PlanarCross by control points
378  mitkPlanarCrossTestClass::TestPlanarCrossPlacementSingleLine(planarCross);
379 
380  // **************************************************************************
381  // 3. Tests of application of spatial constraints for double-line mode
382  planarCross = mitk::PlanarCross::New();
383  planarCross->SetPlaneGeometry(planeGeometry);
384 
385  // Test placement with various out-of-bounds control points (automatic application of
386  // constraints expected)
387  mitkPlanarCrossTestClass::TestPlanarCrossPlacementConstrained(planarCross);
388 
389  // **************************************************************************
390  // 4. Tests if editing of PlanarCross works as intended
391  mitkPlanarCrossTestClass::TestPlanarCrossEdit(planarCross);
392 
393  // always end with this!
394  MITK_TEST_END()
395 }
#define MITK_TEST_CONDITION_REQUIRED(COND, MSG)
section GeneralTestsDeprecatedOldTestingStyle Deprecated macros All tests with MITK_TEST_BEGIN()
#define MITK_TEST_CONDITION(COND, MSG)
static Pointer New()
int mitkPlanarCrossTest(int, char *[])
static Pointer New()
MITKCORE_EXPORT const ScalarType eps
std::vector< PolyLineElement > PolyLineType
and MITK_TEST_END()