Finite Element Domain Decomposition Library
FEDDLib
Loading...
Searching...
No Matches
AABBTree_def.hpp
1#ifndef AABBTree_def_hpp
2#define AABBTree_def_hpp
3
4#include "AABBTree_decl.hpp"
5
14
15namespace FEDD{
16 // Default Constructor
17 template <class SC, class LO, class GO, class NO>
18 AABBTree<SC, LO, GO, NO>::AABBTree():
19 empty_(true),
20 dim_(),
21 numNodes_(),
22 minXY_(),
23 maxXY_(),
24 parentChild_(),
25 containedElements_()
26 {
27 }
28
29
30 /*
31 Creates a new AABBTree from given Element- and node-vector.
32 Finds minimal AABB for each element and uses them to call
33 AABBTree::createTreeFromRectangles
34 */
35 template <class SC, class LO, class GO, class NO> \
36 void AABBTree<SC, LO, GO, NO>::createTreeFromElements(
37 ElementsPtr_Type elements,
38 vec2D_dbl_ptr_Type nodes,
39 int numberObjects, // = 32,
40 double longTol, // = 0.75,
41 double volumeTol, // = 0.55,
42 bool verbose // = false
43 ){
44
45 if (verbose){
46 std::cout << " Starting AABBTree::'createTreeFromElements'" << '\n';
47 }
48
49 std::cout << " Starting to create an AABB-Tree" << '\n';
50 int numElems = elements->numberElements();
51
52
53 vec2D_dbl_ptr_Type triangleMinMax( // point_min_max per triangle
54 new vec2D_dbl_Type(
55 numElems,
56 vec_dbl_Type(4, 0.0)
57 )
58 );
59
60 vec_int_Type localNodes;
61 int currentNode;
62 double currentNodeX, currentNodeY;
63
64 for (int elem=0; elem<numElems; elem++){
65 localNodes = elements->getElement(elem).getVectorNodeList();
66 // Initialize with first point
67 currentNode = localNodes[0];
68 currentNodeX = nodes->at(currentNode).at(0);
69 currentNodeY = nodes->at(currentNode).at(1);
70
71 triangleMinMax->at(elem).at(0) = currentNodeX;
72 triangleMinMax->at(elem).at(1) = currentNodeY;
73
74 triangleMinMax->at(elem).at(2) = currentNodeX;
75 triangleMinMax->at(elem).at(3) = currentNodeY;
76 for ( int node=1; node<3; node++ ){
77 currentNode = localNodes[node];
78 currentNodeX = nodes->at(currentNode).at(0);
79 currentNodeY = nodes->at(currentNode).at(1);
80 // Find min_x
81 if ( currentNodeX < triangleMinMax->at(elem).at(0) )
82 triangleMinMax->at(elem).at(0) = currentNodeX;
83 // Find min_y
84 if ( currentNodeY < triangleMinMax->at(elem).at(1) )
85 triangleMinMax->at(elem).at(1) = currentNodeY;
86 // Find max_x
87 if ( currentNodeX > triangleMinMax->at(elem).at(2) )
88 triangleMinMax->at(elem).at(2) = currentNodeX;
89 // Find max_y
90 if ( currentNodeY > triangleMinMax->at(elem).at(3) )
91 triangleMinMax->at(elem).at(3) = currentNodeY;
92 }
93 }
94
95 createTreeFromRectangles(
96 triangleMinMax,
97 numberObjects,
98 longTol,
99 volumeTol,
100 verbose
101 );
102
103 if (verbose){
104 std::cout << " Ending AABBTree::'createTreeFromElements'" << '\n';
105 }
106 }
107
108
109 /*
110 Creates a new AABBTree from the given rectangle list
111 Expects each rectangle to conform to one element
112 Forms a binary search tree, such that each
113 "leaf" node in the tree encloses a maximum number of re-
114 ctangles. The tree is formed by recursively subdividing
115 the bounding-box of the collection. At each division, a
116 simple heuristic is used to determine a splitting axis
117 and to position an axis-aligned splitting (hyper-)plane.
118 The associated collection of rectangles is partitioned
119 between two new child nodes. The dimensions of each node
120 in the tree are selected to provide a minimal enclosure
121 of the rectangles in its associated sub-tree. Tree nodes
122 may overlap as a result.
123 */
124 template <class SC, class LO, class GO, class NO> \
125 void AABBTree<SC, LO, GO, NO>::createTreeFromRectangles(
126 vec2D_dbl_ptr_Type initMinMaxXY,
127 int numberObjects, // = 32
128 double longTol, // = 0.75
129 double volumeTol, // = 0.55
130 bool verbose // = false
131 ){
132 // initMinMaxXY:
133 // double-Vector with four columns and numElems rows
134 // containing min_x, min_y, max_x and max_y for each initial rectangle
135 // numberObjects:
136 // Desired number of objects per node (bound population control)
137 // longTol, volumeTol:
138 // bound tolerance, in respect to side-length along the splitting
139 // axis and volume of the rectangle, that define whether
140 // to split or not
141
142
143 if (verbose){
144 std::cout << " Starting AABBTree::'createTreeFromRectangles'" << '\n';
145 }
146 // FIXME: Do some Error-Checking here
147
148 // Number of Elements
149 int numberElements = initMinMaxXY->size();
150 std::cout << " Number of Elements = " << numberElements << '\n';
151
152 //***********************************************************************//
153 //
154 // Start by defining a rectangle that contains all other rectangles and
155 // initializing variables we need later
156 //
157 //***********************************************************************//
158
159 // Allocate Workspace
160 vec2D_dbl_ptr_Type recMin(
161 new vec2D_dbl_Type(
162 numberElements,
163 vec_dbl_Type(2, 0.0)
164 )
165 );
166 vec2D_dbl_ptr_Type recMax(
167 new vec2D_dbl_Type(
168 numberElements,
169 vec_dbl_Type(2, 0.0)
170 )
171 );
172
173 vec2D_int_ptr_Type parentChild
174 (new vec2D_int_Type(
175 numberElements,
176 vec_int_Type(2, 0)
177 )
178 );
179
180 std::vector<std::list<int> > containedElements(
181 numberElements,
182 std::list<int>()
183 );
184
185 vec_int_Type stack(numberElements, 0);
186
187 // find min and max coords
188 vec_dbl_Type bigMinMax = initMinMaxXY->at(0);
189 for(int elem=1; elem<numberElements; elem++){
190 if (initMinMaxXY->at(elem).at(0) < bigMinMax[0])
191 bigMinMax[0] = initMinMaxXY->at(elem).at(0);
192 if (initMinMaxXY->at(elem).at(1) < bigMinMax[1])
193 bigMinMax[1] = initMinMaxXY->at(elem).at(1);
194 if (initMinMaxXY->at(elem).at(2) > bigMinMax[2])
195 bigMinMax[2] = initMinMaxXY->at(elem).at(2);
196 if (initMinMaxXY->at(elem).at(3) > bigMinMax[3])
197 bigMinMax[3] = initMinMaxXY->at(elem).at(3);
198 }
199
200 // Make rectangles slightly larger
201 vec_dbl_Type inflateBy(2, 0.0);
202 inflateBy[0] = bigMinMax[2] - bigMinMax[0];
203 inflateBy[1] = bigMinMax[3] - bigMinMax[1];
204 for (int elem=0; elem<numberElements; elem++){
205 initMinMaxXY->at(elem).at(0) -= 1e-13 * inflateBy[0];
206 initMinMaxXY->at(elem).at(1) -= 1e-13 * inflateBy[1];
207 initMinMaxXY->at(elem).at(2) += 1e-13 * inflateBy[0];
208 initMinMaxXY->at(elem).at(3) += 1e-13 * inflateBy[1];
209 }
210
211 vec2D_dbl_ptr_Type recCenter( // rectangle center
212 new vec2D_dbl_Type(
213 numberElements,
214 vec_dbl_Type(2, 0.0)
215 )
216 );
217
218 vec2D_dbl_ptr_Type recLength( // rectangle length
219 new vec2D_dbl_Type(
220 numberElements,
221 vec_dbl_Type(2, 0.0)
222 )
223 );
224
225 // Calculate rectangle center and length
226 for (int elem = 0; elem<numberElements; elem++){
227 recCenter->at(elem).at(0) = initMinMaxXY->at(elem).at(0) + initMinMaxXY->at(elem).at(2);
228 recCenter->at(elem).at(0) *= 0.5;
229 recCenter->at(elem).at(1) = initMinMaxXY->at(elem).at(1) + initMinMaxXY->at(elem).at(3);
230 recCenter->at(elem).at(1) *= 0.5;
231
232 recLength->at(elem).at(0) = initMinMaxXY->at(elem).at(2) - initMinMaxXY->at(elem).at(0);
233 recLength->at(elem).at(0) = initMinMaxXY->at(elem).at(3) - initMinMaxXY->at(elem).at(1);
234 }
235
236 // First Rectangle contains all other rectangles
237
238 recMin->at(0).at(0) = bigMinMax[0] - 1e-13 * inflateBy[0];
239 recMin->at(0).at(1) = bigMinMax[1] - 1e-13 * inflateBy[1];
240 recMax->at(0).at(0) = bigMinMax[2] + 1e-13 * inflateBy[0];
241 recMax->at(0).at(1) = bigMinMax[3] + 1e-13 * inflateBy[1];
242
243 for (int elem = 0; elem<numberElements; elem++){
244 containedElements[0].push_back(elem);
245 }
246
247 if (verbose){
248 std::cout << " First rectangle = " << recMin->at(0).at(0) << ", " << recMin->at(0).at(1)<< ", " << recMax->at(0).at(0) << ", " << recMax->at(0).at(1) << '\n';
249 }
250
251
252 //***********************************************************************//
253 //
254 // Main Loop: divide nodes untill all constraints are satisfied
255 //
256 //***********************************************************************//
257 stack[0] = 0;
258 int nodesOnStack = 0;
259 int numberNodes = 1;
260 int sonLeft, sonRight, parentNode, axis;
261 int countCurrentElements, countShortRectangles, countLongRectangles;
262 int countLeft, countRight;
263 double lengthAxis, splitPosition, volumeParent, volumeLeft, volumeRight;
264 std::list<int> currentElements;
265 vec_dbl_Type dd(2, 0.0);
266 vec_int_Type ia(2, 0);
267 std::vector<bool> isLong(numberElements, false);
268 std::vector<bool> isLeft(numberElements, false);
269 if (verbose){
270 std::cout << "##### Beginning Main Loop #####" << '\n';
271 }
272 while (nodesOnStack != -1){
273 if (verbose){
274 std::cout << " nodesOnStack = " << nodesOnStack << '\n';
275 }
276 // pop node from stack
277 parentNode = stack[nodesOnStack];
278 nodesOnStack = nodesOnStack - 1;
279
280 if (verbose){
281 std::cout << " main loop for node = " << parentNode << '\n';
282 }
283
284 // push child indexing
285 sonLeft = numberNodes;
286 sonRight = numberNodes + 1;
287
288 if (verbose){
289 std::cout << " sonLeft = " << sonLeft << '\n';
290 std::cout << " sonRight = " << sonRight << '\n';
291 }
292
293 // set of rectangles in parent
294 currentElements = containedElements[parentNode];
295 countCurrentElements = currentElements.size();
296 if (verbose){
297 std::cout << " count currentElements = " << countCurrentElements << '\n';
298 }
299 // split plane on longest axis
300 dd[0] = recMax->at(parentNode).at(0) - recMin->at(parentNode).at(0);
301 dd[1] = recMax->at(parentNode).at(1) - recMin->at(parentNode).at(1);
302
303 // sorting by which axis to split
304 if (dd[0] < dd[1]){
305 ia[0] = 0;
306 ia[1] = 1;
307 }
308 else{
309 ia[1] = 0;
310 ia[0] = 1;
311 }
312
313 if (verbose){
314 std::cout << " lengthAxis[0] = " << dd[0] << ", lengthAxis[1] = "<< dd[1] << '\n';
315 }
316
317 for (int id=1; id>-1; id--){
318 // push rectangles to children
319 axis = ia[id];
320 lengthAxis = dd[id];
321
322 countShortRectangles = 0;
323 countLongRectangles = 0;
324 for (auto const& elem : currentElements) {
325 if(recLength->at(elem).at(axis) > longTol * lengthAxis){
326 // long rectangles
327 isLong[elem] = true;
328 countLongRectangles += 1;
329 }
330 else {
331 // short rectangles
332 isLong[elem] = false;
333 countShortRectangles += 1;
334 }
335 }
336 if (countLongRectangles < 0.5*countShortRectangles
337 && countLongRectangles < 0.5 * numberObjects){
338 break;
339 }
340 }
341 if (verbose){
342 std::cout << " splitting on axis = " << axis << ", with length = " << lengthAxis << '\n';
343 std::cout << " countShortRectangles = " << countShortRectangles << '\n';
344 std::cout << " countLongRectangles = " << countLongRectangles << '\n';
345 }
346
347 if(countShortRectangles == 0){
348 // The partition is empty, we are done
349 continue;
350 }
351
352 // select the split position: take the mean of the set of
353 // (non-"long") rectangle centres along axis AX
354 splitPosition = 0.0;
355 for (auto const& elem : currentElements){
356 if (!isLong[elem]){
357 splitPosition = splitPosition + recCenter->at(elem).at(axis);
358 }
359 }
360 splitPosition = splitPosition / countShortRectangles;
361
362 if (verbose){
363 std::cout << " split position = " << splitPosition << '\n';
364 }
365
366 // partition elements based on centres
367 // if isLeft == true, the elment goes to the left rectangle, if == false
368 // the element goes to the right rectangle
369 countLeft = 0;
370 countRight = 0;
371 for (auto const& elem : currentElements){
372 if (!isLong[elem]){
373 if (recCenter->at(elem).at(axis) < splitPosition){
374 isLeft[elem] = true;
375 countLeft += 1;
376 }
377 else {
378 isLeft[elem] = false;
379 countRight +=1;
380 }
381 }
382 }
383
384 if (verbose){
385 std::cout << " countLeft = " << countLeft << '\n';
386 std::cout << " countRight = " << countRight << '\n';
387 }
388 if (countLeft == 0 || countRight == 0) {
389 // The partition is empty, we are done
390 continue;
391 }
392
393 // Finalise node position and push elemts downwards
394 //Initialize with previous rectangle, but in reverse
395 recMin->at(sonLeft).at(0) = recMax->at(parentNode).at(0);
396 recMin->at(sonLeft).at(1) = recMax->at(parentNode).at(1);
397 recMax->at(sonLeft).at(0) = recMin->at(parentNode).at(0);
398 recMax->at(sonLeft).at(1) = recMin->at(parentNode).at(1);
399
400 recMin->at(sonRight).at(0) = recMax->at(parentNode).at(0);
401 recMin->at(sonRight).at(1) = recMax->at(parentNode).at(0);
402 recMax->at(sonRight).at(0) = recMin->at(parentNode).at(0);
403 recMax->at(sonRight).at(1) = recMin->at(parentNode).at(0);
404 containedElements[parentNode].clear();
405 containedElements[sonLeft].clear();
406 containedElements[sonRight].clear();
407 for(auto elem : currentElements){
408 if (isLong[elem]){
409 // long elements will not be pushed down
410 containedElements[parentNode].push_back(elem);
411 }
412 else{
413
414 if (isLeft[elem]){
415 // element is in left rectangle, push it down to sonLeft
416 containedElements[sonLeft].push_back(elem);
417 if (initMinMaxXY->at(elem).at(0) < recMin->at(sonLeft).at(0)){
418 recMin->at(sonLeft).at(0) = initMinMaxXY->at(elem).at(0);
419 }
420 if (initMinMaxXY->at(elem).at(1) < recMin->at(sonLeft).at(1)){
421 recMin->at(sonLeft).at(1) = initMinMaxXY->at(elem).at(1);
422 }
423 if (initMinMaxXY->at(elem).at(2) > recMax->at(sonLeft).at(0)){
424 recMax->at(sonLeft).at(0) = initMinMaxXY->at(elem).at(2);
425 }
426 if (initMinMaxXY->at(elem).at(3) > recMax->at(sonLeft).at(1)){
427 recMax->at(sonLeft).at(1) = initMinMaxXY->at(elem).at(3);
428 }
429 }
430 else {
431 // element is in right rectangle, push it down to rightSon
432 containedElements[sonRight].push_back(elem);
433 if (initMinMaxXY->at(elem).at(0) < recMin->at(sonRight).at(0)){
434 recMin->at(sonRight).at(0) = initMinMaxXY->at(elem).at(0);
435 }
436 if (initMinMaxXY->at(elem).at(1) < recMin->at(sonRight).at(1)){
437 recMin->at(sonRight).at(1) = initMinMaxXY->at(elem).at(1);
438 }
439 if (initMinMaxXY->at(elem).at(2) > recMax->at(sonRight).at(0)){
440 recMax->at(sonRight).at(0) = initMinMaxXY->at(elem).at(2);
441 }
442 if (initMinMaxXY->at(elem).at(3) > recMax->at(sonRight).at(1)){
443 recMax->at(sonRight).at(1) = initMinMaxXY->at(elem).at(3);
444 }
445 }
446 }
447 }
448
449 if (verbose){
450 std::cout << " left rectangle (" << recMin->at(sonLeft).at(0) << ", " << recMin->at(sonLeft).at(1)<< "), (" << recMax->at(sonLeft).at(0) << ", " << recMax->at(sonLeft).at(1) << ")"<<'\n';
451 std::cout << " right rectangle (" << recMin->at(sonRight).at(0) << ", " << recMin->at(sonRight).at(1)<< "), (" << recMax->at(sonRight).at(0) << ", " << recMax->at(sonRight).at(1) << ")"<<'\n';
452 }
453
454 if (countCurrentElements <= numberObjects){
455 // if we are already below our desired number of objects we will only
456 // split if the volume constraint is not yet satisfied
457 if (verbose){
458 std::cout << " Checking for Volume Constraint (ie objects constraint satisfied)" << '\n';
459 }
460 volumeParent = \
461 (recMax->at(parentNode).at(0) - recMin->at(parentNode).at(0))\
462 * (recMax->at(parentNode).at(1) - recMin->at(parentNode).at(1));
463 volumeLeft = \
464 (recMax->at(sonLeft).at(0) - recMin->at(sonLeft).at(0))\
465 * (recMax->at(sonLeft).at(1) - recMin->at(sonLeft).at(1));
466 volumeRight = \
467 (recMax->at(sonRight).at(0) - recMin->at(sonRight).at(0))\
468 * (recMax->at(sonRight).at(1) - recMin->at(sonRight).at(1));
469 if (volumeLeft + volumeRight < volumeTol * volumeParent){
470 // parent-child indexing
471 parentChild->at(sonLeft).at(0) = parentNode;
472 parentChild->at(sonRight).at(0) = parentNode;
473 parentChild->at(parentNode).at(1) = sonLeft;
474
475 stack[nodesOnStack + 1] = sonLeft;
476 stack[nodesOnStack + 2] = sonRight;
477 nodesOnStack = nodesOnStack + 2;
478 numberNodes = numberNodes + 2;
479 }
480 else{
481 // all Constraints satisfied, no partition needed
482 // pull al elemts back to the parentNode
483 containedElements[parentNode].splice(
484 containedElements[parentNode].begin(),
485 containedElements[sonLeft]
486 );
487 containedElements[parentNode].splice(
488 containedElements[parentNode].begin(),
489 containedElements[sonRight]
490 );
491 }
492 }
493 else {
494 // object constraint is not satisfied, so we split
495 if (verbose){
496 std::cout << " Objects constraint not satisfied, Setting indices" << '\n';
497 }
498 parentChild->at(sonLeft).at(0) = parentNode;
499 parentChild->at(sonRight).at(0) = parentNode;
500 parentChild->at(parentNode).at(1) = sonLeft;
501 stack[nodesOnStack + 1] = sonLeft;
502 stack[nodesOnStack + 2] = sonRight;
503 nodesOnStack = nodesOnStack + 2;
504 numberNodes = numberNodes + 2;
505 }
506
507 if (verbose){
508 std::cout << " nodesOnStack = " << nodesOnStack << '\n';
509 }
510
511 if (verbose){
512 std::cout << " " << '\n';
513 }
514
515 } // end MAIN-LOOP
516 if (verbose){
517 std::cout << "##### End Main Loop #####" << '\n';
518 }
519
520 std::cout << " Number of nodes in Tree = " << numberNodes << '\n';
521
522 // trim allocation
523 recMin->resize(numberNodes);
524 recMax->resize(numberNodes);
525 parentChild->resize(numberNodes);
526 containedElements.resize(numberNodes);
527
528 // Saving data in class-members
529 this->dim_ = 2;
530 this->numNodes_ = numberNodes;
531 this->minXY_ = recMin;
532 this->maxXY_ = recMax;
533 this->parentChild_ = parentChild;
534 this->containedElements_ = containedElements;
535 this->empty_ = false;
536
537 if (verbose){
538 std::cout << "##### End AABBTree::'createTreeFromRectangles' #####" << '\n';
539 }
540 }
541
542
543 /*
544 Low level routine that returns the tree-to-item mapping for a collection
545 of query points.
546 returns:
547
548 The tree-to-item mapping (i : list<int>) where i corresponds to the
549 i-th node and and list<int> contains the number of query points that
550 intersect with the i-th node.
551
552 The item-to-tree mapping (i : list<int>) where i corresponds to the
553 i-th query point and list<int> contains the number of nodes that
554 intersect with the i-th query point.
555 */
556 template <class SC, class LO, class GO, class NO> \
557 std::tuple<std::map<int, std::list<int>>, std::map<int, std::list<int> > > \
558 AABBTree<SC, LO, GO, NO>::scanTree(
559 vec2D_dbl_ptr_Type queryPoints,
560 bool verbose
561 ){
562
563 if (verbose){
564 std::cout << " Starting AABBTree::'scanTree'" << '\n';
565 }
566 // FIXME: Catch some errors where
567 if (queryPoints->at(0).size() != this->dim_){
568 std::cerr << "Query point dimension =" << queryPoints->at(0).size() << ", but expected dim = " << this->dim_ << '\n';
569 }
570 int numberQueryPoints = queryPoints->size();
571
572 // Allocate Workspace
573 std::map<int, std::list<int>> treeToItem;
574 std::map<int, std::list<int>> itemToTree;
575
576
577 //***********************************************************************//
578 //
579 // Start by calculating treeToItem
580 //
581 //***********************************************************************//
582
583 vec_int_Type stack(
584 this->numNodes_,
585 0
586 );
587 std::vector<std::list<int> > pointsInNode(
588 this->numNodes_,
589 std::list<int>()
590 );
591
592 int leftSon, rightSon;
593 int nodesOnStack = 0;
594 int parentNode, no=0;
595 stack[0] = 0;
596 for (int point = 0; point<queryPoints->size(); point++){
597 pointsInNode[0].push_back(point);
598 }
599 while (nodesOnStack != -1){
600 // pop node from stack
601 parentNode = stack[nodesOnStack];
602 nodesOnStack = nodesOnStack - 1;
603
604 if (verbose){
605 std::cout << " main loop for node = " << parentNode << '\n';
606 }
607
608 if (!this->containedElements_[parentNode].empty()){
609 // non-empty node contains items, push onto tree-item mapping
610 treeToItem[parentNode] = pointsInNode[parentNode];
611 no = no + 1;
612 if (verbose){
613 std::cout << " Node " << parentNode << " is not empty, pushing onto tree-item mapping" << '\n';
614 }
615 }
616
617 if(this->parentChild_->at(parentNode).at(1) != 0){
618 // partition amongst child nodes
619 leftSon = parentChild_->at(parentNode).at(1);
620 rightSon = parentChild_->at(parentNode).at(1) + 1;
621 if(verbose){
622 std::cout << "leftSon = "<< leftSon << ", rightSon = " << rightSon <<'\n';
623 }
624 // partition of points
625 for (auto point : pointsInNode[parentNode]){
626 if(isInRectangle(leftSon, queryPoints->at(point), false)){
627 // point is in leftSon
628 pointsInNode[leftSon].push_back(point);
629 }
630 if(isInRectangle(rightSon, queryPoints->at(point), false)){
631 // point is in rightSon
632 pointsInNode[rightSon].push_back(point);
633 }
634 }
635 if (!pointsInNode[leftSon].empty()){
636 // leftSon has queryPoints in it, push node to stack
637 nodesOnStack = nodesOnStack + 1;
638 stack[nodesOnStack] = leftSon;
639 if (verbose){
640 }
641 }
642 if (!pointsInNode[leftSon].empty()){
643 // rightSon has queryPoints in it, push node to stack
644 nodesOnStack = nodesOnStack + 1;
645 stack[nodesOnStack] = rightSon;
646 }
647 }
648 }
649
650 //***********************************************************************//
651 //
652 // Calculate itemToTree, which is the inverse of treeToItem
653 //
654 //***********************************************************************//
655
656 for (auto keyValue: treeToItem){
657 // iterate through treeToItem, i.e. 'for each node with points in it'
658 for (auto value: keyValue.second){
659 // iterate through points in node
660 itemToTree[value].push_back(keyValue.first);
661 }
662 }
663
664 if (verbose){
665 std::cout << " End AABBTree::'scanTree'" << '\n';
666 }
667
668 return std::make_tuple(treeToItem, itemToTree);
669 } // End scanTree
670
671 /*
672 Is a given query point in a given rectangle?
673 */
674 template <class SC, class LO, class GO, class NO> \
675 bool \
676 AABBTree<SC, LO, GO, NO>::isInRectangle(
677 int numberRectangle,
678 vec_dbl_Type queryPoint,
679 bool verbose
680 ){
681
682 bool result = true;
683 if (verbose){
684 std::cout << " Start AABBTree::'isInRectangle'" << '\n';
685 }
686
687 vec_dbl_Type rectangleMin, rectangleMax;
688 rectangleMin = this->minXY_->at(numberRectangle);
689 rectangleMax = this->maxXY_->at(numberRectangle);
690
691 for (int dim = 0; dim < this->dim_-1; dim ++){
692 if(result \
693 && queryPoint[dim] > rectangleMin[dim] \
694 && queryPoint[dim] < rectangleMax[dim]){
695 result = true;
696 }
697 else{
698 result = false;
699 }
700 }
701 if (verbose){
702 std::cout << " End AABBTree::'isInRectangle'" << '\n';
703 }
704 return result;
705 }
706
707
708 template <class SC, class LO, class GO, class NO> \
709 bool AABBTree<SC, LO, GO, NO>::isEmpty(){
710 return empty_;
711 }
712
713 template <class SC, class LO, class GO, class NO> \
714 int AABBTree<SC, LO, GO, NO>::getDim(){
715 return dim_;
716 }
717
718 template <class SC, class LO, class GO, class NO> \
719 int AABBTree<SC, LO, GO, NO>::getNumNodes(){
720 return numNodes_;
721 }
722
723 template <class SC, class LO, class GO, class NO> \
724 std::list<int> AABBTree<SC, LO, GO, NO>::getElements(int node){
725 return containedElements_[node];
726 }
727
728
729}
730
731
732#endif //AABBTree_def_hpp
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5