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