1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
|
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Pt { double x, y; };
struct Edge{ Pt A, B; };
using Polygon = vector<Pt>;
bool operator == ( Pt p , Pt q ) { return p.x == q.x && p.y == q.y; }
bool operator != ( Pt p , Pt q ) { return !(p == q); }
bool operator == ( Edge e, Edge f ) { return e.A == f.A && e.B == f.B; }
Pt operator - ( Pt p , Pt q ) { return { p.x - q.x, p.y - q.y }; }
ostream &operator << ( ostream &out, const Pt p ) { return out << p.x << '\t' << p.y << '\t'; }
ostream &operator << ( ostream &out, const Polygon P ) { for ( Pt pt : P ) out << pt << '\n'; return out; }
//======================================================================
Polygon detriangulate( const Polygon &P ) // Presumes input is a correct sequence of triangles
{
// Take points in threes, make sure triangle is traversed anticlockwise and add edges to a collection
vector<Edge> edges;
for ( int i = 0; i < P.size(); i += 3 )
{
Pt A = P[i], B = P[i+1], C = P[i+2];
Pt AB = B - A, AC = C - A;
if ( AB.x * AC.y - AB.y * AC.x > 0 ) edges.insert( edges.end(), { { A, B }, { B, C }, { C, A } } );
else edges.insert( edges.end(), { { A, C }, { C, B }, { B, A } } );
}
// Border consists of all edges for which (p,q) and (q,p) aren't both in the collection
vector<Edge> borderEdges;
for ( Edge e : edges )
{
Edge rev = { e.B, e.A };
if ( find( edges.begin(), edges.end(), rev ) == edges.end() ) borderEdges.push_back( e );
}
// Cycle round the border, joining up points
Polygon Q;
Pt first = borderEdges.front().A, last = borderEdges.front().B;
Q.push_back( first );
while ( last != first )
{
Q.push_back( last );
for ( Edge e : borderEdges )
{
if ( e.A == last )
{
last = e.B;
break;
}
}
}
return Q;
}
//======================================================================
int main()
{
Polygon P = { {259 , 611.5 }, {204.3, 577.25}, {372.5, 331 },
{568 , 298 }, {568.5, 202.75}, {713.3, 239.5 },
{720 , 421 }, {751.8, 544.5 }, {469 , 642.25},
{469 , 642.25}, {259 , 611.5 }, {372.5, 331 },
{568 , 298 }, {713.3, 239.5 }, {720 , 421 },
{720 , 421 }, {469 , 642.25}, {372.5, 331 },
{480.3, 331.25}, {568 , 298 }, {720 , 421 },
{720 , 421 }, {372.5, 331 }, {480.3 ,331.25} };
Polygon Q = detriangulate( P );
cout << Q;
}
|