38namespace energybased {
90 void setPoint(
int i,
int d,
double coord);
165 : m_numPoints(numPoints)
166 , m_wspdSeparationFactor(1.0)
167 , m_wspdSeparationFactorPlus2Squared_cached(9.0) {
172 for (
int i = 0; i < Dim; i++) {
186 m_pTree =
new Tree(m_numPoints);
187 m_nodeData =
new NodeData[m_pTree->maxNumNodes()];
188 m_pointData =
new PointData[m_numPoints];
195 delete[] m_pointData;
204 updateTreeGridPoints();
210 updateTreeNodeGeometry();
218 const double s = (m_wspdSeparationFactor + 2.0);
221 m_wspdSeparationFactorPlus2Squared_cached = s * s;
224 wspdRecursive(m_pTree->rootIndex());
231 for (
int i = 0; i < m_pTree->numChilds(curr); i++) {
233 const int first_child = m_pTree->child(curr, i);
236 for (
int j = i + 1; j < m_pTree->numChilds(curr); j++) {
238 const int second_child = m_pTree->child(curr, j);
241 wspdRecursive(first_child, second_child);
245 wspdRecursive(first_child);
251 if (areWellSeparated(a, b)) {
254 m_pIWSPD->onWellSeparatedPair(a, b);
262 if (
node(small_node).radius_sq >
node(large_node).radius_sq) {
263 std::swap(small_node, large_node);
267 for (
int i = 0; i <
tree().numChilds(large_node); ++i) {
269 wspdRecursive(small_node,
tree().child(large_node, i));
277 double r_max_sq = std::max(
node(a).radius_sq,
node(b).radius_sq);
280 double dist_sq = 0.0;
283 for (
int d = 0; d < Dim; d++) {
284 double dx =
node(a).x[d] -
node(b).x[d];
296 const double s = (m_wspdSeparationFactor + 2.0);
297 return dist_sq > (m_wspdSeparationFactor * m_wspdSeparationFactor + 4.0 * m_wspdSeparationFactor + 4) * r_max * r_max;
299 return dist_sq > s * s * r_max_sq;
302 return dist_sq > m_wspdSeparationFactorPlus2Squared_cached * r_max_sq;
309 double r_max_sq = std::max(
node(a).radius_sq,
node(b).radius_sq);
312 double dx_0 =
node(a).x[0] -
node(b).x[0];
313 double dx_1 =
node(a).x[1] -
node(b).x[1];
314 double dist_sq = dx_0 * dx_0 + dx_1 * dx_1;
317 return dist_sq > m_wspdSeparationFactorPlus2Squared_cached * r_max_sq;
323 double r_max_sq = std::max(
node(a).radius_sq,
node(b).radius_sq);
326 double dx_0 =
node(a).x[0] -
node(b).x[0];
327 double dx_1 =
node(a).x[1] -
node(b).x[1];
328 double dx_2 =
node(a).x[2] -
node(b).x[2];
329 double dist_sq = dx_0 * dx_0 + dx_1 * dx_1 + dx_2 * dx_2;
332 return dist_sq > m_wspdSeparationFactorPlus2Squared_cached * r_max_sq;
338 m_pointData[i].x[d] = coord;
348 for (
int d = 0; d < Dim; d++) {
349 m_bboxMin[d] = m_bboxMax[d] = point(0).x[d];
353 for (
int i = 1; i < m_numPoints; i++) {
354 for (
int d = 0; d < Dim; d++) {
355 m_bboxMin[d] = std::min(m_bboxMin[d], point(i).x[d]);
356 m_bboxMax[d] = std::max(m_bboxMax[d], point(i).x[d]);
364 for (
int d = 0; d < Dim; d++) {
365 double noise_max = (m_bboxMax[d] - m_bboxMin[d]) * 0.25;
370 double quad_size = m_bboxMax[0] - m_bboxMin[0];
371 for (
int d = 1; d < Dim; d++) {
372 quad_size = std::max(quad_size, m_bboxMax[d] - m_bboxMin[d]);
375 const double factor = (double)(0xffffffff);
377 double scale = factor / quad_size;
379 for (
int i = 0; i < m_numPoints; i++) {
380 for (
int d = 0; d < Dim; d++) {
383 double nx = ((point(i).x[d] - m_bboxMin[d] + 0.01) / quad_size + 0.02);
385 double nx = ((point(i).x[d] - m_bboxMin[d]) * scale);
388 unsigned int ix =
static_cast<unsigned int>(nx);
391 m_pTree->setPoint(i, d, ix);
398 updateTreeNodeGeometry(m_pTree->rootIndex());
405 if (m_pTree->numChilds(curr)) {
409 for (
int i = 0; i < m_pTree->numChilds(curr); i++) {
411 const int child = m_pTree->child(curr, i);
414 updateTreeNodeGeometry(child);
418 for (
int d = 0; d < Dim; d++) {
419 node(curr).min_x[d] =
node(child).min_x[d];
420 node(curr).max_x[d] =
node(child).max_x[d];
423 for (
int d = 0; d < Dim; d++) {
424 node(curr).min_x[d] = std::min(
node(curr).min_x[d],
node(child).min_x[d]);
425 node(curr).max_x[d] = std::max(
node(curr).max_x[d],
node(child).max_x[d]);
431 for (
int d = 0; d < Dim; d++) {
432 node(curr).min_x[d] =
node(curr).max_x[d] = point(
tree().point(curr, 0)).x[d];
436 for (
int i = 1; i <
tree().numPoints(curr); ++i) {
437 for (
int d = 0; d < Dim; d++) {
438 node(curr).min_x[d] =
439 std::min(
node(curr).min_x[d], point(
tree().point(curr, i)).x[d]);
440 node(curr).max_x[d] =
441 std::max(
node(curr).max_x[d], point(
tree().point(curr, i)).x[d]);
447 node(curr).radius_sq = 0.0;
450 for (
int d = 0; d < Dim; d++) {
451 node(curr).x[d] = (
node(curr).min_x[d] +
node(curr).max_x[d]) * 0.5;
452 double s_x = (
node(curr).max_x[d] -
node(curr).min_x[d]);
453 node(curr).radius_sq += s_x * s_x;
457 node(curr).radius_sq *= 0.25;
Basic declarations, included by all source files.
Implentation of the reduced quadtree for Dim dimensions.
Tree * m_pTree
the quadtree this wspd is working on
const NodeData & node(int i) const
returns the data for a quadtree
const Tree & tree() const
returns the corresponding Dtree
const PointData & point(int i) const
return ith point
double m_bboxMax[Dim]
the bounding box max coord of the point set
double m_bboxMin[Dim]
the bounding box min coord of the point set
NodeData * m_nodeData
geometry for the quadtree nodes
void computeWSPD(IWSPD *m_pIWSPD)
void allocate()
allocate mem
PointData * m_pointData
point data
void updateTreeNodeGeometry()
updates the geometry of the quadtree nodes
void updateBoundingBox()
updates the bounding box by iterating over all points
double separationFactor() const
returns the parameter s of the WSPD (default is 1.0)
void wspdRecursive(int a)
the unary recursive function generating the binary calls
double m_wspdSeparationFactorPlus2Squared_cached
a cached value for the ws test
void update()
call this when the point set has been updated.
double m_wspdSeparationFactor
the separation factor for the ws predicate
DTreeWSPD(int numPoints)
constructs a new WSPD for numPoints
void deallocate()
free mem
bool areWellSeparated(int a, int b) const
predicate for determining if cells are well-separated
int m_numPoints
number of points
void setSeparationFactor(double s)
sets the parameter s of the WSPD (default is 1.0)
void updateTreeGridPoints()
updates the integer grid points in the quadtree
void setPoint(int i, int d, double coord)
sets the point to the given coords
NodeData & node(int i)
returns the data for a quadtree
virtual void onWellSeparatedPair(int aIndex, int bIndex)=0
called by the WSPD for a pair that is well separated
NodeElement * node
The type of nodes.
double randomDouble(double low, double high)
Returns a random double value from the interval [low, high).
The namespace for all OGDF objects.
@ tree
for every hyperedge e a minimal subcubic tree connecting all hypernodes incident with e together is a...
geometry for the quadtree nodes
double min_x[Dim]
bounding box min coord
double max_x[Dim]
bounding box min coord
double x[Dim]
center of cell circle
double radius_sq
radius of the cell
world coordinates of the points
double x[Dim]
coords of the point