Skip to content

Commit

Permalink
aabb.cc updated
Browse files Browse the repository at this point in the history
  • Loading branch information
selimanac committed Sep 13, 2018
1 parent 382e061 commit 24422d5
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 61 deletions.
133 changes: 78 additions & 55 deletions daabbcc/src/AABB.cc
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@

#include "AABB.h"

const unsigned int MAX_DIMENSIONS = 3;

namespace aabb
{
AABB::AABB()
Expand All @@ -36,7 +34,7 @@ namespace aabb

AABB::AABB(unsigned int dimension)
{
assert((dimension == 2) || (dimension == 3));
assert(dimension >= 2);

lowerBound.resize(dimension);
upperBound.resize(dimension);
Expand All @@ -49,7 +47,8 @@ namespace aabb
if (lowerBound.size() != upperBound.size())
{
//throw std::invalid_argument("[ERROR]: Dimensionality mismatch!");
assert("[ERROR]: Dimensionality mismatch!");
assert("[ERROR]: Dimensionality mismatch!");

}

// Validate that the upper bounds exceed the lower bounds.
Expand All @@ -59,7 +58,6 @@ namespace aabb
if (lowerBound[i] >= upperBound[i])
{
//throw std::invalid_argument("[ERROR]: AABB lower bound is greater than the upper bound!");

assert("[ERROR]: AABB lower bound is greater than the upper bound!");
}
}
Expand All @@ -70,22 +68,27 @@ namespace aabb

double AABB::computeSurfaceArea() const
{
// Calculate the perimeter of the 2D AABB.
if (lowerBound.size() == 2)
{
double wx = upperBound[0] - lowerBound[0];
double wy = upperBound[1] - lowerBound[1];
return 2.0 * (wx + wy);
}
// Sum of volumes of all the sides.
double sum = 0;

// Calculate the surface area of the 3D AABB.
else
// General formula for one side: hold one dimension constant
// and multiply by all the other ones.
for (unsigned int d1 = 0; d1 < lowerBound.size(); d1++)
{
double wx = upperBound[0] - lowerBound[0];
double wy = upperBound[1] - lowerBound[1];
double wz = upperBound[2] - lowerBound[2];
return 2.0 * (wx*wy + wx*wz + wy*wz);
// Volume of current side.
double product = 1;

for (unsigned int d2 = 0; d2 < lowerBound.size(); d2++)
{
if (d1 == d2)
continue;

double dx = upperBound[d2] - lowerBound[d2];
product *= dx;
}
}

return 2.0 * sum;
}

double AABB::getSurfaceArea() const
Expand Down Expand Up @@ -124,28 +127,36 @@ namespace aabb
return true;
}

bool AABB::overlaps(const AABB& aabb) const
bool AABB::overlaps(const AABB& aabb, bool touchIsOverlap) const
{
assert(aabb.lowerBound.size() == lowerBound.size());

if (lowerBound.size() == 2)
bool rv = true;

if (touchIsOverlap)
{
return !( aabb.upperBound[0] < lowerBound[0]
|| aabb.lowerBound[0] > upperBound[0]
|| aabb.upperBound[1] < lowerBound[1]
|| aabb.lowerBound[1] > upperBound[1]
);
for (unsigned int i = 0; i < lowerBound.size(); ++i)
{
if (aabb.upperBound[i] < lowerBound[i] || aabb.lowerBound[i] > upperBound[i])
{
rv = false;
break;
}
}
}
else
{
return !( aabb.upperBound[0] < lowerBound[0]
|| aabb.lowerBound[0] > upperBound[0]
|| aabb.upperBound[1] < lowerBound[1]
|| aabb.lowerBound[1] > upperBound[1]
|| aabb.upperBound[2] < lowerBound[2]
|| aabb.lowerBound[2] > upperBound[2]
);
for (unsigned int i = 0; i < lowerBound.size(); ++i)
{
if (aabb.upperBound[i] <= lowerBound[i] || aabb.lowerBound[i] >= upperBound[i])
{
rv = false;
break;
}
}
}

return rv;
}

std::vector<double> AABB::computeCentre()
Expand All @@ -160,7 +171,7 @@ namespace aabb

void AABB::setDimension(unsigned int dimension)
{
assert((dimension == 2) || (dimension == 3));
assert(dimension >= 2);

lowerBound.resize(dimension);
upperBound.resize(dimension);
Expand All @@ -177,11 +188,13 @@ namespace aabb

Tree::Tree(unsigned int dimension_,
double skinThickness_,
unsigned int nParticles) :
dimension(dimension_), isPeriodic(false), skinThickness(skinThickness_)
unsigned int nParticles,
bool touchIsOverlap_) :
dimension(dimension_), isPeriodic(false), skinThickness(skinThickness_),
touchIsOverlap(touchIsOverlap_)
{
// Validate the dimensionality.
if ((dimension != 2) && (dimension != 3))
if ((dimension < 2))
{
//throw std::invalid_argument("[ERROR]: Invalid dimensionality!");
assert("[ERROR]: Invalid dimensionality!");
Expand Down Expand Up @@ -214,25 +227,29 @@ namespace aabb
double skinThickness_,
const std::vector<bool>& periodicity_,
const std::vector<double>& boxSize_,
unsigned int nParticles) :
dimension(dimension_), skinThickness(skinThickness_), periodicity(periodicity_), boxSize(boxSize_)
unsigned int nParticles,
bool touchIsOverlap_) :
dimension(dimension_), skinThickness(skinThickness_),
periodicity(periodicity_), boxSize(boxSize_),
touchIsOverlap(touchIsOverlap_)
{
// Validate the dimensionality.
if ((dimension != 2) && (dimension != 3))
if (dimension < 2)
{
//throw std::invalid_argument("[ERROR]: Invalid dimensionality!");
assert("[ERROR]: Invalid dimensionality!");
assert("[ERROR]: Invalid dimensionality!");
}

// Validate the dimensionality of the vectors.
if ((periodicity.size() != dimension) || (boxSize.size() != dimension))
{
//throw std::invalid_argument("[ERROR]: Dimensionality mismatch!");
assert("[ERROR]: Dimensionality mismatch!");
assert("[ERROR]: Dimensionality mismatch!");
}

// Initialise the tree.
root = NULL_NODE;
touchIsOverlap = true;
nodeCount = 0;
nodeCapacity = nParticles;
nodes.resize(nodeCapacity);
Expand Down Expand Up @@ -327,7 +344,7 @@ namespace aabb
if (particleMap.count(particle) != 0)
{
//throw std::invalid_argument("[ERROR]: Particle already exists in tree!");
assert("[ERROR]: Particle already exists in tree!");
assert("[ERROR]: Particle already exists in tree!");
}

// Validate the dimensionality of the position vector.
Expand All @@ -341,7 +358,7 @@ namespace aabb
unsigned int node = allocateNode();

// AABB size in each dimension.
double size[MAX_DIMENSIONS];
double size[dimension];

// Compute the AABB limits.
for (unsigned int i=0;i<dimension;i++)
Expand Down Expand Up @@ -386,14 +403,14 @@ namespace aabb
if ((lowerBound.size() != dimension) || (upperBound.size() != dimension))
{
//throw std::invalid_argument("[ERROR]: Dimensionality mismatch!");
assert("[ERROR]: Dimensionality mismatch!");
assert("[ERROR]: Dimensionality mismatch!");
}

// Allocate a new node for the particle.
unsigned int node = allocateNode();

// AABB size in each dimension.
double size[MAX_DIMENSIONS];
double size[dimension];

// Compute the AABB limits.
for (unsigned int i=0;i<dimension;i++)
Expand Down Expand Up @@ -449,7 +466,8 @@ namespace aabb
if (it == particleMap.end())
{
//throw std::invalid_argument("[ERROR]: Invalid particle index!");
assert("[ERROR]: Invalid particle index!");

assert("[ERROR]: Invalid particle index!");
}

// Extract the node index.
Expand Down Expand Up @@ -489,13 +507,14 @@ namespace aabb
particleMap.clear();
}

bool Tree::updateParticle(unsigned int particle, std::vector<double>& position, double radius)
bool Tree::updateParticle(unsigned int particle, std::vector<double>& position, double radius,
bool alwaysReinsert)
{
// Validate the dimensionality of the position vector.
if (position.size() != dimension)
{
//throw std::invalid_argument("[ERROR]: Dimensionality mismatch!");
assert("[ERROR]: Dimensionality mismatch!");
assert("[ERROR]: Dimensionality mismatch!");
}

// AABB bounds vectors.
Expand All @@ -510,16 +529,17 @@ namespace aabb
}

// Update the particle.
return updateParticle(particle, lowerBound, upperBound);
return updateParticle(particle, lowerBound, upperBound, alwaysReinsert);
}

bool Tree::updateParticle(unsigned int particle, std::vector<double>& lowerBound, std::vector<double>& upperBound)
bool Tree::updateParticle(unsigned int particle, std::vector<double>& lowerBound,
std::vector<double>& upperBound, bool alwaysReinsert)
{
// Validate the dimensionality of the bounds vectors.
if ((lowerBound.size() != dimension) && (upperBound.size() != dimension))
{
//throw std::invalid_argument("[ERROR]: Dimensionality mismatch!");
assert("[ERROR]: Dimensionality mismatch!");
assert("[ERROR]: Dimensionality mismatch!");
}

// Map iterator.
Expand All @@ -532,7 +552,7 @@ namespace aabb
if (it == particleMap.end())
{
//throw std::invalid_argument("[ERROR]: Invalid particle index!");
assert("[ERROR]: Invalid particle index!");
assert("[ERROR]: Invalid particle index!");
}

// Extract the node index.
Expand All @@ -542,7 +562,7 @@ namespace aabb
assert(nodes[node].isLeaf());

// AABB size in each dimension.
double size[MAX_DIMENSIONS];
double size[dimension];

// Compute the AABB limits.
for (unsigned int i=0;i<dimension;i++)
Expand All @@ -560,8 +580,9 @@ namespace aabb
// Create the new AABB.
AABB aabb(lowerBound, upperBound);


// No need to update if the particle is still within its fattened AABB.
if (nodes[node].aabb.contains(aabb)) return false;
if (!alwaysReinsert && nodes[node].aabb.contains(aabb)) return false;

// Remove the current leaf.
removeLeaf(node);
Expand Down Expand Up @@ -638,14 +659,16 @@ namespace aabb
}

// Test for overlap between the AABBs.
if (aabb.overlaps(nodeAABB))
if (aabb.overlaps(nodeAABB, touchIsOverlap))
{
// Check that we're at a leaf node.
if (nodes[node].isLeaf())
{
// Can't interact with itself.
if (nodes[node].particle != particle)
{
particles.push_back(nodes[node].particle);
}
}
else
{
Expand Down
29 changes: 24 additions & 5 deletions daabbcc/src/AABB.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,10 +99,13 @@ namespace aabb
/*! \param aabb
A reference to the AABB.
\param touchIsOverlap
Does touching constitute an overlap?
\return
Whether the AABB overlaps.
*/
bool overlaps(const AABB&) const;
bool overlaps(const AABB&, bool touchIsOverlap) const;

//! Compute the centre of the AABB.
/*! \returns
Expand Down Expand Up @@ -195,8 +198,12 @@ namespace aabb
\param nParticles
The number of particles (for fixed particle number systems).
\param touchIsOverlap
Does touching count as overlapping in query operations?
*/
Tree(unsigned int dimension_= 3, double skinThickness_ = 0.05, unsigned int nParticles = 16);
Tree(unsigned int dimension_= 3, double skinThickness_ = 0.05,
unsigned int nParticles = 16, bool touchIsOverlap=true);

//! Constructor (custom periodicity).
/*! \param dimension_
Expand All @@ -214,8 +221,12 @@ namespace aabb
\param nParticles
The number of particles (for fixed particle number systems).
\param touchIsOverlap
Does touching count as overlapping in query operations?
*/
Tree(unsigned int, double, const std::vector<bool>&, const std::vector<double>&, unsigned int nParticles = 16);
Tree(unsigned int, double, const std::vector<bool>&, const std::vector<double>&,
unsigned int nParticles = 16, bool touchIsOverlap=true);

//! Set the periodicity of the simulation box.
/*! \param periodicity_
Expand Down Expand Up @@ -275,10 +286,13 @@ namespace aabb
\param radius
The radius of the particle.
\param alwaysReinsert
Always reinsert the particle, even if it's within its old AABB (default:false)
\return
Whether the particle was reinserted.
*/
bool updateParticle(unsigned int, std::vector<double>&, double);
bool updateParticle(unsigned int, std::vector<double>&, double, bool alwaysReinsert=false);

//! Update the tree if a particle moves outside its fattened AABB.
/*! \param particle
Expand All @@ -290,8 +304,10 @@ namespace aabb
\param upperBound
The upper bound in each dimension.
\param alwaysReinsert
Always reinsert the particle, even if it's within its old AABB (default: false)
*/
bool updateParticle(unsigned int, std::vector<double>&, std::vector<double>&);
bool updateParticle(unsigned int, std::vector<double>&, std::vector<double>&, bool alwaysReinsert=false);

//! Query the tree to find candidate interactions for a particle.
/*! \param particle
Expand Down Expand Up @@ -401,6 +417,9 @@ namespace aabb
/// A map between particle and node indices.
std::map<unsigned int, unsigned int> particleMap;

/// Does touching count as overlapping in tree queries?
bool touchIsOverlap;

//! Allocate a new node.
/*! \return
The index of the allocated node.
Expand Down
Loading

0 comments on commit 24422d5

Please sign in to comment.