Commit 883eac38 authored by Andreas Schwarzkopf's avatar Andreas Schwarzkopf

[FIX #371] Repaired the multithreading setting

 * General style Some style improvements.
 *
 * General features:
 *   - Points - Transform: Color equalizer (contrast and offset setting for each color
 *     channel)
 *
 * Performance improvements (in general about 4 times faster)
 *   - Lari/Habib 2014 clustering has now following improvements.
 *       - Removing points from the parameter space kd-tree after adding to a plane -
 *         This change created an additional, temporary parameter domain kd-tree which
 *         is in the beginning just a copy of the original parameter domain kd-tree.
 *         When points are added to a plane, they are removed from that copy. It makes
 *         the algorithm a way faster.
 *       - Distinguishing whether a point belongs to an extent directly in an point
 *         searcher instance works faster than building a list with additional
 *         unnecessary points and filtering afterwards. In that change a new class
 *         inherited from WPointSearcher and overwrote a method which distinguishes
 *         whether points are added or not.
 *       - Another story is counting points of an extent with a searched point as peak
 *         centre. Previously points were put in a list in order to count them
 *         afterwards. This new class was further modified at traversing. So no new
 *         unnecessary list is built up.
 *
 * Bugs fixed:
 *   - Boundary detection problems were fixed. Originally there was a detection that
 *     checked whether a new bound would hit the pre previously detectet bound. But that
 *     seemet practically not to be enough. So every point adding a new bound is checked
 *     whether it hits one of all bound pieces detected. Nevertheless the problem is not
 *     solved completely but there are much less less problems by far.
parent 5337e00e
......@@ -31,7 +31,7 @@
#include <core/kernel/WModule.h>
#include "buildingsDetection/WMBuildingsDetection.h"
#include "buildingsDetectionByPCA/WMBuildingsDetectionByPCA.h"
#include "treeDetectionByPCA/WMTreeDetectionByPCA.h"
#include "elevationImageExport/WMElevationImageExport.h"
#include "pointsTransform/WMPointsTransform.h"
#include "pointsCutOutliers/WMPointsCutOutliers.h"
......@@ -60,7 +60,7 @@
extern "C" void WLoadModule( WModuleList& m ) // NOLINT
{
m.push_back( boost::shared_ptr< WModule >( new WMBuildingsDetection ) );
m.push_back( boost::shared_ptr< WModule >( new WMBuildingsDetectionByPCA ) );
m.push_back( boost::shared_ptr< WModule >( new WMTreeDetectionByPCA ) );
m.push_back( boost::shared_ptr< WModule >( new WMElevationImageExport ) );
m.push_back( boost::shared_ptr< WModule >( new WMPointsCutOutliers ) );
m.push_back( boost::shared_ptr< WModule >( new WMPointsGroupSelector ) );
......
......@@ -84,7 +84,7 @@ void WBuildingDetector::initMinimalMaxima( WQuadNode* sourceNode, WQuadTree* tar
double coordX = sourceNode->getCenter( 0 );
double coordY = sourceNode->getCenter( 1 );
double d = m_minSearchDetailDepth / 2.0;
double height = sourceNode->getElevationMax();
double height = sourceNode->getValueMax();
targetTree->registerPoint( coordX - d, coordY - d, height );
targetTree->registerPoint( coordX - d, coordY + d, height );
targetTree->registerPoint( coordX + d, coordY - d, height );
......@@ -108,11 +108,11 @@ void WBuildingDetector::projectDrawableAreas( WQuadNode* sourceNode,
WQuadNode* minimalNodeBigHeight = minimalMaxima->getLeafNode( coordX, coordY,
m_minSearchCutUntilAboveBigHeights );
if( minimalNode == 0 || minimalNodeBigHeight == 0 ) return;
double minimalHeight = m_minSearchCutUntilAbove + minimalNode->getElevationMin();
double minimalHeightBigHeights = m_minSearchCutUntilAbove + minimalNodeBigHeight->getElevationMin();
if( sourceNode->getElevationMax() < minimalHeight
&& sourceNode->getElevationMax() < minimalHeightBigHeights ) return;
targetTree->registerPoint( coordX, coordY, sourceNode->getElevationMax() );
double minimalHeight = m_minSearchCutUntilAbove + minimalNode->getValueMin();
double minimalHeightBigHeights = m_minSearchCutUntilAbove + minimalNodeBigHeight->getValueMin();
if( sourceNode->getValueMax() < minimalHeight
&& sourceNode->getValueMax() < minimalHeightBigHeights ) return;
targetTree->registerPoint( coordX, coordY, sourceNode->getValueMax() );
}
else
{
......
......@@ -107,7 +107,7 @@ void WMBuildingsDetection::properties()
"depth for the octree search tree.", 0 );
m_detailDepth->setMin( -3 );
m_detailDepth->setMax( 4 );
m_detailDepthLabel = m_properties->addProperty( "Voxel width meters: ", "Resulting detail depth "
m_detailDepthLabel = m_properties->addProperty( "Pixel width meters: ", "Resulting detail depth "
"in meters for the octree search tree.", pow( 2.0, m_detailDepth->get() ) * 2.0 );
m_detailDepthLabel->setPurpose( PV_PURPOSE_INFORMATION );
......@@ -205,8 +205,8 @@ void WMBuildingsDetection::moduleMain()
m_xMax->set( boundingBox->getRootNode()->getXMax() );
m_yMin->set( boundingBox->getRootNode()->getYMin() );
m_yMax->set( boundingBox->getRootNode()->getYMax() );
m_zMin->set( boundingBox->getRootNode()->getElevationMin() );
m_zMax->set( boundingBox->getRootNode()->getElevationMax() );
m_zMin->set( boundingBox->getRootNode()->getValueMin() );
m_zMax->set( boundingBox->getRootNode()->getValueMax() );
m_progressStatus->finish();
}
m_reloadData->set( WPVBaseTypes::PV_TRIGGER_READY, true );
......
......@@ -95,6 +95,15 @@ WKdTreeND::~WKdTreeND()
}
void WKdTreeND::add( vector<WKdPointND*>* addables )
{
/*cout << "Adding points to kd-tree:" << endl;
for( size_t index = 0; index < addables->size(); index++ )
{
for( size_t dimension = 0; dimension < 3; dimension++ )
cout << "\t" << addables->at( index )->getCoordinate()[dimension];
cout << endl;
}
cout << endl;*/
if( addables->size() == 0 )
return;
for( size_t index = 0; index < addables->size(); index++ )
......@@ -110,6 +119,10 @@ void WKdTreeND::add( vector<WKdPointND*>* addables )
double point1Scalar = m_points->at( 0 )->getCoordinate()[m_splittingDimension];
double point2Scalar = m_points->at( 1 )->getCoordinate()[m_splittingDimension];
m_splittingPosition = ( point1Scalar + point2Scalar ) / 2.0;
if( m_splittingPosition == point2Scalar && point1Scalar > point2Scalar )
m_splittingPosition = point1Scalar;
if( m_splittingPosition == point1Scalar && point2Scalar > point1Scalar )
m_splittingPosition = point2Scalar;
}
else
{
......@@ -141,29 +154,45 @@ bool WKdTreeND::canSplit()
{
return m_splittingDimension < m_dimensions;
}
void WKdTreeND::assignZeroToPointers()
{
m_lowerChild = 0;
m_higherChild = 0;
m_points->resize( 0 );
m_points->reserve( 0 );
}
void WKdTreeND::copyPointersFrom( WKdTreeND* copiedNode )
{
m_parentSplittingDimension = copiedNode->m_parentSplittingDimension;
m_lowerChild = copiedNode->m_lowerChild;
m_higherChild = copiedNode->m_higherChild;
m_dimensions = copiedNode->m_dimensions;
m_splittingDimension = copiedNode->m_splittingDimension;
m_splittingPosition = copiedNode->m_splittingPosition;
m_allowDoubles = copiedNode->m_allowDoubles;
m_points->resize( 0 );
m_points->reserve( 0 );
for( size_t index = 0; index < copiedNode->m_points->size(); index++ )
m_points->push_back( copiedNode->m_points->at( index ) );
}
void WKdTreeND::fetchPoints( vector<WKdPointND* >* targetPointSet )
{
if( m_points->size() == 0 && m_lowerChild == 0 && m_lowerChild == 0 )
if( m_points->size() > 0 && m_lowerChild == 0 && m_lowerChild == 0 )
{
for(size_t index = 0; index < m_points->size(); index++)
targetPointSet->push_back( m_points->at( index ) );
}
else
{
if( m_points->size() > 0 && m_lowerChild == 0 && m_lowerChild == 0 )
if( m_points->size() == 0 && m_lowerChild != 0 && m_lowerChild != 0 )
{
for(size_t index = 0; index < m_points->size(); index++)
targetPointSet->push_back( m_points->at( index ) );
m_lowerChild->fetchPoints( targetPointSet );
m_higherChild->fetchPoints( targetPointSet );
}
else
{
if( m_points->size() == 0 && m_lowerChild != 0 && m_lowerChild != 0 )
{
m_lowerChild->fetchPoints( targetPointSet );
m_higherChild->fetchPoints( targetPointSet );
}
else
{
if( m_points->size() != 0 || m_lowerChild != 0 || m_lowerChild != 0 )
cout << "!!!UNKNOWN EXCEPTION!!!" << endl;
}
}
}
}
......@@ -172,7 +201,7 @@ vector<WKdPointND*>* WKdTreeND::getAllPoints()
vector<WKdPointND*>* outputPoints = new vector<WKdPointND*>();
vector<WKdTreeND*>* kdNodes = getAllLeafNodes();
for( size_t nodeIndex = 0; nodeIndex < kdNodes->size(); nodeIndex++ )
for( size_t pointIndex = 0; pointIndex < kdNodes->at(nodeIndex)->getNodePoints()->size(); pointIndex++ )
for( size_t pointIndex = 0; pointIndex < kdNodes->at( nodeIndex )->getNodePoints()->size(); pointIndex++ )
outputPoints->push_back( kdNodes->at( nodeIndex )->getNodePoints()->at( pointIndex ) );
kdNodes->resize( 0 );
kdNodes->reserve( 0 );
......@@ -220,9 +249,58 @@ size_t WKdTreeND::getSplittingDimension()
{
return m_splittingDimension;
}
double WKdTreeND::getSplittingPosition()
bool WKdTreeND::isEmpty()
{
return m_points->size() == 0 && m_lowerChild == 0 && m_lowerChild == 0;
}
bool WKdTreeND::isLowerKdNodeCase( double position )
{
return position < m_splittingPosition;
}
bool WKdTreeND::removePoint( WKdPointND* removablePoint )
{
return m_splittingPosition;
if( m_points->size() > 0 && m_lowerChild == 0 && m_lowerChild == 0 )
{
size_t removeCount = 0;
size_t size = m_points->size();
for(size_t index = 0; index < size; index++)
{
if( m_points->at( index ) == removablePoint )
{
for( size_t index2 = index + 1; index2 < size - removeCount; index2++ )
m_points->at( index ) = m_points->at( index + 1 );
removeCount++;
}
}
m_points->resize( size - removeCount );
m_points->reserve( size - removeCount );
return removeCount > 0;
}
else
{
if( m_points->size() == 0 && m_lowerChild != 0 && m_lowerChild != 0 )
{
double position = removablePoint->getCoordinate()[getSplittingDimension()];
WKdTreeND* deletedNode = isLowerKdNodeCase( position ) ?m_lowerChild :m_higherChild;
WKdTreeND* copiedNode = !isLowerKdNodeCase( position ) ?m_lowerChild :m_higherChild;
bool couldFind = deletedNode->removePoint( removablePoint );
if( deletedNode->isEmpty() )
{
delete deletedNode;
copyPointersFrom( copiedNode );
copiedNode->assignZeroToPointers();
delete copiedNode;
}
return couldFind;
}
else
{
if( m_points->size() != 0 || m_lowerChild != 0 || m_lowerChild != 0 )
cout << "!!!UNKNOWN EXCEPTION!!!" << endl;
}
}
return false;
}
WKdTreeND* WKdTreeND::getNewInstance( size_t dimensions )
{
......@@ -236,7 +314,7 @@ void WKdTreeND::addPointsToChildren( vector<WKdPointND* >* newPoints )
{
WKdPointND* newPoint = newPoints->at( index );
double position = newPoint->getCoordinate().at( m_splittingDimension );
if( position < m_splittingPosition )
if( isLowerKdNodeCase( position ) )
{
lowerPoints->push_back( newPoint );
}
......@@ -322,7 +400,9 @@ void WKdTreeND::calculateSplittingPosition( vector<WKdPointND* >* inputPoints )
}
m_splittingPosition = ( line->at( medianIdx ) + line->at( medianIdx - 1 ) ) / 2.0;
m_splittingPosition = ( line->at( medianIdx - 1 ) + line->at( medianIdx ) ) / 2.0;
if( m_splittingPosition == line->at( medianIdx - 1 ) )
m_splittingPosition = line->at( medianIdx );
line->resize( 0 );
line->reserve( 0 );
delete line;
......@@ -361,10 +441,10 @@ bool WKdTreeND::determineNewSplittingDimension( vector<WKdPointND* >* inputPoint
if( m_splittingDimension >= m_dimensions && m_parentSplittingDimension < m_dimensions
&& boundingBoxMax->at( m_parentSplittingDimension ) - boundingBoxMin->at( m_parentSplittingDimension ) > 0.0 )
m_splittingDimension = m_parentSplittingDimension;
boundingBoxMin->resize( 0 );
boundingBoxMin->reserve( 0 );
boundingBoxMin->resize( 0 );
boundingBoxMin->reserve( 0 );
boundingBoxMin->resize( 0 ); //TODO(aschwarzkopf): delete instead
boundingBoxMin->reserve( 0 ); //TODO(aschwarzkopf): delete instead
boundingBoxMin->resize( 0 ); //TODO(aschwarzkopf): delete instead
boundingBoxMin->reserve( 0 ); //TODO(aschwarzkopf): delete instead
delete boundingBoxMin;
delete boundingBoxMax;
return m_splittingDimension < m_dimensions;
......
......@@ -112,10 +112,30 @@ public:
*/
size_t getSplittingDimension();
/**
* Returns the splitting position of the splitted dimension.
* \return The splitting position of the splitted dimension.
* Return whether the node has neither points nor child nodes.
* \return Node has no contents.
*/
double getSplittingPosition();
bool isEmpty();
/**
* Tells whether a position hits a lower or higher case or roughly said in the area
* before or after the splitting position. There actually was a case when an average
* of two positions had to be calculated what was unsuccessful because the numbers
* were too close that the position was either the coordinate from first or second
* point. Therefore getSplittingPosition is not public any more. Regard
* getSplittingDimension() when executing that method.
* \param position Position which has to be checked whether it is before or after
* the splitting position of the kd-node within the splitting
* dimension.
* \return Coordinate belongs either to the lower or higher coordinate child.
*/
bool isLowerKdNodeCase( double position );
/**
* Removes a point. The pointer reference must equal to the removable point. No
* points are removed if another point with the same coordinate exists.
* \param removablePoint Point to be removed from the kd-tree.
* \return Point was found and successfully removed or not.
*/
bool removePoint( WKdPointND* removablePoint );
protected:
/**
......@@ -128,6 +148,16 @@ protected:
virtual WKdTreeND* getNewInstance( size_t dimensions );
private:
/**
* Assigns zero to pointers. It makes sense for some operations when some nodes have to be deleted but
*/
void assignZeroToPointers();
/**
* Copies pointer value to a node. No actual copies are created. So every change
* would be shared. Other node parameters are copied.
* \param copiedNode Object which should be copied by pointers.
*/
void copyPointersFrom( WKdTreeND* copiedNode );
/**
* Returns all the leaf nodes of the kd tree.
* \return All the leaf nodes of the kd tree.
......@@ -177,7 +207,7 @@ private:
* The splitting dimension of the parent kd tree node. It is considered to determine
* the splitting dimension of the current kd tree node.
*/
size_t m_parentSplittingDimension; //ggf. wegschmeißen
size_t m_parentSplittingDimension; //TODO(aschwarzkopf): ggf. wegschmeißen
//TODO(aschwarzkopf): Ggf. Sinn: Nicht bis ins Letzte unterteilen, ggf. nur über einem Threshold
/**
* The kd tree node child which is on the lower position across the splitting
......@@ -198,8 +228,13 @@ private:
*/
size_t m_splittingDimension;
/**
* Children of a kd tree node are separated by a plane. The splitting dimension axis * is perpendicular to that. This position variable is the intersection between this
* Children of a kd tree node are separated by a plane. The splitting dimension axis
* is perpendicular to that. This position variable is the intersection between this
* plane and axis.
* This field should not be accessible publically. There actually was a case when an
* average of two positions had to be calculated what was unsuccessful because the
* numbers were too close that the position was either the coordinate from first or
* second point. Try to use isLowerKdNodeCase() instead.
*/
double m_splittingPosition;
/**
......
......@@ -25,6 +25,7 @@
#include <vector>
#include "WPointDistance.h"
#include "../../math/vectors/WVectorMaths.h"
WPointDistance::WPointDistance()
{
......@@ -34,7 +35,7 @@ WPointDistance::WPointDistance()
WPointDistance::WPointDistance( vector<double> sourcePoint, WKdPointND* comparedPoint )
{
m_comparedPoint = comparedPoint;
m_pointDistance = getPointDistance( sourcePoint, getComparedPoint()->getCoordinate() );
m_pointDistance = WVectorMaths::getEuclidianDistance( sourcePoint, getComparedPoint()->getCoordinate() );
}
WPointDistance::~WPointDistance()
......@@ -52,12 +53,16 @@ double WPointDistance::getDistance()
{
return m_pointDistance;
}
double WPointDistance::getPointDistance( const vector<double>& point1, const vector<double>& point2 )
{ //TODO(aschwarzkopf): Not verified that the euclidian distance is calculated right also for points above 3 dimensions.
double distance = 0;
for( size_t index = 0; index < point1.size() && index < point2.size(); index++ )
distance += pow( point1[index] - point2[index], 2 );
return pow( distance, 0.5 );
vector<WPosition>* WPointDistance::convertToPointSet( vector<WPointDistance>* pointDistances )
{
vector<WPosition>* pointSet = new vector<WPosition>();
for( size_t index = 0; index < pointDistances->size(); index++ )
{
vector<double> coordinate = pointDistances->at( index ).getComparedCoordinate();
if( coordinate.size() == 3 )
pointSet->push_back( WPosition( coordinate[0], coordinate[1], coordinate[2] ) );
}
return pointSet;
}
bool WPointDistance::operator<( WPointDistance const& right ) const
{
......
......@@ -30,6 +30,7 @@
#include <iostream>
#include <vector>
#include "WKdPointND.h"
#include "core/common/math/linearAlgebra/WPosition.h"
using std::vector;
......@@ -75,13 +76,12 @@ public:
*/
double getDistance();
/**
* Static method that calculates the euclidian distance between two arbitrary
* unidimensional points.
* \param point1 First point for calculating the distance.
* \param point2 Second point for calculating the distance.
* \return Euclidian distance between that two points.
* Static method that fetches coordinates of WPointDistance sets into a three
* dimensional WPosition point list.
* \param pointDistances Point distance data sets to fetch positions from.
* \return A WPosition list. That type is very commonly used in OpenWalnut.
*/
static double getPointDistance( const vector<double>& point1, const vector<double>& point2 );
static vector<WPosition>* convertToPointSet( vector<WPointDistance>* pointDistances );
/**
* Operator for sorting a vector<WPointDistance> using std::sort.
* \param right The right compared object to this one.
......
......@@ -26,6 +26,7 @@
#include <vector>
#include <limits>
#include "../../math/vectors/WVectorMaths.h"
#include "WPointSearcher.h"
WPointSearcher::WPointSearcher()
......@@ -34,6 +35,7 @@ WPointSearcher::WPointSearcher()
m_examinedKdTree = 0;
m_maxResultPointCount = 50;
m_maxSearchDistance = 0.5;
m_foundPoints = 0;
}
WPointSearcher::WPointSearcher( WKdTreeND* kdTree )
{
......@@ -42,48 +44,84 @@ WPointSearcher::WPointSearcher( WKdTreeND* kdTree )
m_maxResultPointCount = 50;
m_maxSearchDistance = 0.5;
m_examinedKdTree = kdTree;
m_foundPoints = 0;
}
WPointSearcher::~WPointSearcher()
{
m_searchedCoordinate.resize( 0 );
m_searchedCoordinate.reserve( 0 );
}
vector<WPosition>* WPointSearcher::convertToPointSet( vector<WPointDistance>* pointDistances )
{
vector<WPosition>* pointSet = new vector<WPosition>();
for( size_t index = 0; index < pointDistances->size(); index++ )
{
vector<double> coordinate = pointDistances->at( index ).getComparedCoordinate();
if( coordinate.size() == 3 )
pointSet->push_back( WPosition( coordinate[0], coordinate[1], coordinate[2] ) );
}
return pointSet;
}
vector<WPointDistance>* WPointSearcher::getNearestPoints()
{
vector<WPointDistance>* nearestPoints = new vector<WPointDistance>(); //TODO(aschwarzkopf): Only debugging step over crashes on that line.
m_foundPoints = new vector<WPointDistance>(); //TODO(aschwarzkopf): Only debugging step over crashes on that line.
double index = 1;
size_t distanceSteps = m_maxResultPointCount == std::numeric_limits< size_t >::max() ?1 :m_distanceSteps;
for( index = 1; index <= distanceSteps
&& nearestPoints->size() < m_maxResultPointCount; index++ )
&& m_foundPoints->size() < m_maxResultPointCount; index++ )
{
delete nearestPoints;
nearestPoints = new vector<WPointDistance>();
delete m_foundPoints;
m_foundPoints = new vector<WPointDistance>();
double maxDistance = m_maxSearchDistance * pow( 2.0, - ( double )distanceSteps + ( double )index );
fetchNearestPoints( m_examinedKdTree, nearestPoints, maxDistance );
//cout << "Attempt at max distance: " << maxDistance << " size = " << nearestPoints->size() << endl;
traverseNodePoints( m_examinedKdTree, maxDistance );
//cout << "Attempt at max distance: " << maxDistance << " size = " << m_foundPoints->size() << endl;
}
std::sort( nearestPoints->begin(), nearestPoints->end() );
//cout << "Found " << nearestPoints->size() << " Neighbors on index " << (index - 1)
// << " with maximal disstance " << nearestPoints->at(nearestPoints->size() - 1).getDistance() << endl;
if( nearestPoints->size() > m_maxResultPointCount )
std::sort( m_foundPoints->begin(), m_foundPoints->end() );
//cout << "Found " << m_foundPoints->size() << " Neighbors on index " << (index - 1)
// << " with maximal disstance " << m_foundPoints->at(m_foundPoints->size() - 1).getDistance() << endl;
if( m_foundPoints->size() > m_maxResultPointCount )
{
nearestPoints->resize( m_maxResultPointCount );
nearestPoints->reserve( m_maxResultPointCount );
m_foundPoints->resize( m_maxResultPointCount );
m_foundPoints->reserve( m_maxResultPointCount );
}
return nearestPoints;
return m_foundPoints;
}
size_t WPointSearcher::getNearestNeighborCount()
{
if( m_maxResultPointCount == std::numeric_limits< size_t >::max() )
{
return getNearestNeighborCountInfiniteMaxCount( m_examinedKdTree );
}
else
{
vector<WPointDistance>* nearestPoints = getNearestPoints();
size_t neighbourCount = nearestPoints->size();
delete nearestPoints;
return neighbourCount;
}
}
size_t WPointSearcher::getNearestNeighborCountInfiniteMaxCount( WKdTreeND* currentNode )
{
size_t pointCount = 0;
vector<WKdPointND* >* nodePoints = currentNode->getNodePoints();
WKdTreeND* lowerChild = currentNode->getLowerChild();
WKdTreeND* higherChild = currentNode->getHigherChild();
if( nodePoints->size() > 0 && lowerChild == 0 && higherChild == 0)
{
for( size_t index = 0; index < nodePoints->size(); index++ )
{
WKdPointND* point = nodePoints->at( index );
if( pointCanBelongToPointSet( point->getCoordinate(), m_maxSearchDistance ) )
pointCount++;
}
}
else
{
if( nodePoints->size() == 0 && lowerChild != 0 && higherChild != 0 )
{
double splittingDimension = currentNode->getSplittingDimension();
double pointCoord = m_searchedCoordinate.at( splittingDimension );
if( currentNode->isLowerKdNodeCase( pointCoord - m_maxSearchDistance ) )
pointCount += getNearestNeighborCountInfiniteMaxCount( currentNode->getLowerChild() );
if( !currentNode->isLowerKdNodeCase( pointCoord + m_maxSearchDistance ) )
pointCount += getNearestNeighborCountInfiniteMaxCount( currentNode->getHigherChild() );
}
else
{
cout << "!!!UNKNOWN EXCEPTION!!! - getting nearest points" << endl;
}
}
return pointCount;
}
void WPointSearcher::setExaminedKdTree( WKdTreeND* kdTree )
{
m_examinedKdTree = kdTree;
......@@ -100,7 +138,11 @@ void WPointSearcher::setMaxResultPointCount( size_t maxPointCount )
{
m_maxResultPointCount = maxPointCount;
}
void WPointSearcher::fetchNearestPoints( WKdTreeND* currentNode, vector<WPointDistance>* targetPoints, double maxDistance )
void WPointSearcher::setMaxResultPointCountInfinite()
{
m_maxResultPointCount = std::numeric_limits< size_t >::max();
}
void WPointSearcher::traverseNodePoints( WKdTreeND* currentNode, double maxDistance )
{
vector<WKdPointND* >* nodePoints = currentNode->getNodePoints();
WKdTreeND* lowerChild = currentNode->getLowerChild();
......@@ -110,21 +152,20 @@ void WPointSearcher::fetchNearestPoints( WKdTreeND* currentNode, vector<WPointDi
for( size_t index = 0; index < nodePoints->size(); index++ )
{
WKdPointND* point = nodePoints->at( index );
if( WPointDistance::getPointDistance( m_searchedCoordinate, point->getCoordinate() ) <= maxDistance )
targetPoints->push_back( WPointDistance( m_searchedCoordinate, nodePoints->at( index ) ) );
if( pointCanBelongToPointSet( point->getCoordinate(), maxDistance ) )
onPointFound( point );
}
}
else
{
if( nodePoints->size() == 0 && lowerChild != 0 && higherChild != 0 )
{
double splittingDimension = currentNode->getSplittingDimension();
double splittingPosition = currentNode->getSplittingPosition();
size_t splittingDimension = currentNode->getSplittingDimension();
double pointCoord = m_searchedCoordinate.at( splittingDimension );
if( pointCoord < splittingPosition + maxDistance )
fetchNearestPoints( currentNode->getLowerChild(), targetPoints, maxDistance );
if( pointCoord > splittingPosition - maxDistance )
fetchNearestPoints( currentNode->getHigherChild(), targetPoints, maxDistance );
if( currentNode->isLowerKdNodeCase( pointCoord - maxDistance ) )
traverseNodePoints( currentNode->getLowerChild(), maxDistance );
if( !currentNode->isLowerKdNodeCase( pointCoord + maxDistance ) )
traverseNodePoints( currentNode->getHigherChild(), maxDistance );
}
else
{
......@@ -132,3 +173,11 @@ void WPointSearcher::fetchNearestPoints( WKdTreeND* currentNode, vector<WPointDi
}
}
}
void WPointSearcher::onPointFound( WKdPointND* point )
{
m_foundPoints->push_back( WPointDistance( m_searchedCoordinate, point ) );
}
bool WPointSearcher::pointCanBelongToPointSet( const vector<double>& point, double maxDistance )
{
return WVectorMaths::getEuclidianDistance( m_searchedCoordinate, point ) <= maxDistance;
}
......@@ -54,13 +54,6 @@ public:
* Destroys the points searcher
*/
virtual ~WPointSearcher();
/**
* Static method that fetches coordinates of WPointDistance sets into a three
* dimensional WPosition point list.
* \param pointDistances Point distance data sets to fetch positions from.
* \return A WPosition list. That type is very commonly used in OpenWalnut.
*/
static vector<WPosition>* convertToPointSet( vector<WPointDistance>* pointDistances );