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