Skip to content
Snippets Groups Projects
Commit 0c2605c2 authored by Tom Fischer's avatar Tom Fischer
Browse files

[GL] Impl. of AABB::enlarge(), restructured updates.

parent eaf820ec
No related branches found
No related tags found
No related merge requests found
......@@ -15,11 +15,14 @@
#ifndef AABB_H_
#define AABB_H_
#include <limits>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstddef>
#include <cstdlib>
#include <iterator>
#include <cassert>
#include <limits>
#include <tuple>
#include <vector>
#include <logog/include/logog.hpp>
......@@ -49,8 +52,9 @@ public:
assert(! ids.empty());
init(pnts[ids[0]]);
for (std::size_t i=1; i<ids.size(); ++i) {
update(*(pnts[ids[i]]));
updateWithoutEnlarge(*(pnts[ids[i]]));
}
enlarge();
}
/**
......@@ -81,25 +85,41 @@ public:
init(*first);
InputIterator it(first);
while (it != last) {
update(*it);
updateWithoutEnlarge(*it);
it++;
}
enlarge();
}
bool update(PNT_TYPE const & pnt)
/// Checks if the bounding box has to be updated.
/// @return true if AABB is updated.
bool update(PNT_TYPE const & p)
{
bool updated(false);
// First component of the pair signals if the minimum point is changed
// Second component signals not only if the max point is changed.
// Furthermore it is signaled what coordinate (0,1,2) is changed.
std::pair<bool,std::bitset<3>> updated(0,0);
for (std::size_t k(0); k<3; k++) {
if (pnt[k] < _min_pnt[k]) {
_min_pnt[k] = pnt[k];
updated = true;
// if the minimum point is updated pair.first==true
if (p[k] < _min_pnt[k]) {
_min_pnt[k] = p[k];
updated.first = true;
}
if (_max_pnt[k] < pnt[k]) {
_max_pnt[k] = pnt[k];
updated = true;
// if the kth coordinate of the maximum point is updated
// pair.second[k]==true
if (p[k] >= _max_pnt[k]) {
_max_pnt[k] = p[k];
updated.second[k] = true;
}
}
return updated;
if (updated.second.any()) {
enlarge(updated.second);
return true;
} else if (updated.first) {
return true;
}
return false;
}
/**
......@@ -150,6 +170,19 @@ protected:
std::numeric_limits<double>::lowest(),
std::numeric_limits<double>::lowest()}}};
private:
/// Enlarge the bounding box the smallest possible amount (modifying the
/// unit in the last place). Only the coordinates of the maximum point are
/// changed such that the half-open property will be preserved.
void enlarge(std::bitset<3> to_update = 7)
{
for (std::size_t k=0; k<3; ++k) {
if (to_update[k]) {
_max_pnt[k] = std::nextafter(_max_pnt[k],
std::numeric_limits<double>::max());
}
}
}
void init(PNT_TYPE const & pnt)
{
_min_pnt[0] = _max_pnt[0] = pnt[0];
......@@ -160,9 +193,32 @@ private:
{
init(*pnt);
}
/// Private method that is used internally to update the min and max point
/// of the bounding box using point \f$p\f$ without enlarging the bounding
/// box. Using this method the bounding box of the initial point set is
/// enlarged only once.
/// @param p point that will possibly change the bounding box points
void updateWithoutEnlarge(PNT_TYPE const & p)
{
for (std::size_t k(0); k<3; k++) {
if (p[k] < _min_pnt[k]) {
_min_pnt[k] = p[k];
}
if (p[k] >= _max_pnt[k]) {
_max_pnt[k] = p[k];
}
}
}
void updateWithoutEnlarge(PNT_TYPE const * pnt)
{
updateWithoutEnlarge(*pnt);
}
void update(PNT_TYPE const * pnt)
{
update (*pnt);
update(*pnt);
}
};
} // end namespace
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment