Commit 1bc05cfd authored by Andreas Schwarzkopf's avatar Andreas Schwarzkopf

[ADD #371] Completed main features.

 * Finalized main features
 *
 * New added features:
 *   - Brute Force peak detection clustering
 *   - Modified convex hull boundary detection for separation of spatially disconnected
 *     points.
 *
 * Reached beta version status.
parent 4fc2c24d
......@@ -33,6 +33,12 @@ WKdPointND::WKdPointND( vector<double> coordinate )
{
m_coordinate = coordinate;
}
WKdPointND::WKdPointND( double x, double y )
{
m_coordinate = vector<double>( 2, 0 );
m_coordinate[0] = x;
m_coordinate[1] = y;
}
WKdPointND::WKdPointND( double x, double y, double z )
{
m_coordinate = vector<double>( 3, 0 );
......@@ -52,3 +58,7 @@ vector<double> WKdPointND::getCoordinate()
{
return m_coordinate;
}
void WKdPointND::setCoordinate( vector<double> coordinate )
{
m_coordinate = coordinate;
}
......@@ -44,6 +44,12 @@ public:
* \param coordinate N dimensional coordinate of the new kd tree point.
*/
explicit WKdPointND( vector<double> coordinate );
/**
* Instance to create a two dimensional kd tree point instance.
* \param x Three dimensional X coordinate of the new kd tree point.
* \param y Three dimensional Y coordinate of the new kd tree point.
*/
WKdPointND( double x, double y );
/**
* Instance to create a three dimensional kd tree point instance.
* \param x X coordinate of the new kd tree point.
......@@ -66,6 +72,11 @@ public:
* \return Coordinate of a kd tree point.
*/
vector<double> getCoordinate();
/**
* Sets coordinate of the point.
* \param coordinate Point's coordinate.
*/
void setCoordinate( vector<double> coordinate );
private:
/**
......
......@@ -31,6 +31,29 @@ using std::cout;
using std::endl;
WKdTreeND::WKdTreeND()
{
m_dimensions = 3;
// areaMin.reserve( 3 );
// areaMin.resize( 3 );
// areaMax.reserve( 3 );
// areaMax.resize( 3 );
// hasBoundMin.reserve( 3 );
// hasBoundMin.resize( 3 );
// hasBoundMax.reserve( 3 );
// hasBoundMax.resize( 3 );
// for( size_t index = 0; index < 3; index++ )
// {
// areaMin[index] = 0;
// areaMax[index] = 0;
// hasBoundMin[index] = false;
// hasBoundMax[index] = false;
// }
m_splittingDimension = 0;
m_splittingPosition = 0.0;
m_allowDoubles = true;
m_points = new vector<WKdPointND* >();
m_parentSplittingDimension = 3;
m_higherChild = 0;
m_lowerChild = 0;
}
WKdTreeND::WKdTreeND( size_t dimensions )
{
......
......@@ -29,6 +29,7 @@
WPointDistance::WPointDistance()
{
m_pointDistance = 0;
m_comparedPoint = 0;
}
WPointDistance::WPointDistance( vector<double> sourcePoint, WKdPointND* comparedPoint )
{
......@@ -51,15 +52,11 @@ double WPointDistance::getDistance()
{
return m_pointDistance;
}
double WPointDistance::getPointDistance( vector<double> point1, vector<double> point2 )
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++ )
{
double coord1 = point1[index];
double coord2 = point2[index];
distance += pow( coord1 - coord2, 2 );
}
distance += pow( point1[index] - point2[index], 2 );
return pow( distance, 0.5 );
}
bool WPointDistance::operator<( WPointDistance const& right ) const
......
......@@ -81,7 +81,7 @@ public:
* \param point2 Second point for calculating the distance.
* \return Euclidian distance between that two points.
*/
static double getPointDistance( vector<double> point1, vector<double> point2 );
static double getPointDistance( const vector<double>& point1, const vector<double>& point2 );
/**
* Operator for sorting a vector<WPointDistance> using std::sort.
* \param right The right compared object to this one.
......
......@@ -28,6 +28,13 @@
#include "WPointSearcher.h"
WPointSearcher::WPointSearcher()
{
m_distanceSteps = 4;
m_examinedKdTree = 0;
m_maxResultPointCount = 50;
m_maxSearchDistance = 0.5;
}
WPointSearcher::WPointSearcher( WKdTreeND* kdTree )
{
m_distanceSteps = 4;
......@@ -54,7 +61,7 @@ vector<WPosition>* WPointSearcher::convertToPointSet( vector<WPointDistance>* po
}
vector<WPointDistance>* WPointSearcher::getNearestPoints()
{
vector<WPointDistance>* nearestPoints = new vector<WPointDistance>();
vector<WPointDistance>* nearestPoints = 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
......@@ -62,7 +69,7 @@ vector<WPointDistance>* WPointSearcher::getNearestPoints()
{
delete nearestPoints;
nearestPoints = new vector<WPointDistance>();
double maxDistance = m_maxSearchDistance * pow( 2.0, - ( double )m_distanceSteps + ( double )index );
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;
}
......@@ -81,7 +88,7 @@ void WPointSearcher::setExaminedKdTree( WKdTreeND* kdTree )
{
m_examinedKdTree = kdTree;
}
void WPointSearcher::setSearchedPoint( vector<double> searchedPoint )
void WPointSearcher::setSearchedPoint( const vector<double>& searchedPoint )
{
m_searchedCoordinate = searchedPoint;
}
......
......@@ -44,6 +44,7 @@ using std::vector;
class WPointSearcher
{
public:
explicit WPointSearcher();
/**
* Instantiates the points searcher.
* \param kdTree Assigned source kd tree to search points.
......@@ -79,7 +80,7 @@ public:
* Sets the coordinate of the point to get its neighbors afterwarts.
* \param searchedPoint Coordinate to search for neighbors.
*/
void setSearchedPoint( vector<double> searchedPoint );
void setSearchedPoint( const vector<double>& searchedPoint );
/**
* Sets the maximal distance of neighbors.
* \param distance The maximal distance of neighbors.
......
......@@ -27,9 +27,9 @@
#include "../common/math/leastSquares/WLeastSquares.h"
WLariOutliner::WLariOutliner( WSurfaceDetectorLari* surfaceDetector )
WLariOutliner::WLariOutliner( WLariPointClassifier* pointClassifier )
{
m_surfaceDetector = surfaceDetector;
m_pointClassifier = pointClassifier;
}
WLariOutliner::~WLariOutliner()
......@@ -43,16 +43,19 @@ boost::shared_ptr< WDataSetPointsGrouped > WLariOutliner::outlineParameterDomain
new WDataSetPointsGrouped::ColorArray::element_type() );
WDataSetPointsGrouped::GroupArray outGroups(
new WDataSetPointsGrouped::GroupArray::element_type() );
vector<WKdPointND*>* parameters = m_surfaceDetector->getParameterDomain()->getAllPoints();
vector<WKdPointND*>* parameters = m_pointClassifier->getParameterDomain()->getAllPoints();
for( size_t index = 0; index < parameters->size(); index++ )
{
WParameterDomainKdPoint* parameter = static_cast<WParameterDomainKdPoint*>( parameters->at( index ) );
vector<double> parameterCoordinate = parameter->getCoordinate();
for( size_t dimension = 0; dimension < parameterCoordinate.size(); dimension++ )
outVertices->push_back( parameterCoordinate[dimension] );
for( size_t colorCh = 0; colorCh < 3; colorCh++ )
outColors->push_back( 1.0 );
outGroups->push_back( parameter->getSpatialPoint()->getClusterID() );
if( m_pointClassifier->calculateIsPlanarPoint( parameter->getSpatialPoint()->getEigenValues() ) )
{
vector<double> parameterCoordinate = parameter->getCoordinate();
for( size_t dimension = 0; dimension < parameterCoordinate.size(); dimension++ )
outVertices->push_back( parameterCoordinate[dimension] );
for( size_t colorCh = 0; colorCh < 3; colorCh++ )
outColors->push_back( 1.0 );
outGroups->push_back( parameter->getSpatialPoint()->getClusterID() );
}
}
boost::shared_ptr< WDataSetPointsGrouped > outputPoints(
new WDataSetPointsGrouped( outVertices, outColors, outGroups ) );
......@@ -66,16 +69,19 @@ boost::shared_ptr< WDataSetPointsGrouped > WLariOutliner::outlineSpatialDomainGr
new WDataSetPointsGrouped::ColorArray::element_type() );
WDataSetPointsGrouped::GroupArray outGroups(
new WDataSetPointsGrouped::GroupArray::element_type() );
vector<WKdPointND*>* spatialDomainPoints = m_surfaceDetector->getSpatialDomain()->getAllPoints();
vector<WKdPointND*>* spatialDomainPoints = m_pointClassifier->getSpatialDomain()->getAllPoints();
for( size_t index = 0; index < spatialDomainPoints->size(); index++ )
{
WSpatialDomainKdPoint* spatialPoint = static_cast<WSpatialDomainKdPoint*>( spatialDomainPoints->at( index ) );
vector<double> spatialCoordinate = spatialPoint->getCoordinate();
for( size_t dimension = 0; dimension < spatialCoordinate.size(); dimension++ )
outVertices->push_back( spatialCoordinate[dimension] );
outGroups->push_back( spatialPoint->getClusterID() );
if( m_pointClassifier->calculateIsPlanarPoint( spatialPoint->getEigenValues() ) )
{
vector<double> spatialCoordinate = spatialPoint->getCoordinate();
for( size_t dimension = 0; dimension < spatialCoordinate.size(); dimension++ )
outVertices->push_back( spatialCoordinate[dimension] );
outGroups->push_back( spatialPoint->getClusterID() );
for( size_t colorCh = 0; colorCh < 3; colorCh++ )
outColors->push_back( 1.0 );
}
}
boost::shared_ptr< WDataSetPointsGrouped > outputPoints(
new WDataSetPointsGrouped( outVertices, outColors, outGroups ) );
......@@ -85,7 +91,7 @@ boost::shared_ptr< WDataSetPoints > WLariOutliner::outlineSpatialDomainCategorie
{
WDataSetPoints::VertexArray outVertices( new WDataSetPoints::VertexArray::element_type() );
WDataSetPoints::ColorArray outColors( new WDataSetPoints::ColorArray::element_type() );
vector<WKdPointND*>* spatialDomainPoints = m_surfaceDetector->getSpatialDomain()->getAllPoints();
vector<WKdPointND*>* spatialDomainPoints = m_pointClassifier->getSpatialDomain()->getAllPoints();
for( size_t index = 0; index < spatialDomainPoints->size(); index++ )
{
WSpatialDomainKdPoint* spatialPoint = static_cast<WSpatialDomainKdPoint*>( spatialDomainPoints->at( index ) );
......@@ -100,8 +106,8 @@ boost::shared_ptr< WDataSetPoints > WLariOutliner::outlineSpatialDomainCategorie
nLambdaI.push_back( eigenValues[i] / sumLambda );
for( size_t dimension = 0; dimension < spatialCoordinate.size(); dimension++ )
outVertices->push_back( spatialCoordinate[dimension] );
bool isPlanar = m_surfaceDetector->calculateIsPlanarPoint( eigenValues );
bool isCylindrical = m_surfaceDetector->calculateIsCylindricalPoint( eigenValues );
bool isPlanar = m_pointClassifier->calculateIsPlanarPoint( eigenValues );
bool isCylindrical = m_pointClassifier->calculateIsCylindricalPoint( eigenValues );
if( isPlanar || isCylindrical )
{
outColors->push_back( isPlanar ?1 :0 );
......@@ -121,7 +127,7 @@ boost::shared_ptr< WDataSetPoints > WLariOutliner::outlineSpatialDomainCategorie
boost::shared_ptr< WTriangleMesh > WLariOutliner::outlineLeastSquaresPlanes( double squaresWidth )
{
boost::shared_ptr< WTriangleMesh > outputMesh( new WTriangleMesh( 0, 0 ) );
vector<WKdPointND*>* spatialNodes = m_surfaceDetector->getSpatialDomain()->getAllPoints();
vector<WKdPointND*>* spatialNodes = m_pointClassifier->getSpatialDomain()->getAllPoints();
for( size_t index = 0; index < spatialNodes->size(); index++ )
{
WSpatialDomainKdPoint* spatialDomainPoint = static_cast<WSpatialDomainKdPoint*>( spatialNodes->at( index ) );
......
......@@ -28,7 +28,7 @@
#include <iostream>
#include <vector>
#include "WSurfaceDetectorLari.h"
#include "WLariPointClassifier.h"
#include "core/dataHandler/WDataSetPoints.h"
#include "structure/WParameterDomainKdPoint.h"
#include "structure/WSpatialDomainKdPoint.h"
......@@ -53,10 +53,10 @@ class WLariOutliner
public:
/**
* Instantiates the Lari/Habib segmentation result outliner.
* \param surfaceDetector Lari/Habib segmentation insgance to access the spatial and
* parameter domain.
* \param pointClassifier Lari/Habib segmentation insgance to access the spatial and
* parameter domain.
*/
explicit WLariOutliner( WSurfaceDetectorLari* surfaceDetector );
explicit WLariOutliner( WLariPointClassifier* pointClassifier );
/**
* Destroys the result outlining instance.
*/
......@@ -90,10 +90,11 @@ public:
private:
/**
* Assigned Surface detection instance that uses the approach of Lari/Habib. It's
* used to retirieve a corresponding spatial or parameter domain.
* Point classification instance. By this way spatial and parameter domain points
* are fetched. But also points can be classified whether they areplanar,
* cylindrical or rough surface.
*/
WSurfaceDetectorLari* m_surfaceDetector;
WLariPointClassifier* m_pointClassifier;
};
#endif // WLARIOUTLINER_H
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------
#include <vector>
#include <limits>
#include "WLariPointClassifier.h"
#include "../common/math/leastSquares/WLeastSquares.h"
WLariPointClassifier::WLariPointClassifier()
{
m_numberPointsK = 12;
m_maxPointDistanceR = 1.0;
m_planarNLambdaMin.reserve( 3 );
m_planarNLambdaMin.resize( 3 );
m_planarNLambdaMax.reserve( 3 );
m_planarNLambdaMax.resize( 3 );
m_cylindricalNLambdaMin.reserve( 3 );
m_cylindricalNLambdaMin.resize( 3 );
m_cylindricalNLambdaMax.reserve( 3 );
m_cylindricalNLambdaMax.resize( 3 );
m_spatialDomain = new WKdTreeND( 3 );
m_parameterDomain = new WKdTreeND( 3 );
setCpuThreadCount( 8 );
}
WLariPointClassifier::~WLariPointClassifier()
{
}
void WLariPointClassifier::analyzeData( vector<WSpatialDomainKdPoint*>* inputPoints )
{
//TODO(aschwarzkopf): After draft stage refine in several methods and remove comments
cout << "Attempting to analyze " << inputPoints->size() << " points" << endl;
delete m_spatialDomain;
delete m_parameterDomain;
m_spatialDomain = new WKdTreeND( 3 );
m_parameterDomain = new WKdTreeND( 3 );
m_spatialDomain->add( reinterpret_cast<vector<WKdPointND*>*>( inputPoints ) );
vector<WParameterDomainKdPoint*>* parameterPoints = new vector<WParameterDomainKdPoint*>();
classifyPoints( inputPoints, parameterPoints );
//Generating properties for each existing point
cout << "Adding " << parameterPoints->size() << " parameter points" << endl;
m_parameterDomain->add( reinterpret_cast<vector<WKdPointND*>*>( parameterPoints ) );
}
WKdTreeND* WLariPointClassifier::getParameterDomain()
{
return m_parameterDomain;
}
WKdTreeND* WLariPointClassifier::getSpatialDomain()
{
return m_spatialDomain;
}
void WLariPointClassifier::classifyPoints( vector<WSpatialDomainKdPoint*>* spatialPoints, vector<WParameterDomainKdPoint*>* parameterPoints )
{
size_t threads = m_cpuThreadCount < spatialPoints->size() ?m_cpuThreadCount :spatialPoints->size();
for( size_t thread = 0; thread < threads; thread++ )
m_cpuThreads[thread] = new boost::thread( &WLariPointClassifier::
classifyPointsAtThread, this, spatialPoints, thread );
for( size_t thread = 0; thread < threads; thread++ )
m_cpuThreads[thread]->join();
for( size_t index = 0; index < spatialPoints->size(); index++ )
{
WSpatialDomainKdPoint* spatialPoint = spatialPoints->at( index );
if( calculateIsPlanarPoint(spatialPoint->getEigenValues() ) && spatialPoint->hasValidParameters() )
{
WParameterDomainKdPoint* newParameter =
new WParameterDomainKdPoint( spatialPoint->getParametersXYZ0() );
newParameter->setSpatialPoint( spatialPoint );
parameterPoints->push_back( newParameter );
}
spatialPoint->setIndexInInputArray( index );
}
}
void WLariPointClassifier::classifyPointsAtThread( vector<WSpatialDomainKdPoint*>* spatialPoints, size_t threadIndex )
{
//cout << (spatialPoints->size()) << " " << (parameterPoints->size()) << " " << threadIndex << endl;
WPointSearcher spatialSearcher( m_spatialDomain );
spatialSearcher.setMaxResultPointCount( m_numberPointsK );
spatialSearcher.setMaxSearchDistance( m_maxPointDistanceR );
for( size_t index = threadIndex; index < spatialPoints->size(); index += m_cpuThreadCount )
{
if( index == 1061 )
cout << "Garbled classified point - " << index << endl;
//cout << "Thread " << threadIndex << ", index " << index << endl;
//Getting nearest n points
WSpatialDomainKdPoint* spatialPoint = spatialPoints->at( index );
vector<double> spatialCoordinate = spatialPoint->getCoordinate();
spatialSearcher.setSearchedPoint( spatialCoordinate );
vector<WPointDistance>* nearestPoints = spatialSearcher.getNearestPoints();
vector<WPosition>* points = WPointSearcher::convertToPointSet( nearestPoints );
spatialPoint->setKNearestPoints( points->size() );
spatialPoint->setDistanceToNthNearestNeighbor( nearestPoints->at( points->size() - 1 ).getDistance() );
//Calculating Eigen properties
WPrincipalComponentAnalysis pca;
pca.analyzeData( points );
spatialPoint->setEigenVectors( pca.getDirections() );
vector<double> eigenValues = pca.getEigenValues();
spatialPoint->setEigenValues( eigenValues );
//Adding parameter space information
WLeastSquares leastSquares;
leastSquares.analyzeData( points );
spatialPoint->setHessescheNormalForm( leastSquares.getHessescheNormalForm() );
delete nearestPoints;
delete points;
}
}
bool WLariPointClassifier::calculateIsPlanarPoint( vector<double> eigenValues )
{
double sum = getVectorSum( eigenValues );
for( size_t index = 0; index < eigenValues.size(); index++ )
{
double value = eigenValues[index] / sum;
if( value <= m_planarNLambdaMin[index]
|| value > m_planarNLambdaMax[index] )
return false;
}
return true;
}
bool WLariPointClassifier::calculateIsCylindricalPoint( vector<double> eigenValues )
{
double sum = getVectorSum( eigenValues );
for( size_t index = 0; index < eigenValues.size(); index++ )
{
double value = eigenValues[index] / sum;
if( value <= m_cylindricalNLambdaMin[index]
|| value > m_cylindricalNLambdaMax[index] )
return false;
}
return true;
}
double WLariPointClassifier::getVectorSum( vector<double> allNumbers )
{
double value = 0;
for( size_t index = 0; index < allNumbers.size(); index++ )
value += allNumbers[index];
return value;
}
void WLariPointClassifier::setNumberPointsK( size_t pointsCount )
{
m_numberPointsK = pointsCount;
}
void WLariPointClassifier::setMaxPointDistanceR( double maxPointDistance )
{
m_maxPointDistanceR = maxPointDistance;
}
void WLariPointClassifier::setCpuThreadCount( size_t cpuThreadCount )
{
m_cpuThreadCount = cpuThreadCount;
m_cpuThreads.reserve( m_cpuThreadCount );
m_cpuThreads.resize( m_cpuThreadCount );
}
void WLariPointClassifier::setPlanarNLambdaRange( size_t lambdaIndex, double min, double max )
{
m_planarNLambdaMin[lambdaIndex] = min;
m_planarNLambdaMax[lambdaIndex] = max;
}
void WLariPointClassifier::setCylindricalNLambdaRange( size_t lambdaIndex, double min, double max )
{
m_cylindricalNLambdaMin[lambdaIndex] = min;
m_cylindricalNLambdaMax[lambdaIndex] = max;
}
......@@ -22,11 +22,12 @@
//
//---------------------------------------------------------------------------
#ifndef WSURFACEDETECTORLARI_H
#define WSURFACEDETECTORLARI_H
#ifndef WLARIPOINTCLASSIFIER_H
#define WLARIPOINTCLASSIFIER_H
#include <iostream>
#include <vector>
#include <boost/thread.hpp>
#include "core/dataHandler/WDataSetPoints.h"
#include "structure/WParameterDomainKdPoint.h"
......@@ -44,23 +45,18 @@ using std::cout;
using std::endl;
using std::vector;
/**
* Class that dues the surface detection using the approaches of Lari/abib (2014). This
* class is in a very early stage and no purpose at the moment.
*/
class WSurfaceDetectorLari
class WLariPointClassifier
{
public:
explicit WSurfaceDetectorLari();
virtual ~WSurfaceDetectorLari();
explicit WLariPointClassifier();
/**
* Destroys the surface detection instance
*/
virtual ~WLariPointClassifier();
/**
* Detects the surfaces using the approach of Lari/Habib (2014). At the moment it
* only colors points whether they have either planar or linear/cylindrical features.
* \param inputPoints nput points to process.
* \return The points that are added a color. Red points have either planar and blue
* ones have linear/cylindrical features. Magenta ones meet both and grey
* none of both criterias.
* Analyzes input point data.
* \param inputPoints Input point data to analyze.
*/
void analyzeData( vector<WSpatialDomainKdPoint*>* inputPoints );
/**
......@@ -74,7 +70,6 @@ public:
* \return The whole point set of the spatial domain.
*/
WKdTreeND* getSpatialDomain();
/**
* Calculates whether a point's eigen values in relation to its neighbors have
* planar features.
......@@ -101,6 +96,11 @@ public:
* \param maxPointDistance The maximal distance to examined neighbors.
*/
void setMaxPointDistanceR( double maxPointDistance );
/**
* Sets the applied CPU thread count.
* \param cpuThreadCount Applied CPU thread count.
*/
void setCpuThreadCount( size_t cpuThreadCount );
/**
* Returns the numbers sum of an array.
* \param allNumbers The numbers to sum.
......@@ -125,54 +125,23 @@ public:
* \param max The higher limit of the lamba of that index.
*/
void setCylindricalNLambdaRange( size_t lambdaIndex, double min, double max );
/**
* Sets the main segmentation settings of the segmentation algorithm. They regard
* the planar formula of each spatial point in relation to its
* neighborship.
* \param maxAngleDegrees Maximal angular deviation of plane formulas between two
* points.
* \param planeDistance Maximal difference between two plane perpendicular distances
* to the origin.
*/
void setSegmentationSettings( double maxAngleDegrees, double planeDistance );
private:
/**
* Initializes the extent sizes of each parameter.
*/
void initExtentSizes();
/**
* Detects surface clusters. It takes information of each parameter point
* (represents a plane formula) how many others it contains in the same planar
* extent group. At first biggest parameter extents are segmented to a plane until
* no parameter point remains
*/
void detectClustersByBruteForce();
/**
* Returns the masimal euclidian distance within an extent from the peak center in
* the parameter domain kd tree.
* \param parametersXYZ0 Parameter domain coordinate from which the maximal
* euclidian distance to the farest extent point is determined.
* \return The maximal euclidian distance from the peak center to the farest
* belonging parameter to the plane within the parameter domain.
*/
double getMaxParameterDistance( vector<double> parametersXYZ0 );
/**
* Returns the points within the parameter domain which belong to an extent of a
* plane.
* \param parametersXYZ0 Peak center coordinate which depicts the region.
* \return Parameter domain points that belong to the extent of a particular plane
* formula.
* Classifies points using Eigen Value analyses (Eigen Values and Eigen Vectors) and