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
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()