Mercurial > hg > orthanc-stone
comparison OrthancStone/UnitTestsSources/ComputationalGeometryTests.cpp @ 1877:a2955abe4c2e
skeleton for the RenderingPlugin
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 12 Jan 2022 08:23:38 +0100 |
parents | UnitTestsSources/ComputationalGeometryTests.cpp@b1f510e601d2 |
children | 6ce81914f7e4 |
comparison
equal
deleted
inserted
replaced
1876:b1f510e601d2 | 1877:a2955abe4c2e |
---|---|
1 /** | |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2022 Osimis S.A., Belgium | |
6 * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium | |
7 * | |
8 * This program is free software: you can redistribute it and/or | |
9 * modify it under the terms of the GNU Lesser General Public License | |
10 * as published by the Free Software Foundation, either version 3 of | |
11 * the License, or (at your option) any later version. | |
12 * | |
13 * This program is distributed in the hope that it will be useful, but | |
14 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
19 * License along with this program. If not, see | |
20 * <http://www.gnu.org/licenses/>. | |
21 **/ | |
22 | |
23 | |
24 #include <gtest/gtest.h> | |
25 | |
26 #include "../Sources/Toolbox/Internals/OrientedIntegerLine2D.h" | |
27 #include "../Sources/Toolbox/Internals/RectanglesIntegerProjection.h" | |
28 #include "../Sources/Toolbox/SegmentTree.h" | |
29 #include "../Sources/Toolbox/UnionOfRectangles.h" | |
30 | |
31 #include <Logging.h> | |
32 #include <OrthancException.h> | |
33 | |
34 | |
35 namespace | |
36 { | |
37 typedef Orthanc::SingleValueObject<int> Counter; | |
38 | |
39 class CounterFactory : public OrthancStone::SegmentTree::IPayloadFactory | |
40 { | |
41 private: | |
42 int value_; | |
43 | |
44 public: | |
45 CounterFactory(int value) : | |
46 value_(value) | |
47 { | |
48 } | |
49 | |
50 virtual Orthanc::IDynamicObject* Create() ORTHANC_OVERRIDE | |
51 { | |
52 return new Counter(value_); | |
53 } | |
54 }; | |
55 | |
56 class IncrementVisitor : public OrthancStone::SegmentTree::IVisitor | |
57 { | |
58 private: | |
59 int increment_; | |
60 | |
61 public: | |
62 IncrementVisitor(int increment) : | |
63 increment_(increment) | |
64 { | |
65 } | |
66 | |
67 virtual void Visit(const OrthancStone::SegmentTree& node, | |
68 bool fullyInside) ORTHANC_OVERRIDE | |
69 { | |
70 if (fullyInside) | |
71 { | |
72 Counter& payload = node.GetTypedPayload<Counter>(); | |
73 | |
74 if (payload.GetValue() + increment_ < 0) | |
75 { | |
76 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
77 } | |
78 else | |
79 { | |
80 payload.SetValue(payload.GetValue() + increment_); | |
81 } | |
82 } | |
83 } | |
84 }; | |
85 } | |
86 | |
87 | |
88 TEST(SegmentTree, Create) | |
89 { | |
90 CounterFactory factory(42); | |
91 OrthancStone::SegmentTree root(4u, 15u, factory); // Check out Figure 1.1 (page 14) from textbook | |
92 | |
93 ASSERT_EQ(4u, root.GetLowBound()); | |
94 ASSERT_EQ(15u, root.GetHighBound()); | |
95 ASSERT_FALSE(root.IsLeaf()); | |
96 ASSERT_EQ(42, root.GetTypedPayload<Counter>().GetValue()); | |
97 ASSERT_EQ(21u, root.CountNodes()); | |
98 | |
99 const OrthancStone::SegmentTree* n = &root.GetLeftChild(); | |
100 ASSERT_EQ(4u, n->GetLowBound()); | |
101 ASSERT_EQ(9u, n->GetHighBound()); | |
102 ASSERT_FALSE(n->IsLeaf()); | |
103 ASSERT_EQ(9u, n->CountNodes()); | |
104 | |
105 n = &root.GetLeftChild().GetLeftChild(); | |
106 ASSERT_EQ(4u, n->GetLowBound()); | |
107 ASSERT_EQ(6u, n->GetHighBound()); | |
108 ASSERT_FALSE(n->IsLeaf()); | |
109 ASSERT_EQ(3u, n->CountNodes()); | |
110 | |
111 n = &root.GetLeftChild().GetLeftChild().GetLeftChild(); | |
112 ASSERT_EQ(4u, n->GetLowBound()); | |
113 ASSERT_EQ(5u, n->GetHighBound()); | |
114 ASSERT_TRUE(n->IsLeaf()); | |
115 ASSERT_THROW(n->GetLeftChild(), Orthanc::OrthancException); | |
116 ASSERT_THROW(n->GetRightChild(), Orthanc::OrthancException); | |
117 ASSERT_EQ(1u, n->CountNodes()); | |
118 | |
119 n = &root.GetLeftChild().GetLeftChild().GetRightChild(); | |
120 ASSERT_EQ(5u, n->GetLowBound()); | |
121 ASSERT_EQ(6u, n->GetHighBound()); | |
122 ASSERT_TRUE(n->IsLeaf()); | |
123 ASSERT_EQ(1u, n->CountNodes()); | |
124 | |
125 n = &root.GetLeftChild().GetRightChild(); | |
126 ASSERT_EQ(6u, n->GetLowBound()); | |
127 ASSERT_EQ(9u, n->GetHighBound()); | |
128 ASSERT_FALSE(n->IsLeaf()); | |
129 ASSERT_EQ(5u, n->CountNodes()); | |
130 | |
131 n = &root.GetLeftChild().GetRightChild().GetLeftChild(); | |
132 ASSERT_EQ(6u, n->GetLowBound()); | |
133 ASSERT_EQ(7u, n->GetHighBound()); | |
134 ASSERT_TRUE(n->IsLeaf()); | |
135 ASSERT_EQ(1u, n->CountNodes()); | |
136 | |
137 n = &root.GetLeftChild().GetRightChild().GetRightChild(); | |
138 ASSERT_EQ(7u, n->GetLowBound()); | |
139 ASSERT_EQ(9u, n->GetHighBound()); | |
140 ASSERT_FALSE(n->IsLeaf()); | |
141 ASSERT_EQ(3u, n->CountNodes()); | |
142 | |
143 n = &root.GetLeftChild().GetRightChild().GetRightChild().GetLeftChild(); | |
144 ASSERT_EQ(7u, n->GetLowBound()); | |
145 ASSERT_EQ(8u, n->GetHighBound()); | |
146 ASSERT_TRUE(n->IsLeaf()); | |
147 ASSERT_EQ(1u, n->CountNodes()); | |
148 | |
149 n = &root.GetLeftChild().GetRightChild().GetRightChild().GetRightChild(); | |
150 ASSERT_EQ(8u, n->GetLowBound()); | |
151 ASSERT_EQ(9u, n->GetHighBound()); | |
152 ASSERT_TRUE(n->IsLeaf()); | |
153 ASSERT_EQ(1u, n->CountNodes()); | |
154 | |
155 n = &root.GetRightChild(); | |
156 ASSERT_EQ(9u, n->GetLowBound()); | |
157 ASSERT_EQ(15u, n->GetHighBound()); | |
158 ASSERT_FALSE(n->IsLeaf()); | |
159 ASSERT_EQ(11u, n->CountNodes()); | |
160 | |
161 n = &root.GetRightChild().GetLeftChild(); | |
162 ASSERT_EQ(9u, n->GetLowBound()); | |
163 ASSERT_EQ(12u, n->GetHighBound()); | |
164 ASSERT_FALSE(n->IsLeaf()); | |
165 ASSERT_EQ(5u, n->CountNodes()); | |
166 | |
167 n = &root.GetRightChild().GetLeftChild().GetLeftChild(); | |
168 ASSERT_EQ(9u, n->GetLowBound()); | |
169 ASSERT_EQ(10u, n->GetHighBound()); | |
170 ASSERT_TRUE(n->IsLeaf()); | |
171 ASSERT_EQ(1u, n->CountNodes()); | |
172 | |
173 n = &root.GetRightChild().GetLeftChild().GetRightChild(); | |
174 ASSERT_EQ(10u, n->GetLowBound()); | |
175 ASSERT_EQ(12u, n->GetHighBound()); | |
176 ASSERT_FALSE(n->IsLeaf()); | |
177 ASSERT_EQ(3u, n->CountNodes()); | |
178 | |
179 n = &root.GetRightChild().GetLeftChild().GetRightChild().GetLeftChild(); | |
180 ASSERT_EQ(10u, n->GetLowBound()); | |
181 ASSERT_EQ(11u, n->GetHighBound()); | |
182 ASSERT_TRUE(n->IsLeaf()); | |
183 ASSERT_EQ(1u, n->CountNodes()); | |
184 | |
185 n = &root.GetRightChild().GetLeftChild().GetRightChild().GetRightChild(); | |
186 ASSERT_EQ(11u, n->GetLowBound()); | |
187 ASSERT_EQ(12u, n->GetHighBound()); | |
188 ASSERT_TRUE(n->IsLeaf()); | |
189 ASSERT_EQ(1u, n->CountNodes()); | |
190 | |
191 n = &root.GetRightChild().GetRightChild(); | |
192 ASSERT_EQ(12u, n->GetLowBound()); | |
193 ASSERT_EQ(15u, n->GetHighBound()); | |
194 ASSERT_FALSE(n->IsLeaf()); | |
195 ASSERT_EQ(5u, n->CountNodes()); | |
196 | |
197 n = &root.GetRightChild().GetRightChild().GetLeftChild(); | |
198 ASSERT_EQ(12u, n->GetLowBound()); | |
199 ASSERT_EQ(13u, n->GetHighBound()); | |
200 ASSERT_TRUE(n->IsLeaf()); | |
201 ASSERT_EQ(1u, n->CountNodes()); | |
202 | |
203 n = &root.GetRightChild().GetRightChild().GetRightChild(); | |
204 ASSERT_EQ(13u, n->GetLowBound()); | |
205 ASSERT_EQ(15u, n->GetHighBound()); | |
206 ASSERT_FALSE(n->IsLeaf()); | |
207 ASSERT_EQ(3u, n->CountNodes()); | |
208 | |
209 n = &root.GetRightChild().GetRightChild().GetRightChild().GetLeftChild(); | |
210 ASSERT_EQ(13u, n->GetLowBound()); | |
211 ASSERT_EQ(14u, n->GetHighBound()); | |
212 ASSERT_TRUE(n->IsLeaf()); | |
213 ASSERT_EQ(1u, n->CountNodes()); | |
214 | |
215 n = &root.GetRightChild().GetRightChild().GetRightChild().GetRightChild(); | |
216 ASSERT_EQ(14u, n->GetLowBound()); | |
217 ASSERT_EQ(15u, n->GetHighBound()); | |
218 ASSERT_TRUE(n->IsLeaf()); | |
219 ASSERT_EQ(1u, n->CountNodes()); | |
220 | |
221 ASSERT_TRUE(root.FindLeaf(3) == NULL); | |
222 for (size_t i = 4; i < 15; i++) | |
223 { | |
224 n = root.FindLeaf(i); | |
225 ASSERT_TRUE(n != NULL); | |
226 ASSERT_TRUE(n->IsLeaf()); | |
227 ASSERT_EQ(i, n->GetLowBound()); | |
228 ASSERT_EQ(i + 1, n->GetHighBound()); | |
229 ASSERT_EQ(42, n->GetTypedPayload<Counter>().GetValue()); | |
230 } | |
231 ASSERT_TRUE(root.FindLeaf(15) == NULL); | |
232 } | |
233 | |
234 | |
235 static bool CheckCounter(const OrthancStone::SegmentTree& node, | |
236 int expectedValue) | |
237 { | |
238 if (node.GetTypedPayload<Counter>().GetValue() != expectedValue) | |
239 { | |
240 return false; | |
241 } | |
242 else if (node.IsLeaf()) | |
243 { | |
244 return true; | |
245 } | |
246 else | |
247 { | |
248 return (CheckCounter(node.GetLeftChild(), expectedValue) && | |
249 CheckCounter(node.GetRightChild(), expectedValue)); | |
250 } | |
251 } | |
252 | |
253 | |
254 #if 0 | |
255 static void Print(const OrthancStone::SegmentTree& node, | |
256 unsigned int indent) | |
257 { | |
258 for (size_t i = 0; i < indent; i++) | |
259 printf(" "); | |
260 printf("(%lu,%lu): %d\n", node.GetLowBound(), node.GetHighBound(), node.GetTypedPayload<Counter>().GetValue()); | |
261 if (!node.IsLeaf()) | |
262 { | |
263 Print(node.GetLeftChild(), indent + 1); | |
264 Print(node.GetRightChild(), indent + 1); | |
265 } | |
266 } | |
267 #endif | |
268 | |
269 | |
270 TEST(SegmentTree, Visit) | |
271 { | |
272 CounterFactory factory(0); | |
273 OrthancStone::SegmentTree root(4u, 15u, factory); // Check out Figure 1.1 (page 14) from textbook | |
274 | |
275 ASSERT_TRUE(CheckCounter(root, 0)); | |
276 | |
277 IncrementVisitor plus(1); | |
278 IncrementVisitor minus(-1); | |
279 | |
280 root.VisitSegment(0, 20, plus); | |
281 ASSERT_EQ(1, root.GetTypedPayload<Counter>().GetValue()); | |
282 ASSERT_TRUE(CheckCounter(root.GetLeftChild(), 0)); | |
283 ASSERT_TRUE(CheckCounter(root.GetRightChild(), 0)); | |
284 | |
285 root.VisitSegment(0, 20, plus); | |
286 ASSERT_EQ(2, root.GetTypedPayload<Counter>().GetValue()); | |
287 ASSERT_TRUE(CheckCounter(root.GetLeftChild(), 0)); | |
288 ASSERT_TRUE(CheckCounter(root.GetRightChild(), 0)); | |
289 | |
290 root.VisitSegment(0, 20, minus); | |
291 root.VisitSegment(0, 20, minus); | |
292 ASSERT_TRUE(CheckCounter(root, 0)); | |
293 | |
294 root.VisitSegment(8, 11, plus); | |
295 ASSERT_EQ(0, root.FindNode(4, 15)->GetTypedPayload<Counter>().GetValue()); | |
296 ASSERT_EQ(0, root.FindNode(4, 9)->GetTypedPayload<Counter>().GetValue()); | |
297 ASSERT_EQ(0, root.FindNode(4, 6)->GetTypedPayload<Counter>().GetValue()); | |
298 ASSERT_EQ(0, root.FindNode(4, 5)->GetTypedPayload<Counter>().GetValue()); | |
299 ASSERT_EQ(0, root.FindNode(5, 6)->GetTypedPayload<Counter>().GetValue()); | |
300 ASSERT_EQ(0, root.FindNode(6, 9)->GetTypedPayload<Counter>().GetValue()); | |
301 ASSERT_EQ(0, root.FindNode(6, 7)->GetTypedPayload<Counter>().GetValue()); | |
302 ASSERT_EQ(0, root.FindNode(7, 9)->GetTypedPayload<Counter>().GetValue()); | |
303 ASSERT_EQ(0, root.FindNode(7, 8)->GetTypedPayload<Counter>().GetValue()); | |
304 ASSERT_EQ(1, root.FindNode(8, 9)->GetTypedPayload<Counter>().GetValue()); | |
305 ASSERT_EQ(0, root.FindNode(9, 15)->GetTypedPayload<Counter>().GetValue()); | |
306 ASSERT_EQ(0, root.FindNode(9, 12)->GetTypedPayload<Counter>().GetValue()); | |
307 ASSERT_EQ(1, root.FindNode(9, 10)->GetTypedPayload<Counter>().GetValue()); | |
308 ASSERT_EQ(0, root.FindNode(10, 12)->GetTypedPayload<Counter>().GetValue()); | |
309 ASSERT_EQ(1, root.FindNode(10, 11)->GetTypedPayload<Counter>().GetValue()); | |
310 ASSERT_EQ(0, root.FindNode(11, 12)->GetTypedPayload<Counter>().GetValue()); | |
311 ASSERT_EQ(0, root.FindNode(12, 15)->GetTypedPayload<Counter>().GetValue()); | |
312 ASSERT_EQ(0, root.FindNode(12, 13)->GetTypedPayload<Counter>().GetValue()); | |
313 ASSERT_EQ(0, root.FindNode(13, 15)->GetTypedPayload<Counter>().GetValue()); | |
314 ASSERT_EQ(0, root.FindNode(13, 14)->GetTypedPayload<Counter>().GetValue()); | |
315 ASSERT_EQ(0, root.FindNode(14, 15)->GetTypedPayload<Counter>().GetValue()); | |
316 | |
317 root.VisitSegment(9, 11, minus); | |
318 ASSERT_EQ(0, root.FindNode(4, 15)->GetTypedPayload<Counter>().GetValue()); | |
319 ASSERT_EQ(0, root.FindNode(4, 9)->GetTypedPayload<Counter>().GetValue()); | |
320 ASSERT_EQ(0, root.FindNode(4, 6)->GetTypedPayload<Counter>().GetValue()); | |
321 ASSERT_EQ(0, root.FindNode(4, 5)->GetTypedPayload<Counter>().GetValue()); | |
322 ASSERT_EQ(0, root.FindNode(5, 6)->GetTypedPayload<Counter>().GetValue()); | |
323 ASSERT_EQ(0, root.FindNode(6, 9)->GetTypedPayload<Counter>().GetValue()); | |
324 ASSERT_EQ(0, root.FindNode(6, 7)->GetTypedPayload<Counter>().GetValue()); | |
325 ASSERT_EQ(0, root.FindNode(7, 9)->GetTypedPayload<Counter>().GetValue()); | |
326 ASSERT_EQ(0, root.FindNode(7, 8)->GetTypedPayload<Counter>().GetValue()); | |
327 ASSERT_EQ(1, root.FindNode(8, 9)->GetTypedPayload<Counter>().GetValue()); | |
328 ASSERT_TRUE(CheckCounter(root.GetRightChild(), 0)); | |
329 | |
330 root.VisitSegment(8, 9, minus); | |
331 ASSERT_TRUE(CheckCounter(root, 0)); | |
332 } | |
333 | |
334 | |
335 TEST(UnionOfRectangles, RectanglesIntegerProjection) | |
336 { | |
337 std::list<OrthancStone::Extent2D> rectangles; | |
338 rectangles.push_back(OrthancStone::Extent2D(10, 20, 30, 40)); | |
339 | |
340 { | |
341 OrthancStone::Internals::RectanglesIntegerProjection h(rectangles, true); | |
342 ASSERT_EQ(2u, h.GetEndpointsCount()); | |
343 ASSERT_EQ(10, h.GetEndpointCoordinate(0)); | |
344 ASSERT_EQ(30, h.GetEndpointCoordinate(1)); | |
345 ASSERT_EQ(1u, h.GetProjectedRectanglesCount()); | |
346 ASSERT_EQ(0u, h.GetProjectedRectangleLow(0)); | |
347 ASSERT_EQ(1u, h.GetProjectedRectangleHigh(0)); | |
348 | |
349 ASSERT_THROW(h.GetEndpointCoordinate(2), Orthanc::OrthancException); | |
350 ASSERT_THROW(h.GetProjectedRectangleLow(1), Orthanc::OrthancException); | |
351 ASSERT_THROW(h.GetProjectedRectangleHigh(1), Orthanc::OrthancException); | |
352 } | |
353 | |
354 { | |
355 OrthancStone::Internals::RectanglesIntegerProjection h(rectangles, false); | |
356 ASSERT_EQ(2u, h.GetEndpointsCount()); | |
357 ASSERT_EQ(20, h.GetEndpointCoordinate(0)); | |
358 ASSERT_EQ(40, h.GetEndpointCoordinate(1)); | |
359 ASSERT_EQ(1u, h.GetProjectedRectanglesCount()); | |
360 ASSERT_EQ(0u, h.GetProjectedRectangleLow(0)); | |
361 ASSERT_EQ(1u, h.GetProjectedRectangleHigh(0)); | |
362 } | |
363 | |
364 rectangles.push_back(OrthancStone::Extent2D(20, 30, 40, 50)); | |
365 | |
366 { | |
367 OrthancStone::Internals::RectanglesIntegerProjection h(rectangles, true); | |
368 ASSERT_EQ(4u, h.GetEndpointsCount()); | |
369 ASSERT_EQ(10, h.GetEndpointCoordinate(0)); | |
370 ASSERT_EQ(20, h.GetEndpointCoordinate(1)); | |
371 ASSERT_EQ(30, h.GetEndpointCoordinate(2)); | |
372 ASSERT_EQ(40, h.GetEndpointCoordinate(3)); | |
373 ASSERT_EQ(2u, h.GetProjectedRectanglesCount()); | |
374 ASSERT_EQ(0u, h.GetProjectedRectangleLow(0)); | |
375 ASSERT_EQ(2u, h.GetProjectedRectangleHigh(0)); | |
376 ASSERT_EQ(1u, h.GetProjectedRectangleLow(1)); | |
377 ASSERT_EQ(3u, h.GetProjectedRectangleHigh(1)); | |
378 } | |
379 | |
380 { | |
381 OrthancStone::Internals::RectanglesIntegerProjection h(rectangles, false); | |
382 ASSERT_EQ(4u, h.GetEndpointsCount()); | |
383 ASSERT_EQ(20, h.GetEndpointCoordinate(0)); | |
384 ASSERT_EQ(30, h.GetEndpointCoordinate(1)); | |
385 ASSERT_EQ(40, h.GetEndpointCoordinate(2)); | |
386 ASSERT_EQ(50, h.GetEndpointCoordinate(3)); | |
387 ASSERT_EQ(2u, h.GetProjectedRectanglesCount()); | |
388 ASSERT_EQ(0u, h.GetProjectedRectangleLow(0)); | |
389 ASSERT_EQ(2u, h.GetProjectedRectangleHigh(0)); | |
390 ASSERT_EQ(1u, h.GetProjectedRectangleLow(1)); | |
391 ASSERT_EQ(3u, h.GetProjectedRectangleHigh(1)); | |
392 } | |
393 } | |
394 | |
395 | |
396 static void Convert(std::vector<size_t>& horizontal, | |
397 std::vector<size_t>& vertical, | |
398 const OrthancStone::Internals::OrientedIntegerLine2D::Chain& chain) | |
399 { | |
400 horizontal.clear(); | |
401 vertical.clear(); | |
402 | |
403 for (OrthancStone::Internals::OrientedIntegerLine2D::Chain::const_iterator | |
404 it = chain.begin(); it != chain.end(); ++it) | |
405 { | |
406 horizontal.push_back(it->first); | |
407 vertical.push_back(it->second); | |
408 } | |
409 } | |
410 | |
411 | |
412 TEST(UnionOfRectangles, ExtractChains) | |
413 { | |
414 std::vector<OrthancStone::Internals::OrientedIntegerLine2D> edges; | |
415 edges.push_back(OrthancStone::Internals::OrientedIntegerLine2D(0, 0, 10, 0)); | |
416 edges.push_back(OrthancStone::Internals::OrientedIntegerLine2D(10, 0, 10, 20)); | |
417 edges.push_back(OrthancStone::Internals::OrientedIntegerLine2D(10, 20, 0, 20)); | |
418 | |
419 std::list<OrthancStone::Internals::OrientedIntegerLine2D::Chain> chains; | |
420 OrthancStone::Internals::OrientedIntegerLine2D::ExtractChains(chains, edges); | |
421 | |
422 std::vector<size_t> h, v; | |
423 | |
424 ASSERT_EQ(1u, chains.size()); | |
425 | |
426 Convert(h, v, chains.front()); | |
427 ASSERT_EQ(4u, h.size()); | |
428 ASSERT_EQ(0u, h[0]); | |
429 ASSERT_EQ(10u, h[1]); | |
430 ASSERT_EQ(10u, h[2]); | |
431 ASSERT_EQ(0u, h[3]); | |
432 ASSERT_EQ(4u, v.size()); | |
433 ASSERT_EQ(0u, v[0]); | |
434 ASSERT_EQ(0u, v[1]); | |
435 ASSERT_EQ(20u, v[2]); | |
436 ASSERT_EQ(20u, v[3]); | |
437 | |
438 edges.push_back(OrthancStone::Internals::OrientedIntegerLine2D(5, 5, 10, 5)); | |
439 OrthancStone::Internals::OrientedIntegerLine2D::ExtractChains(chains, edges); | |
440 | |
441 ASSERT_EQ(2u, chains.size()); | |
442 | |
443 Convert(h, v, chains.front()); | |
444 ASSERT_EQ(4u, h.size()); | |
445 ASSERT_EQ(0u, h[0]); | |
446 ASSERT_EQ(10u, h[1]); | |
447 ASSERT_EQ(10u, h[2]); | |
448 ASSERT_EQ(0u, h[3]); | |
449 ASSERT_EQ(4u, v.size()); | |
450 ASSERT_EQ(0u, v[0]); | |
451 ASSERT_EQ(0u, v[1]); | |
452 ASSERT_EQ(20u, v[2]); | |
453 ASSERT_EQ(20u, v[3]); | |
454 | |
455 Convert(h, v, chains.back()); | |
456 ASSERT_EQ(2u, h.size()); | |
457 ASSERT_EQ(5u, h[0]); | |
458 ASSERT_EQ(10u, h[1]); | |
459 ASSERT_EQ(2u, v.size()); | |
460 ASSERT_EQ(5u, v[0]); | |
461 ASSERT_EQ(5u, v[1]); | |
462 | |
463 edges.push_back(OrthancStone::Internals::OrientedIntegerLine2D(0, 20, 5, 5)); | |
464 OrthancStone::Internals::OrientedIntegerLine2D::ExtractChains(chains, edges); | |
465 | |
466 ASSERT_EQ(1u, chains.size()); | |
467 | |
468 Convert(h, v, chains.front()); | |
469 ASSERT_EQ(6u, h.size()); | |
470 ASSERT_EQ(0u, h[0]); | |
471 ASSERT_EQ(10u, h[1]); | |
472 ASSERT_EQ(10u, h[2]); | |
473 ASSERT_EQ(0u, h[3]); | |
474 ASSERT_EQ(5u, h[4]); | |
475 ASSERT_EQ(10u, h[5]); | |
476 ASSERT_EQ(6u, v.size()); | |
477 ASSERT_EQ(0u, v[0]); | |
478 ASSERT_EQ(0u, v[1]); | |
479 ASSERT_EQ(20u, v[2]); | |
480 ASSERT_EQ(20u, v[3]); | |
481 ASSERT_EQ(5u, v[4]); | |
482 ASSERT_EQ(5u, v[5]); | |
483 } | |
484 | |
485 | |
486 TEST(UnionOfRectangles, Textbook) | |
487 { | |
488 // This is Figure 8.12 from textbook | |
489 | |
490 std::list<OrthancStone::Extent2D> rectangles; | |
491 rectangles.push_back(OrthancStone::Extent2D(1, 3, 13, 5)); | |
492 rectangles.push_back(OrthancStone::Extent2D(3, 1, 7, 12)); | |
493 rectangles.push_back(OrthancStone::Extent2D(5, 7, 11, 10)); | |
494 rectangles.push_back(OrthancStone::Extent2D(10, 2, 14, 8)); | |
495 rectangles.push_back(OrthancStone::Extent2D(3, 3, 4, 3)); // empty rectangle | |
496 | |
497 for (unsigned int fillHole = 0; fillHole < 2; fillHole++) | |
498 { | |
499 if (fillHole) | |
500 { | |
501 rectangles.push_back(OrthancStone::Extent2D(6.5, 4.5, 10.5, 7.5)); | |
502 } | |
503 | |
504 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
505 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
506 | |
507 ASSERT_EQ(fillHole ? 1u : 2u, contours.size()); | |
508 ASSERT_EQ(17u, contours.front().size()); | |
509 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(3, 12))); | |
510 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(7, 12))); | |
511 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(7, 10))); | |
512 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(11, 10))); | |
513 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(11, 8))); | |
514 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(14, 8))); | |
515 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(14, 2))); | |
516 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(10, 2))); | |
517 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(10, 3))); | |
518 ASSERT_TRUE(contours.front()[9].IsEqual(OrthancStone::ScenePoint2D(7, 3))); | |
519 ASSERT_TRUE(contours.front()[10].IsEqual(OrthancStone::ScenePoint2D(7, 1))); | |
520 ASSERT_TRUE(contours.front()[11].IsEqual(OrthancStone::ScenePoint2D(3, 1))); | |
521 ASSERT_TRUE(contours.front()[12].IsEqual(OrthancStone::ScenePoint2D(3, 3))); | |
522 ASSERT_TRUE(contours.front()[13].IsEqual(OrthancStone::ScenePoint2D(1, 3))); | |
523 ASSERT_TRUE(contours.front()[14].IsEqual(OrthancStone::ScenePoint2D(1, 5))); | |
524 ASSERT_TRUE(contours.front()[15].IsEqual(OrthancStone::ScenePoint2D(3, 5))); | |
525 ASSERT_TRUE(contours.front()[16].IsEqual(OrthancStone::ScenePoint2D(3, 12))); | |
526 | |
527 if (!fillHole) | |
528 { | |
529 ASSERT_EQ(5u, contours.back().size()); | |
530 ASSERT_TRUE(contours.back()[0].IsEqual(OrthancStone::ScenePoint2D(10, 7))); | |
531 ASSERT_TRUE(contours.back()[1].IsEqual(OrthancStone::ScenePoint2D(7, 7))); | |
532 ASSERT_TRUE(contours.back()[2].IsEqual(OrthancStone::ScenePoint2D(7, 5))); | |
533 ASSERT_TRUE(contours.back()[3].IsEqual(OrthancStone::ScenePoint2D(10, 5))); | |
534 ASSERT_TRUE(contours.back()[4].IsEqual(OrthancStone::ScenePoint2D(10, 7))); | |
535 } | |
536 } | |
537 } | |
538 | |
539 | |
540 #if 0 | |
541 static void SaveSvg(const std::list< std::vector<OrthancStone::ScenePoint2D> >& contours) | |
542 { | |
543 float ww = 15; | |
544 float hh = 13; | |
545 | |
546 FILE* fp = fopen("test.svg", "w"); | |
547 fprintf(fp, "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"); | |
548 fprintf(fp, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n"); | |
549 fprintf(fp, "<svg width=\"%f\" height=\"%f\" viewBox=\"0 0 %f %f\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n", 100.0f*ww, 100.0f*hh, ww, hh); | |
550 | |
551 // http://thenewcode.com/1068/Making-Arrows-in-SVG | |
552 fprintf(fp, "<defs>\n"); | |
553 fprintf(fp, "<marker id=\"arrowhead\" markerWidth=\"2\" markerHeight=\"3\" \n"); | |
554 fprintf(fp, "refX=\"2\" refY=\"1.5\" orient=\"auto\">\n"); | |
555 fprintf(fp, "<polygon points=\"0 0, 2 1.5, 0 3\" />\n"); | |
556 fprintf(fp, "</marker>\n"); | |
557 fprintf(fp, "</defs>\n"); | |
558 | |
559 fprintf(fp, "<rect fill=\"#fff\" stroke=\"#000\" x=\"0\" y=\"0\" width=\"%f\" height=\"%f\"/>\n", ww, hh); | |
560 | |
561 for (std::list< std::vector<OrthancStone::ScenePoint2D> >::const_iterator | |
562 it = contours.begin(); it != contours.end(); ++it) | |
563 { | |
564 for (size_t i = 0; i + 1 < it->size(); i++) | |
565 { | |
566 float x1 = (*it)[i].GetX(); | |
567 float x2 = (*it)[i + 1].GetX(); | |
568 float y1 = (*it)[i].GetY(); | |
569 float y2 = (*it)[i + 1].GetY(); | |
570 | |
571 fprintf(fp, "<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" stroke=\"blue\" stroke-width=\"0.05\" marker-end=\"url(#arrowhead)\"/>\n", x1, y1, x2, y2); | |
572 } | |
573 } | |
574 fprintf(fp, "</svg>\n"); | |
575 | |
576 fclose(fp); | |
577 } | |
578 #endif | |
579 | |
580 | |
581 TEST(UnionOfRectangles, EdgeCases) | |
582 { | |
583 { | |
584 std::list<OrthancStone::Extent2D> rectangles; | |
585 | |
586 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
587 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
588 | |
589 ASSERT_EQ(0u, contours.size()); | |
590 } | |
591 | |
592 { | |
593 std::list<OrthancStone::Extent2D> rectangles; | |
594 rectangles.push_back(OrthancStone::Extent2D(3, 3, 4, 3)); // empty rectangle | |
595 | |
596 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
597 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
598 | |
599 ASSERT_EQ(0u, contours.size()); | |
600 } | |
601 | |
602 { | |
603 std::list<OrthancStone::Extent2D> rectangles; | |
604 rectangles.push_back(OrthancStone::Extent2D(1, 1, 2, 2)); | |
605 | |
606 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
607 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
608 | |
609 ASSERT_EQ(1u, contours.size()); | |
610 ASSERT_EQ(5u, contours.front().size()); | |
611 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(1, 2))); | |
612 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(2, 2))); | |
613 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(2, 1))); | |
614 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(1, 1))); | |
615 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(1, 2))); | |
616 } | |
617 | |
618 { | |
619 std::list<OrthancStone::Extent2D> rectangles; | |
620 rectangles.push_back(OrthancStone::Extent2D(1, 1, 2, 2)); | |
621 rectangles.push_back(OrthancStone::Extent2D(1, 3, 2, 4)); | |
622 | |
623 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
624 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
625 | |
626 ASSERT_EQ(2u, contours.size()); | |
627 | |
628 ASSERT_EQ(5u, contours.front().size()); | |
629 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(1, 4))); | |
630 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(2, 4))); | |
631 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(2, 3))); | |
632 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(1, 3))); | |
633 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(1, 4))); | |
634 | |
635 ASSERT_EQ(5u, contours.back().size()); | |
636 ASSERT_TRUE(contours.back()[0].IsEqual(OrthancStone::ScenePoint2D(1, 2))); | |
637 ASSERT_TRUE(contours.back()[1].IsEqual(OrthancStone::ScenePoint2D(2, 2))); | |
638 ASSERT_TRUE(contours.back()[2].IsEqual(OrthancStone::ScenePoint2D(2, 1))); | |
639 ASSERT_TRUE(contours.back()[3].IsEqual(OrthancStone::ScenePoint2D(1, 1))); | |
640 ASSERT_TRUE(contours.back()[4].IsEqual(OrthancStone::ScenePoint2D(1, 2))); | |
641 } | |
642 | |
643 { | |
644 std::list<OrthancStone::Extent2D> rectangles; | |
645 rectangles.push_back(OrthancStone::Extent2D(1, 4, 4, 6)); | |
646 rectangles.push_back(OrthancStone::Extent2D(4, 6, 7, 8)); | |
647 rectangles.push_back(OrthancStone::Extent2D(4, 2, 7, 4)); | |
648 rectangles.push_back(OrthancStone::Extent2D(7, 4, 10, 6)); | |
649 | |
650 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
651 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
652 | |
653 ASSERT_EQ(1u, contours.size()); | |
654 ASSERT_EQ(17u, contours.front().size()); | |
655 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(4, 8))); | |
656 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(7, 8))); | |
657 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(7, 6))); | |
658 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(10, 6))); | |
659 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(10, 4))); | |
660 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(7, 4))); | |
661 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(7, 2))); | |
662 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(4, 2))); | |
663 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(4, 4))); | |
664 ASSERT_TRUE(contours.front()[9].IsEqual(OrthancStone::ScenePoint2D(7, 4))); | |
665 ASSERT_TRUE(contours.front()[10].IsEqual(OrthancStone::ScenePoint2D(7, 6))); | |
666 ASSERT_TRUE(contours.front()[11].IsEqual(OrthancStone::ScenePoint2D(4, 6))); | |
667 ASSERT_TRUE(contours.front()[12].IsEqual(OrthancStone::ScenePoint2D(4, 4))); | |
668 ASSERT_TRUE(contours.front()[13].IsEqual(OrthancStone::ScenePoint2D(1, 4))); | |
669 ASSERT_TRUE(contours.front()[14].IsEqual(OrthancStone::ScenePoint2D(1, 6))); | |
670 ASSERT_TRUE(contours.front()[15].IsEqual(OrthancStone::ScenePoint2D(4, 6))); | |
671 ASSERT_TRUE(contours.front()[16].IsEqual(OrthancStone::ScenePoint2D(4, 8))); | |
672 } | |
673 | |
674 { | |
675 std::list<OrthancStone::Extent2D> rectangles; | |
676 rectangles.push_back(OrthancStone::Extent2D(1, 4, 4, 6)); | |
677 rectangles.push_back(OrthancStone::Extent2D(4, 4, 7, 6)); | |
678 | |
679 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
680 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
681 | |
682 ASSERT_EQ(1u, contours.size()); | |
683 ASSERT_EQ(5u, contours.front().size()); | |
684 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(1, 6))); | |
685 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(7, 6))); | |
686 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(7, 4))); | |
687 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(1, 4))); | |
688 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(1, 6))); | |
689 } | |
690 | |
691 { | |
692 std::list<OrthancStone::Extent2D> rectangles; | |
693 rectangles.push_back(OrthancStone::Extent2D(1, 4, 4, 6)); | |
694 rectangles.push_back(OrthancStone::Extent2D(1, 6, 4, 8)); | |
695 | |
696 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
697 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
698 | |
699 ASSERT_EQ(1u, contours.size()); | |
700 ASSERT_EQ(5u, contours.front().size()); | |
701 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(1, 8))); | |
702 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(4, 8))); | |
703 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(4, 4))); | |
704 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(1, 4))); | |
705 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(1, 8))); | |
706 } | |
707 | |
708 { | |
709 std::list<OrthancStone::Extent2D> rectangles; | |
710 rectangles.push_back(OrthancStone::Extent2D(1, 1, 2, 2)); | |
711 rectangles.push_back(OrthancStone::Extent2D(4, 4, 7, 6)); | |
712 rectangles.push_back(OrthancStone::Extent2D(4, 6, 7, 8)); | |
713 | |
714 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
715 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
716 | |
717 ASSERT_EQ(2u, contours.size()); | |
718 | |
719 ASSERT_EQ(5u, contours.front().size()); | |
720 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(4, 8))); | |
721 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(7, 8))); | |
722 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(7, 4))); | |
723 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(4, 4))); | |
724 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(4, 8))); | |
725 | |
726 ASSERT_EQ(5u, contours.back().size()); | |
727 ASSERT_TRUE(contours.back()[0].IsEqual(OrthancStone::ScenePoint2D(1, 2))); | |
728 ASSERT_TRUE(contours.back()[1].IsEqual(OrthancStone::ScenePoint2D(2, 2))); | |
729 ASSERT_TRUE(contours.back()[2].IsEqual(OrthancStone::ScenePoint2D(2, 1))); | |
730 ASSERT_TRUE(contours.back()[3].IsEqual(OrthancStone::ScenePoint2D(1, 1))); | |
731 ASSERT_TRUE(contours.back()[4].IsEqual(OrthancStone::ScenePoint2D(1, 2))); | |
732 } | |
733 | |
734 { | |
735 std::list<OrthancStone::Extent2D> rectangles; | |
736 rectangles.push_back(OrthancStone::Extent2D(1, 4, 4, 6)); | |
737 rectangles.push_back(OrthancStone::Extent2D(6, 4, 9, 6)); | |
738 rectangles.push_back(OrthancStone::Extent2D(4, 6, 7, 8)); | |
739 rectangles.push_back(OrthancStone::Extent2D(4, 2, 7, 6)); | |
740 | |
741 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
742 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
743 | |
744 ASSERT_EQ(1u, contours.size()); | |
745 ASSERT_EQ(13u, contours.front().size()); | |
746 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(4, 8))); | |
747 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(7, 8))); | |
748 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(7, 6))); | |
749 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(9, 6))); | |
750 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(9, 4))); | |
751 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(7, 4))); | |
752 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(7, 2))); | |
753 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(4, 2))); | |
754 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(4, 4))); | |
755 ASSERT_TRUE(contours.front()[9].IsEqual(OrthancStone::ScenePoint2D(1, 4))); | |
756 ASSERT_TRUE(contours.front()[10].IsEqual(OrthancStone::ScenePoint2D(1, 6))); | |
757 ASSERT_TRUE(contours.front()[11].IsEqual(OrthancStone::ScenePoint2D(4, 6))); | |
758 ASSERT_TRUE(contours.front()[12].IsEqual(OrthancStone::ScenePoint2D(4, 8))); | |
759 } | |
760 | |
761 { | |
762 std::list<OrthancStone::Extent2D> rectangles; | |
763 rectangles.push_back(OrthancStone::Extent2D(1, 4, 4, 6)); | |
764 rectangles.push_back(OrthancStone::Extent2D(4, 6, 7, 8)); | |
765 rectangles.push_back(OrthancStone::Extent2D(4, 2, 7, 6)); | |
766 | |
767 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
768 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
769 | |
770 ASSERT_EQ(1u, contours.size()); | |
771 ASSERT_EQ(9u, contours.front().size()); | |
772 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(4, 8))); | |
773 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(7, 8))); | |
774 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(7, 2))); | |
775 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(4, 2))); | |
776 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(4, 4))); | |
777 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(1, 4))); | |
778 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(1, 6))); | |
779 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(4, 6))); | |
780 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(4, 8))); | |
781 } | |
782 | |
783 { | |
784 std::list<OrthancStone::Extent2D> rectangles; | |
785 rectangles.push_back(OrthancStone::Extent2D(2, 2, 4, 4)); | |
786 rectangles.push_back(OrthancStone::Extent2D(3, 3, 5, 5)); | |
787 | |
788 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
789 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
790 | |
791 ASSERT_EQ(1u, contours.size()); | |
792 ASSERT_EQ(9u, contours.front().size()); | |
793 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(3, 5))); | |
794 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(5, 5))); | |
795 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(5, 3))); | |
796 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(4, 3))); | |
797 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(4, 2))); | |
798 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(2, 2))); | |
799 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(2, 4))); | |
800 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(3, 4))); | |
801 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(3, 5))); | |
802 } | |
803 | |
804 { | |
805 std::list<OrthancStone::Extent2D> rectangles; | |
806 rectangles.push_back(OrthancStone::Extent2D(2, 2, 4, 4)); | |
807 rectangles.push_back(OrthancStone::Extent2D(3, 1, 5, 3)); | |
808 | |
809 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
810 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
811 | |
812 ASSERT_EQ(1u, contours.size()); | |
813 ASSERT_EQ(9u, contours.front().size()); | |
814 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(2, 4))); | |
815 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(4, 4))); | |
816 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(4, 3))); | |
817 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(5, 3))); | |
818 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(5, 1))); | |
819 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(3, 1))); | |
820 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(3, 2))); | |
821 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(2, 2))); | |
822 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(2, 4))); | |
823 } | |
824 | |
825 { | |
826 std::list<OrthancStone::Extent2D> rectangles; | |
827 rectangles.push_back(OrthancStone::Extent2D(2, 2, 4, 4)); | |
828 rectangles.push_back(OrthancStone::Extent2D(1, 1, 3, 3)); | |
829 | |
830 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
831 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
832 | |
833 ASSERT_EQ(1u, contours.size()); | |
834 ASSERT_EQ(9u, contours.front().size()); | |
835 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(2, 4))); | |
836 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(4, 4))); | |
837 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(4, 2))); | |
838 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(3, 2))); | |
839 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(3, 1))); | |
840 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(1, 1))); | |
841 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(1, 3))); | |
842 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(2, 3))); | |
843 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(2, 4))); | |
844 } | |
845 | |
846 { | |
847 std::list<OrthancStone::Extent2D> rectangles; | |
848 rectangles.push_back(OrthancStone::Extent2D(2, 2, 4, 4)); | |
849 rectangles.push_back(OrthancStone::Extent2D(1, 3, 3, 5)); | |
850 | |
851 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
852 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
853 | |
854 ASSERT_EQ(1u, contours.size()); | |
855 ASSERT_EQ(9u, contours.front().size()); | |
856 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(1, 5))); | |
857 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(3, 5))); | |
858 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(3, 4))); | |
859 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(4, 4))); | |
860 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(4, 2))); | |
861 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(2, 2))); | |
862 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(2, 3))); | |
863 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(1, 3))); | |
864 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(1, 5))); | |
865 } | |
866 | |
867 { | |
868 std::list<OrthancStone::Extent2D> rectangles; | |
869 rectangles.push_back(OrthancStone::Extent2D(2, 2, 3, 3)); | |
870 rectangles.push_back(OrthancStone::Extent2D(3, 1, 4, 2)); | |
871 | |
872 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
873 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
874 | |
875 ASSERT_EQ(1u, contours.size()); | |
876 ASSERT_EQ(9u, contours.front().size()); | |
877 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(2, 3))); | |
878 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(3, 3))); | |
879 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(3, 2))); | |
880 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(4, 2))); | |
881 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(4, 1))); | |
882 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(3, 1))); | |
883 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(3, 2))); | |
884 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(2, 2))); | |
885 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(2, 3))); | |
886 } | |
887 | |
888 { | |
889 std::list<OrthancStone::Extent2D> rectangles; | |
890 rectangles.push_back(OrthancStone::Extent2D(2, 2, 3, 3)); | |
891 rectangles.push_back(OrthancStone::Extent2D(3, 3, 4, 4)); | |
892 | |
893 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
894 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
895 | |
896 ASSERT_EQ(1u, contours.size()); | |
897 ASSERT_EQ(9u, contours.front().size()); | |
898 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(3, 4))); | |
899 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(4, 4))); | |
900 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(4, 3))); | |
901 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(3, 3))); | |
902 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(3, 2))); | |
903 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(2, 2))); | |
904 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(2, 3))); | |
905 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(3, 3))); | |
906 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(3, 4))); | |
907 } | |
908 | |
909 { | |
910 std::list<OrthancStone::Extent2D> rectangles; | |
911 rectangles.push_back(OrthancStone::Extent2D(2, 2, 3, 3)); | |
912 rectangles.push_back(OrthancStone::Extent2D(1, 3, 2, 4)); | |
913 | |
914 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
915 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
916 | |
917 ASSERT_EQ(1u, contours.size()); | |
918 ASSERT_EQ(9u, contours.front().size()); | |
919 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(1, 4))); | |
920 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(2, 4))); | |
921 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(2, 3))); | |
922 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(3, 3))); | |
923 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(3, 2))); | |
924 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(2, 2))); | |
925 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(2, 3))); | |
926 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(1, 3))); | |
927 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(1, 4))); | |
928 } | |
929 | |
930 { | |
931 std::list<OrthancStone::Extent2D> rectangles; | |
932 rectangles.push_back(OrthancStone::Extent2D(2, 2, 3, 3)); | |
933 rectangles.push_back(OrthancStone::Extent2D(1, 1, 2, 2)); | |
934 | |
935 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
936 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
937 | |
938 ASSERT_EQ(1u, contours.size()); | |
939 ASSERT_EQ(9u, contours.front().size()); | |
940 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(2, 3))); | |
941 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(3, 3))); | |
942 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(3, 2))); | |
943 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(2, 2))); | |
944 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(2, 1))); | |
945 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(1, 1))); | |
946 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(1, 2))); | |
947 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(2, 2))); | |
948 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(2, 3))); | |
949 } | |
950 | |
951 { | |
952 std::list<OrthancStone::Extent2D> rectangles; | |
953 rectangles.push_back(OrthancStone::Extent2D(2, 2, 3, 5)); | |
954 rectangles.push_back(OrthancStone::Extent2D(1, 3, 4, 4)); | |
955 | |
956 std::list< std::vector<OrthancStone::ScenePoint2D> > contours; | |
957 OrthancStone::UnionOfRectangles::Apply(contours, rectangles); | |
958 | |
959 ASSERT_EQ(1u, contours.size()); | |
960 ASSERT_EQ(13u, contours.front().size()); | |
961 ASSERT_TRUE(contours.front()[0].IsEqual(OrthancStone::ScenePoint2D(2, 5))); | |
962 ASSERT_TRUE(contours.front()[1].IsEqual(OrthancStone::ScenePoint2D(3, 5))); | |
963 ASSERT_TRUE(contours.front()[2].IsEqual(OrthancStone::ScenePoint2D(3, 4))); | |
964 ASSERT_TRUE(contours.front()[3].IsEqual(OrthancStone::ScenePoint2D(4, 4))); | |
965 ASSERT_TRUE(contours.front()[4].IsEqual(OrthancStone::ScenePoint2D(4, 3))); | |
966 ASSERT_TRUE(contours.front()[5].IsEqual(OrthancStone::ScenePoint2D(3, 3))); | |
967 ASSERT_TRUE(contours.front()[6].IsEqual(OrthancStone::ScenePoint2D(3, 2))); | |
968 ASSERT_TRUE(contours.front()[7].IsEqual(OrthancStone::ScenePoint2D(2, 2))); | |
969 ASSERT_TRUE(contours.front()[8].IsEqual(OrthancStone::ScenePoint2D(2, 3))); | |
970 ASSERT_TRUE(contours.front()[9].IsEqual(OrthancStone::ScenePoint2D(1, 3))); | |
971 ASSERT_TRUE(contours.front()[10].IsEqual(OrthancStone::ScenePoint2D(1, 4))); | |
972 ASSERT_TRUE(contours.front()[11].IsEqual(OrthancStone::ScenePoint2D(2, 4))); | |
973 ASSERT_TRUE(contours.front()[12].IsEqual(OrthancStone::ScenePoint2D(2, 5))); | |
974 } | |
975 } |