/******************************************************************************* * Math.cpp * * (C) 2007 AG Aktives Sehen <agas@uni-koblenz.de> * Universitaet Koblenz-Landau * * Additional information: * $Id: $ *******************************************************************************/ #include <limits.h> #include "Math.h" #include <math.h> #include "vec2.h" #define THIS Math THIS::THIS() { } THIS::~THIS() { } float THIS::meanAngle( const std::vector<float>& angles ) { //calculate vectors from angles CVec2 vectorSum(0,0); for ( unsigned i=0; i<angles.size(); i++ ) { vectorSum = vectorSum + CVec2( cos( angles[i] ), sin ( angles[i] ) ); } //return vectorSum.getAngle( CVec2(1,0) ); if ( vectorSum.magnitude() == 0 ) { return 0; } return atan2( vectorSum.y(), vectorSum.x() ); } float THIS::meanAngleWeighted( const std::vector< WeightedValue >& weightedAngles ) { //calculate vectors from angles CVec2 vectorSum(0,0); for ( unsigned i=0; i<weightedAngles.size(); i++ ) { vectorSum = vectorSum + weightedAngles[i].weight * CVec2( cos( weightedAngles[i].value ), sin ( weightedAngles[i].value ) ); } //return vectorSum.getAngle( CVec2(1,0) ); if ( vectorSum.magnitude() == 0 ) { return 0; } return atan2( vectorSum.y(), vectorSum.x() ); } float THIS::angleVariance( float meanAngle, const std::vector<float>& angles ) { float quadSum=0; for( unsigned i=0; i < angles.size(); i++ ) { float turnAngle=minTurnAngle( angles[i], meanAngle ); quadSum += turnAngle*turnAngle; } return quadSum / float ( angles.size() ); } float THIS::minTurnAngle( float angle1, float angle2 ) { /* CVec2 vector1( cos( angle1 ), sin ( angle1 ) ); CVec2 vector2( cos( angle2 ), sin ( angle2 ) ); return vector1.getAngle( vector2 ); */ angle1 *= 180.0/M_PI; angle2 *= 180.0/M_PI; //if(angle1 < 0) angle1 += M_PI * 2; //if(angle2 < 0) angle2 += M_PI * 2; int diff= angle2 - angle1; diff = (diff + 180) % 360 - 180; //float sign=1; //if ( diff < 0 ) { sign=-1; } //minimal turn angle: //if the absolute difference is above 180°, calculate the difference in other direction //if ( fabs(diff) > M_PI ) { // diff = 2*M_PI - fabs(diff); // diff *= sign; //} float ret = static_cast<double>(diff) * M_PI/180.0; return ret; } Point2D THIS::center( std::vector<Point2D>& points ) { double numPoints = double( points.size() ); double sumX=0, sumY=0; for( unsigned i=0; i < points.size(); i++ ) { sumX += points[i].x(); sumY += points[i].y(); } return Point2D( sumX / numPoints, sumY / numPoints ); } double THIS::randomGauss(float variance) { if (variance < 0) { variance = -variance; } double x1, x2, w, y1; do { x1 = 2.0 * random01() - 1.0; x2 = 2.0 * random01() - 1.0; w = x1 * x1 + x2 * x2; } while ( w >= 1.0 ); w = sqrt((-2.0 * log(w)) / w); y1 = x1 * w; // now y1 is uniformly distributed return sqrt(variance) * y1; } double THIS::random01(unsigned long init) { static unsigned long n; if (init > 0) { n = init; } n = 1664525 * n + 1013904223; // create double from unsigned long return (double)(n/2) / (double)LONG_MAX; } #undef THIS