|
|
|
@ -498,34 +498,34 @@ std::vector<Coordinate> computeConvexHull( const std::vector<Coordinate>& points
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
if ( points.size() < 3 ) return points;
|
|
|
|
|
std::vector<Coordinate> worklist = points;
|
|
|
|
|
std::vector<Coordinate> wortdelist = points;
|
|
|
|
|
std::vector<Coordinate> result;
|
|
|
|
|
|
|
|
|
|
double ymin = worklist[0].y;
|
|
|
|
|
double ymin = wortdelist[0].y;
|
|
|
|
|
uint imin = 0;
|
|
|
|
|
for ( uint i = 1; i < worklist.size(); ++i )
|
|
|
|
|
for ( uint i = 1; i < wortdelist.size(); ++i )
|
|
|
|
|
{
|
|
|
|
|
if ( worklist[i].y < ymin )
|
|
|
|
|
if ( wortdelist[i].y < ymin )
|
|
|
|
|
{
|
|
|
|
|
ymin = worklist[i].y;
|
|
|
|
|
ymin = wortdelist[i].y;
|
|
|
|
|
imin = i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// worklist[imin] is definitely on the convex hull, let's start from there
|
|
|
|
|
result.push_back( worklist[imin] );
|
|
|
|
|
Coordinate startpoint = worklist[imin];
|
|
|
|
|
Coordinate apoint = worklist[imin];
|
|
|
|
|
// wortdelist[imin] is definitely on the convex hull, let's start from there
|
|
|
|
|
result.push_back( wortdelist[imin] );
|
|
|
|
|
Coordinate startpoint = wortdelist[imin];
|
|
|
|
|
Coordinate apoint = wortdelist[imin];
|
|
|
|
|
double aangle = 0.0;
|
|
|
|
|
|
|
|
|
|
while ( ! worklist.empty() )
|
|
|
|
|
while ( ! wortdelist.empty() )
|
|
|
|
|
{
|
|
|
|
|
int besti = -1;
|
|
|
|
|
double anglemin = 10000.0;
|
|
|
|
|
for ( uint i = 0; i < worklist.size(); ++i )
|
|
|
|
|
for ( uint i = 0; i < wortdelist.size(); ++i )
|
|
|
|
|
{
|
|
|
|
|
if ( worklist[i] == apoint ) continue;
|
|
|
|
|
Coordinate v = worklist[i] - apoint;
|
|
|
|
|
if ( wortdelist[i] == apoint ) continue;
|
|
|
|
|
Coordinate v = wortdelist[i] - apoint;
|
|
|
|
|
double angle = std::atan2( v.y, v.x );
|
|
|
|
|
while ( angle < aangle ) angle += 2*M_PI;
|
|
|
|
|
if ( angle < anglemin )
|
|
|
|
@ -536,14 +536,14 @@ std::vector<Coordinate> computeConvexHull( const std::vector<Coordinate>& points
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( besti < 0 ) return result; // this happens, e.g. if all points coincide
|
|
|
|
|
apoint = worklist[besti];
|
|
|
|
|
apoint = wortdelist[besti];
|
|
|
|
|
aangle = anglemin;
|
|
|
|
|
if ( apoint == startpoint )
|
|
|
|
|
{
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
result.push_back( apoint );
|
|
|
|
|
worklist.erase( worklist.begin() + besti, worklist.begin() + besti + 1 );
|
|
|
|
|
wortdelist.erase( wortdelist.begin() + besti, wortdelist.begin() + besti + 1 );
|
|
|
|
|
}
|
|
|
|
|
assert( false );
|
|
|
|
|
return result;
|
|
|
|
|