Program Listing for File AABBtree.hxx¶
↰ Return to documentation for file (src/acme/AABBtree.hxx
)
/*
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
* *
* The ACME project *
* *
* Copyright (c) 2020, Davide Stocco and Enrico Bertolazzi. *
* *
* The ACME project and its components are supplied under the terms of *
* the open source BSD 2-Clause License. The contents of the ACME *
* project and its components may not be copied or disclosed except in *
* accordance with the terms of the BSD 2-Clause License. *
* *
* URL: https://opensource.org/licenses/BSD-2-Clause *
* *
* Davide Stocco *
* Department of Industrial Engineering *
* University of Trento *
* e-mail: davide.stocco@unitn.it *
* *
* Enrico Bertolazzi *
* Department of Industrial Engineering *
* University of Trento *
* e-mail: enrico.bertolazzi@unitn.it *
* *
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
*/
#pragma once
#ifndef INCLUDE_ACME_AABBTREE_HXX
#define INCLUDE_ACME_AABBTREE_HXX
#include "aabb.hxx"
#include "math.hxx"
namespace acme
{
/*\
| _ _ ____ ____ _
| / \ / \ | __ )| __ )| |_ _ __ ___ ___
| / _ \ / _ \ | _ \| _ \| __| '__/ _ \/ _ \
| / ___ \ / ___ \| |_) | |_) | |_| | | __/ __/
| /_/ \_\/_/ \_\____/|____/ \__|_| \___|\___|
|
\*/
class AABBtree
{
public:
typedef std::shared_ptr<AABBtree> ptr;
typedef std::vector<ptr> vecptr;
private:
aabb::ptr m_ptrbox;
AABBtree::vecptr m_children;
AABBtree(AABBtree const & tree);
public:
~AABBtree(void);
AABBtree(void);
void
clear(void);
bool
isEmpty(void)
const;
void
build(
aabb::vecptr const & boxes
);
void
print(
out_stream & stream,
integer level = integer(0)
) const;
template <typename collisionFunction>
bool
collision(
AABBtree const & tree,
collisionFunction function,
bool swap_tree = false
)
const
{
// check aabb with
if (!tree.m_ptrbox->intersects(*this->m_ptrbox))
{return false;}
int icase = (this->m_children.empty() ? 0 : 1) +
(tree.m_children.empty() ? 0 : 2);
switch (icase)
{
case 0: // both leaf, use aabb intersection algorithm
if (swap_tree)
{return function(tree.m_ptrbox, this->m_ptrbox);}
else
{return function(this->m_ptrbox, tree.m_ptrbox);}
case 1: // first is a tree, second is a leaf
{
typename AABBtree::vecptr::const_iterator it;
for (it = this->m_children.begin(); it != this->m_children.end(); ++it)
{
if (tree.collision(**it, function, !swap_tree))
{return true;}
}
}
break;
case 2: // first leaf, second is a tree
{
typename AABBtree::vecptr::const_iterator it;
for (it = tree.m_children.begin(); it != tree.m_children.end(); ++it)
{
if (this->collision(**it, function, swap_tree))
{return true;}
}
}
break;
case 3: // first is a tree, second is a tree
{
typename AABBtree::vecptr::const_iterator it1;
typename AABBtree::vecptr::const_iterator it2;
for (it1 = this->m_children.begin(); it1 != this->m_children.end(); ++it1)
{
for (it2 = tree.m_children.begin(); it2 != tree.m_children.end(); ++it2)
{
if ((*it1)->collision(**it2, function, swap_tree))
{return true;}
}
}
}
break;
}
return false;
}
void
intersection(
AABBtree const & tree,
aabb::vecpairptr & intersectionList,
bool swap_tree = false
) const;
private:
void
selectMinimumDistance(
point const & query,
aabb::vecptr & candidateList
) const;
static real
minimumExteriorDistance(
point const & query,
AABBtree const & tree,
real distance
);
static void
selectLessThanDistance(
point const & query,
real distance,
AABBtree const & tree,
aabb::vecptr & candidateList
);
}; // class AABBtree
} // namespace acme
#endif