1#ifndef AABBTree_def_hpp
2#define AABBTree_def_hpp
4#include "AABBTree_decl.hpp"
17 template <
class SC,
class LO,
class GO,
class NO>
18 AABBTree<SC, LO, GO, NO>::AABBTree():
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,
46 std::cout <<
" Starting AABBTree::'createTreeFromElements'" <<
'\n';
49 std::cout <<
" Starting to create an AABB-Tree" <<
'\n';
50 int numElems = elements->numberElements();
53 vec2D_dbl_ptr_Type triangleMinMax(
60 vec_int_Type localNodes;
62 double currentNodeX, currentNodeY;
64 for (
int elem=0; elem<numElems; elem++){
65 localNodes = elements->getElement(elem).getVectorNodeList();
67 currentNode = localNodes[0];
68 currentNodeX = nodes->at(currentNode).at(0);
69 currentNodeY = nodes->at(currentNode).at(1);
71 triangleMinMax->at(elem).at(0) = currentNodeX;
72 triangleMinMax->at(elem).at(1) = currentNodeY;
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);
81 if ( currentNodeX < triangleMinMax->at(elem).at(0) )
82 triangleMinMax->at(elem).at(0) = currentNodeX;
84 if ( currentNodeY < triangleMinMax->at(elem).at(1) )
85 triangleMinMax->at(elem).at(1) = currentNodeY;
87 if ( currentNodeX > triangleMinMax->at(elem).at(2) )
88 triangleMinMax->at(elem).at(2) = currentNodeX;
90 if ( currentNodeY > triangleMinMax->at(elem).at(3) )
91 triangleMinMax->at(elem).at(3) = currentNodeY;
95 createTreeFromRectangles(
104 std::cout <<
" Ending AABBTree::'createTreeFromElements'" <<
'\n';
124 template <
class SC,
class LO,
class GO,
class NO> \
125 void AABBTree<SC, LO, GO, NO>::createTreeFromRectangles(
126 vec2D_dbl_ptr_Type initMinMaxXY,
144 std::cout <<
" Starting AABBTree::'createTreeFromRectangles'" <<
'\n';
149 int numberElements = initMinMaxXY->size();
150 std::cout <<
" Number of Elements = " << numberElements <<
'\n';
160 vec2D_dbl_ptr_Type recMin(
166 vec2D_dbl_ptr_Type recMax(
173 vec2D_int_ptr_Type parentChild
180 std::vector<std::list<int> > containedElements(
185 vec_int_Type stack(numberElements, 0);
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);
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];
211 vec2D_dbl_ptr_Type recCenter(
218 vec2D_dbl_ptr_Type recLength(
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;
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);
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];
243 for (
int elem = 0; elem<numberElements; elem++){
244 containedElements[0].push_back(elem);
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';
258 int nodesOnStack = 0;
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);
270 std::cout <<
"##### Beginning Main Loop #####" <<
'\n';
272 while (nodesOnStack != -1){
274 std::cout <<
" nodesOnStack = " << nodesOnStack <<
'\n';
277 parentNode = stack[nodesOnStack];
278 nodesOnStack = nodesOnStack - 1;
281 std::cout <<
" main loop for node = " << parentNode <<
'\n';
285 sonLeft = numberNodes;
286 sonRight = numberNodes + 1;
289 std::cout <<
" sonLeft = " << sonLeft <<
'\n';
290 std::cout <<
" sonRight = " << sonRight <<
'\n';
294 currentElements = containedElements[parentNode];
295 countCurrentElements = currentElements.size();
297 std::cout <<
" count currentElements = " << countCurrentElements <<
'\n';
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);
314 std::cout <<
" lengthAxis[0] = " << dd[0] <<
", lengthAxis[1] = "<< dd[1] <<
'\n';
317 for (
int id=1;
id>-1;
id--){
322 countShortRectangles = 0;
323 countLongRectangles = 0;
324 for (
auto const& elem : currentElements) {
325 if(recLength->at(elem).at(axis) > longTol * lengthAxis){
328 countLongRectangles += 1;
332 isLong[elem] =
false;
333 countShortRectangles += 1;
336 if (countLongRectangles < 0.5*countShortRectangles
337 && countLongRectangles < 0.5 * numberObjects){
342 std::cout <<
" splitting on axis = " << axis <<
", with length = " << lengthAxis <<
'\n';
343 std::cout <<
" countShortRectangles = " << countShortRectangles <<
'\n';
344 std::cout <<
" countLongRectangles = " << countLongRectangles <<
'\n';
347 if(countShortRectangles == 0){
355 for (
auto const& elem : currentElements){
357 splitPosition = splitPosition + recCenter->at(elem).at(axis);
360 splitPosition = splitPosition / countShortRectangles;
363 std::cout <<
" split position = " << splitPosition <<
'\n';
371 for (
auto const& elem : currentElements){
373 if (recCenter->at(elem).at(axis) < splitPosition){
378 isLeft[elem] =
false;
385 std::cout <<
" countLeft = " << countLeft <<
'\n';
386 std::cout <<
" countRight = " << countRight <<
'\n';
388 if (countLeft == 0 || countRight == 0) {
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);
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){
410 containedElements[parentNode].push_back(elem);
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);
420 if (initMinMaxXY->at(elem).at(1) < recMin->at(sonLeft).at(1)){
421 recMin->at(sonLeft).at(1) = initMinMaxXY->at(elem).at(1);
423 if (initMinMaxXY->at(elem).at(2) > recMax->at(sonLeft).at(0)){
424 recMax->at(sonLeft).at(0) = initMinMaxXY->at(elem).at(2);
426 if (initMinMaxXY->at(elem).at(3) > recMax->at(sonLeft).at(1)){
427 recMax->at(sonLeft).at(1) = initMinMaxXY->at(elem).at(3);
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);
436 if (initMinMaxXY->at(elem).at(1) < recMin->at(sonRight).at(1)){
437 recMin->at(sonRight).at(1) = initMinMaxXY->at(elem).at(1);
439 if (initMinMaxXY->at(elem).at(2) > recMax->at(sonRight).at(0)){
440 recMax->at(sonRight).at(0) = initMinMaxXY->at(elem).at(2);
442 if (initMinMaxXY->at(elem).at(3) > recMax->at(sonRight).at(1)){
443 recMax->at(sonRight).at(1) = initMinMaxXY->at(elem).at(3);
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';
454 if (countCurrentElements <= numberObjects){
458 std::cout <<
" Checking for Volume Constraint (ie objects constraint satisfied)" <<
'\n';
461 (recMax->at(parentNode).at(0) - recMin->at(parentNode).at(0))\
462 * (recMax->at(parentNode).at(1) - recMin->at(parentNode).at(1));
464 (recMax->at(sonLeft).at(0) - recMin->at(sonLeft).at(0))\
465 * (recMax->at(sonLeft).at(1) - recMin->at(sonLeft).at(1));
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){
471 parentChild->at(sonLeft).at(0) = parentNode;
472 parentChild->at(sonRight).at(0) = parentNode;
473 parentChild->at(parentNode).at(1) = sonLeft;
475 stack[nodesOnStack + 1] = sonLeft;
476 stack[nodesOnStack + 2] = sonRight;
477 nodesOnStack = nodesOnStack + 2;
478 numberNodes = numberNodes + 2;
483 containedElements[parentNode].splice(
484 containedElements[parentNode].begin(),
485 containedElements[sonLeft]
487 containedElements[parentNode].splice(
488 containedElements[parentNode].begin(),
489 containedElements[sonRight]
496 std::cout <<
" Objects constraint not satisfied, Setting indices" <<
'\n';
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;
508 std::cout <<
" nodesOnStack = " << nodesOnStack <<
'\n';
512 std::cout <<
" " <<
'\n';
517 std::cout <<
"##### End Main Loop #####" <<
'\n';
520 std::cout <<
" Number of nodes in Tree = " << numberNodes <<
'\n';
523 recMin->resize(numberNodes);
524 recMax->resize(numberNodes);
525 parentChild->resize(numberNodes);
526 containedElements.resize(numberNodes);
530 this->numNodes_ = numberNodes;
531 this->minXY_ = recMin;
532 this->maxXY_ = recMax;
533 this->parentChild_ = parentChild;
534 this->containedElements_ = containedElements;
535 this->empty_ =
false;
538 std::cout <<
"##### End AABBTree::'createTreeFromRectangles' #####" <<
'\n';
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,
564 std::cout <<
" Starting AABBTree::'scanTree'" <<
'\n';
567 if (queryPoints->at(0).size() != this->dim_){
568 std::cerr <<
"Query point dimension =" << queryPoints->at(0).size() <<
", but expected dim = " << this->dim_ <<
'\n';
570 int numberQueryPoints = queryPoints->size();
573 std::map<int, std::list<int>> treeToItem;
574 std::map<int, std::list<int>> itemToTree;
587 std::vector<std::list<int> > pointsInNode(
592 int leftSon, rightSon;
593 int nodesOnStack = 0;
594 int parentNode, no=0;
596 for (
int point = 0; point<queryPoints->size(); point++){
597 pointsInNode[0].push_back(point);
599 while (nodesOnStack != -1){
601 parentNode = stack[nodesOnStack];
602 nodesOnStack = nodesOnStack - 1;
605 std::cout <<
" main loop for node = " << parentNode <<
'\n';
608 if (!this->containedElements_[parentNode].empty()){
610 treeToItem[parentNode] = pointsInNode[parentNode];
613 std::cout <<
" Node " << parentNode <<
" is not empty, pushing onto tree-item mapping" <<
'\n';
617 if(this->parentChild_->at(parentNode).at(1) != 0){
619 leftSon = parentChild_->at(parentNode).at(1);
620 rightSon = parentChild_->at(parentNode).at(1) + 1;
622 std::cout <<
"leftSon = "<< leftSon <<
", rightSon = " << rightSon <<
'\n';
625 for (
auto point : pointsInNode[parentNode]){
626 if(isInRectangle(leftSon, queryPoints->at(point),
false)){
628 pointsInNode[leftSon].push_back(point);
630 if(isInRectangle(rightSon, queryPoints->at(point),
false)){
632 pointsInNode[rightSon].push_back(point);
635 if (!pointsInNode[leftSon].empty()){
637 nodesOnStack = nodesOnStack + 1;
638 stack[nodesOnStack] = leftSon;
642 if (!pointsInNode[leftSon].empty()){
644 nodesOnStack = nodesOnStack + 1;
645 stack[nodesOnStack] = rightSon;
656 for (
auto keyValue: treeToItem){
658 for (
auto value: keyValue.second){
660 itemToTree[value].push_back(keyValue.first);
665 std::cout <<
" End AABBTree::'scanTree'" <<
'\n';
668 return std::make_tuple(treeToItem, itemToTree);
674 template <
class SC,
class LO,
class GO,
class NO> \
676 AABBTree<SC, LO, GO, NO>::isInRectangle(
678 vec_dbl_Type queryPoint,
684 std::cout <<
" Start AABBTree::'isInRectangle'" <<
'\n';
687 vec_dbl_Type rectangleMin, rectangleMax;
688 rectangleMin = this->minXY_->at(numberRectangle);
689 rectangleMax = this->maxXY_->at(numberRectangle);
691 for (
int dim = 0; dim < this->dim_-1; dim ++){
693 && queryPoint[dim] > rectangleMin[dim] \
694 && queryPoint[dim] < rectangleMax[dim]){
702 std::cout <<
" End AABBTree::'isInRectangle'" <<
'\n';
708 template <
class SC,
class LO,
class GO,
class NO> \
709 bool AABBTree<SC, LO, GO, NO>::isEmpty(){
713 template <
class SC,
class LO,
class GO,
class NO> \
714 int AABBTree<SC, LO, GO, NO>::getDim(){
718 template <
class SC,
class LO,
class GO,
class NO> \
719 int AABBTree<SC, LO, GO, NO>::getNumNodes(){
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];
Adaptive Mesh Refinement.
Definition AdaptiveMeshRefinement.cpp:5