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

[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.
......
......@@ -32,8 +32,30 @@ WVectorMaths::~WVectorMaths()
{
}
const double WVectorMaths::ANGLE_90_DEGREES = asin( 1.0 );
const double WVectorMaths::INFINITY_NEGATIVE = -1.0 / 0.0;
const double WVectorMaths::INFINITY_POSITIVE = 1.0 / 0.0;
double WVectorMaths::getAngleOfVectors( vector<double> vector1, vector<double> vector2 )
void WVectorMaths::addVector( vector<double>* changedVector, const vector<double>& summand )
{
size_t size = changedVector->size();
for( size_t dimension = 0; dimension < size; dimension++ )
changedVector->at( dimension ) += summand[dimension];
}
vector<double> WVectorMaths::copyVector( const vector<double>& copiedVector )
{
vector<double> newVector( copiedVector.size(), 0 );
for( size_t dimension = 0; dimension < copiedVector.size(); dimension++ )
newVector[dimension] = copiedVector[dimension];
return newVector;
}
vector<double>* WVectorMaths::copyVectorForPointer( const vector<double>& copiedVector )
{
vector<double>* newVector = new vector<double>( copiedVector.size(), 0 );
for( size_t dimension = 0; dimension < copiedVector.size(); dimension++ )
newVector->at( dimension ) = copiedVector[dimension];
return newVector;
}
double WVectorMaths::getAngleOfVectors( const vector<double>& vector1, const vector<double>& vector2 )
{
double sum = 0;
double range1 = 0;
......@@ -50,7 +72,7 @@ double WVectorMaths::getAngleOfVectors( vector<double> vector1, vector<double> v
:90.0 - 90.0 * ( sum / abs( sum ) );
return angle;
}
double WVectorMaths::getAngleOfPlanes( vector<double> vector1, vector<double> vector2 )
double WVectorMaths::getAngleOfPlanes( const vector<double>& vector1, const vector<double>& vector2 )
{
double angle = getAngleOfVectors( vector1, vector2 );
return angle > 90.0 ?180.0 - angle :angle;
......@@ -66,3 +88,215 @@ double WVectorMaths::getAngleOfPlanes( WVector3d vector1, WVector3d vector2 )
}
return getAngleOfPlanes( unidimensionalVector1, unidimensionalVector2 );
}
double WVectorMaths::getAngleToAxis( double x, double y )
{
if( x == 0.0 && y != 0.0 )
return 90.0;
if( x == 0.0 )
return 90.0;
double angle = atan( y / x ) / ANGLE_90_DEGREES * 90.0;
return angle;
}
double WVectorMaths::getAngleToAxisComplete( double x, double y )
{
if( x == 0.0 && y == 0.0 )
return atan( y / x ) / ANGLE_90_DEGREES * 90.0;
double angle = getAngleToAxis( x, y );
double angleRad = angle / 90.0 * ANGLE_90_DEGREES;
vector<double>* orig = new2dVectorPointer( x, y );
normalizeVector( orig );
vector<double> rotated = new2dVector( cos( angleRad ), sin( angleRad ) );
if( getEuclidianDistance( *orig, rotated ) > 1.0 )
angle -= 180.0;
while( angle < 0.0 )
angle += 360.0;
delete orig;
return angle;
}
double WVectorMaths::getEuclidianDistance( const vector<double>& distanceVector )
{
double sum = 0.0;
for( size_t dimension = 0; dimension < distanceVector.size(); dimension++ )
sum += pow( distanceVector[dimension], 2.0 );
sum = pow( sum, 0.5 );
return sum;
}
double WVectorMaths::getEuclidianDistance( const vector<double>& point1, const vector<double>& point2 )
{
vector<double>* minuend = copyVectorForPointer( point1 );
invertVector( minuend );
addVector( minuend, point2 );
double euclidianDistance = getEuclidianDistance( *minuend );
delete minuend;
return euclidianDistance;
}
vector<double> WVectorMaths::getIntersectionPoint( const vector<double>& line1P1,
const vector<double>& line1P2, const vector<double>& line2P1, const vector<double>& line2P2 )
{
double deltaX = line1P2[0] - line1P1[0];
double deltaY = line1P2[1] - line1P1[1];
vector<double> result = deltaX > deltaY
?getIntersectionPointAtY( line1P1[0], line1P1[1], line1P2[0], line1P2[1],
line2P1[0], line2P1[1], line2P2[0], line2P2[1] )
:getIntersectionPointAtY( line1P1[1], line1P1[0], line1P2[1], line1P2[0],
line2P1[1], line2P1[0], line2P2[1], line2P2[0] );
if( deltaX <= deltaY )
{
double tmp = result[0];
result[0] = result[1];
result[1] = tmp;
}
return result;
}
double WVectorMaths::getLawOfCosinesAlphaByPoints( const vector<double>& pointA,
const vector<double>& pointB, const vector<double>& pointC )
{
double lengthA = getEuclidianDistance( pointB, pointC );
double lengthB = getEuclidianDistance( pointA, pointC );
double lengthC = getEuclidianDistance( pointA, pointB );
return getLawOfCosinesAlphaByLineLengths( lengthA, lengthB, lengthC );
}
double WVectorMaths::getLawOfCosinesAlphaByLineLengths( double lengthA, double lengthB, double lengthC )
{
double quotient = ( lengthA*lengthA - lengthB*lengthB - lengthC*lengthC ) / ( - 2 * lengthB * lengthC );
return acos( quotient ) / ANGLE_90_DEGREES * 90.0;
}
void WVectorMaths::invertVector( vector<double>* invertedVector )
{
for( size_t dimension = 0; dimension < invertedVector->size(); dimension++ )
invertedVector->at( dimension ) = - invertedVector->at( dimension );
}
bool WVectorMaths::isPointInRange( const vector<double>& point, const vector<double>& rangeFrom, const vector<double>& rangeTo )
{
for( size_t index = 0; index < point.size(); index++ )
if( ( point[index] < rangeFrom[index] && point[index] < rangeTo[index] ) ||
( point[index] > rangeFrom[index] && point[index] > rangeTo[index] ) )
return false;
return true;
}
bool WVectorMaths::isPointOnLine2d( const vector<double>& point,
const vector<double>& lineP1, const vector<double>& lineP2 )
{
double deltaX = lineP2[0] - lineP1[0];
double deltaY = lineP2[1] - lineP1[1];
return deltaX > deltaY
?isPointOnLineAtY( point[0], point[1],
lineP1[0], lineP1[1], lineP2[0], lineP2[1] )
:isPointOnLineAtY( point[1], point[0],
lineP1[1], lineP1[0], lineP2[1], lineP2[0] );
}
bool WVectorMaths::isValidVector( const vector<double>& vector )
{
for( size_t index = 0; index < vector.size(); index++ )
if( vector[index] != vector[index] || vector[index] == INFINITY_POSITIVE || vector[index] == INFINITY_NEGATIVE )
return false;
return true;
}
bool WVectorMaths::linesCanIntersectBounded( const vector<double>& line1P1,
const vector<double>& line1P2, const vector<double>& line2P1, const vector<double>& line2P2 )
{
if( !WVectorMaths::linesCanIntersect( line1P1, line1P2, line2P1, line2P2 ) )
return false;
vector<double> intersection = getIntersectionPoint( line1P1, line1P2, line2P1, line2P2 );
return WVectorMaths::isPointInRange( intersection, line1P1, line1P2 ) &&
WVectorMaths::isPointInRange( intersection, line2P1, line2P2 );
}
bool WVectorMaths::linesCanIntersect( const vector<double>& line1P1,
const vector<double>& line1P2, const vector<double>& line2P1, const vector<double>& line2P2 )
{
double deltaX = line1P2[0] - line1P1[0];
double deltaY = line1P2[1] - line1P1[1];
return deltaX > deltaY
?linesCanIntersectAtY( line1P1[0], line1P1[1], line1P2[0], line1P2[1],
line2P1[0], line2P1[1], line2P2[0], line2P2[1] )
:linesCanIntersectAtY( line1P1[1], line1P1[0], line1P2[1], line1P2[0],
line2P1[1], line2P1[0], line2P2[1], line2P2[0] );
}
void WVectorMaths::multiplyVector( vector<double>* changedVector, const vector<double>& factor )
{
size_t size = changedVector->size();
for( size_t dimension = 0; dimension < size; dimension++ )
changedVector->at( dimension ) *= factor[dimension];
}
vector<double> WVectorMaths::new2dVector( double x, double y )
{
vector<double> newVector( 2, 0 );
newVector[0] = x;
newVector[1] = y;
return newVector;
}
vector<double>* WVectorMaths::new2dVectorPointer( double x, double y )
{
vector<double>* newVector = new vector<double>( 2, 0 );
newVector->at( 0 ) = x;
newVector->at( 1 ) = y;
return newVector;
}
vector<double> WVectorMaths::new3dVector( double x, double y, double z )
{
vector<double> newVector( 3, 0 );
newVector[0] = x;
newVector[1] = y;
newVector[2] = z;
return newVector;
}
void WVectorMaths::normalizeVector( vector<double>* normalizableVector )
{
double sum = getEuclidianDistance( *normalizableVector );
if( sum == 0.0 )
return;
for( size_t dimension = 0; dimension < normalizableVector->size(); dimension++ )
normalizableVector->at( dimension ) /= sum;
}
void WVectorMaths::rotateVector( vector<double>* rotatedVector, size_t firstAxis, size_t secondAxis, double angleDegrees )
{
double firstValue = rotatedVector->at( firstAxis );
double secondValue = rotatedVector->at( secondAxis );
double angle = angleDegrees / 90.0 * ANGLE_90_DEGREES;
rotatedVector->at( firstAxis ) = firstValue * cos( angle ) - secondValue * sin( angle );
rotatedVector->at( secondAxis ) = firstValue * sin( angle ) + secondValue * cos( angle );
}
vector<double> WVectorMaths::getIntersectionPointAtY(
const double& line1P1x, const double& line1P1y, const double& line1P2x, const double& line1P2y,
const double& line2P1x, const double& line2P1y, const double& line2P2x, const double& line2P2y )
{
double a1 = ( line1P2y - line1P1y ) / ( line1P2x - line1P1x );
double t1 = line1P1y - a1 * line1P1x;
double deltaX2 = line2P2x - line2P1x;
double finalX = 0;
if( deltaX2 == 0.0 )
{
finalX = line2P1x;
}
else
{
double a2 = ( line2P2y - line2P1y ) / deltaX2;
double t2 = line2P1y - a2 * line2P1x;
finalX = ( t1 - t2 ) / ( a2 - a1 );
}
vector<double> result = new2dVector( finalX, a1 * finalX + t1 );
return result;
}
bool WVectorMaths::isPointOnLineAtY( const double& pointX, const double& pointY,
const double& lineP1x, const double& lineP1y, const double& lineP2x, const double& lineP2y )
{
double a = ( lineP2y - lineP1y ) / ( lineP2x - lineP1x );
double t = lineP1y - a * lineP1x;
return pointY == a * pointX + t;
}
bool WVectorMaths::linesCanIntersectAtY(
const double& line1P1x, const double& line1P1y, const double& line1P2x, const double& line1P2y,
const double& line2P1x, const double& line2P1y, const double& line2P2x, const double& line2P2y )
{
double a1 = ( line1P2y - line1P1y ) / ( line1P2x - line1P1x );
double deltaX2 = line2P2x - line2P1x;
return deltaX2 == 0 ?true
:a1 != ( line2P2y - line2P1y ) / deltaX2;
}
......@@ -30,6 +30,7 @@
using std::vector;
using std::allocator;
/**
* A set of general vector calculation operations.
......@@ -49,14 +50,40 @@ public:
* Radial amount of 90 degrees.
*/
static const double ANGLE_90_DEGREES;
/**
* Negative infinite value.
*/
static const double INFINITY_NEGATIVE;
/**
* Positive infinite value.
*/
static const double INFINITY_POSITIVE;
/**
* Adds a vector with another.
* \param changedVector First summand. The result is written directly in that value.
* \param summand Second summand.
*/
static void addVector( vector<double>* changedVector, const vector<double>& summand );
/**
* Copies a vector
* \param copiedVector Vector that should be copied.
* \return The copied vector.
*/
static vector<double> copyVector( const vector<double>& copiedVector );
/**
* Copies a vector returning a pointer of the new vector.
* \param copiedVector Vector that should be copied.
* \return The copied vector.
*/
static vector<double>* copyVectorForPointer( const vector<double>& copiedVector );
/**
* Calculates angle between two vectors
* \param vector1 First vector.
* \param vector2 Second vector.
* \return Angle of the two vectors using the decree scale.
*/
static double getAngleOfVectors( vector<double> vector1, vector<double> vector2 );
static double getAngleOfVectors( const vector<double>& vector1, const vector<double>& vector2 );
/**
* Calculates the angle of two planes. It has the range of 180°. Vectors showing
* exactly the same direction have 0°. Lying in the same line but
......@@ -65,7 +92,7 @@ public:
* \param vector2 Second plane normal vector to calculate an angle between.
* \return The angle between the two planes.
*/
static double getAngleOfPlanes( vector<double> vector1, vector<double> vector2 );
static double getAngleOfPlanes( const vector<double>& vector1, const vector<double>& vector2 );
/**
* Returns the angle between two planes.
* \param vector1 Normal vector of the first plane.
......@@ -73,8 +100,215 @@ public:
* \return Angle between two planes.
*/
static double getAngleOfPlanes( WVector3d vector1, WVector3d vector2 );
/**
* Returns a points angle from the coordinate system in relation to the coordinate
* system. The range is 180 degrees because it takes the same angle if the the angle
* is the same but the point goes other direction behind the coordinate system
* origin.
* \param x X coordinate to calculate the angle of:
* \param y Y coordinate to calculate the angle of:
* \return The angle of the two dimensional coordinate in relation to the coordinate
* system origin.
*/
static double getAngleToAxis( double x, double y );
/**
* Calculates the angle of a point in relation to the coordinate system origin. It
* has the whole range of 360 degrees. It shows a different angle if a point would
* be behind the coordinate system origin.
* \param x X coordinate to calculate the angle of:
* \param y Y coordinate to calculate the angle of:
* \return The angle of the two dimensional coordinate in relation to the coordinate
* system origin.
*/
static double getAngleToAxisComplete( double x, double y );
/**
* Returns the euclidian distance (shortest distance throgh the space) across a
* vector.
* \param distanceVector Vector to calculate the euclidean distance of.
* \return The euclidian length of a vector.
*/
static double getEuclidianDistance( const vector<double>& distanceVector );
/**
* Returns the euclidian distance (shortest distance throgh the space) between two
* points.
* \param point1 First vector to calculate the distance between.
* \param point2 Second vector to calculate the distance between.
* \return The shortest connection length between two points.
*/
static double getEuclidianDistance( const vector<double>& point1, const vector<double>& point2 );
/**
* Returns the intersection point between two lines, each is described by two
* points. The method works only for two dimensional coordinate systems.
* \param line1P1 First point of the first line.
* \param line1P2 Second point of the first line.
* \param line2P1 First point of the second line.
* \param line2P2 Second point of the second line.
* \return Intersection point between the two lines.
*/
static vector<double> getIntersectionPoint( const vector<double>& line1P1,
const vector<double>& line1P2, const vector<double>& line2P1, const vector<double>& line2P2 );
/**
* Law Of Cosines that returns an edge angle of a triangle knowing all point
* coordinates.
* \param pointA Triangle point A.
* \param pointB Triangle point B.
* \param pointC Triangle point C.
* \return Angle at the point A.
*/
static double getLawOfCosinesAlphaByPoints( const vector<double>& pointA,
const vector<double>& pointB, const vector<double>& pointC );
/**
* Law Of Cosines that returns an edge angle of a triangle knowing all line lengths.
* \param lengthA Triangle line length A.
* \param lengthB Triangle line length B.
* \param lengthC Triangle line length C.
* \return Angle of the edge at the opposite of the triangle line A.
*/
static double getLawOfCosinesAlphaByLineLengths( double lengthA, double lengthB, double lengthC );
/**
* Tells whether a point lies within the rectangular quader described by two other
* points.
* \param point Point that can be within the range.
* \param rangeFrom First point describing the range quader.
* \param rangeTo Second point describing the range quader.
* \return Point is within that range or not.
*/
static bool isPointInRange( const vector<double>& point,
const vector<double>& rangeFrom, const vector<double>& rangeTo );
/**
* Tells whether a point is hit by a line exactly or not. The line is described by
* two two dimensional points. The line has no bounds.
* \param point Point that can lie on the line.
* \param lineP1 First point describing the not bounded line.
* \param lineP2 Second point describing the not bounded line.
* \return point lies on the line or not.
*/
static bool isPointOnLine2d( const vector<double>& point,
const vector<double>& lineP1, const vector<double>& lineP2 );
/**
* Inverts coordinates of a point of vector.
* \param invertedVector Vector to be inverted.