Skip to content

Commit

Permalink
Merge pull request #46 from aaronfranke/enum-std
Browse files Browse the repository at this point in the history
Use named enums and explicit std:: instead of "using namespace std"
  • Loading branch information
ivanfratric authored Jan 12, 2021
2 parents 545dfc5 + 27443d9 commit 7bdffb4
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 52 deletions.
41 changes: 29 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
#### PolyPartition

PolyPartition is a lightweight C++ library for polygon partition and triangulation. PolyPartition implements multiple algorithms for both convex partitioning and triangulation. Different algorithms produce different quality of results (and their complexity varies accordingly). The implemented methods/algorithms with their advantages and disadvantages are outlined below.

For input parameters and return values see method declarations in `polypartition.h`. All methods require that the input polygons are not self-intersecting, and are defined in the correct vertex order (conter-clockwise for non-holes, clockwise for holes). Polygon vertices can easily be ordered correctly by calling `TPPLPoly::SetOrientation` method.
PolyPartition is a lightweight C++ library for polygon partition
and triangulation. PolyPartition implements multiple algorithms
for both convex partitioning and triangulation. Different
algorithms produce different quality of results (and their
complexity varies accordingly). The implemented methods/algorithms
with their advantages and disadvantages are outlined below.

For input parameters and return values see method declarations
in `polypartition.h`. All methods require that the input polygons
are not self-intersecting, are defined in the correct vertex order
(counter-clockwise for non-holes, clockwise for holes), and any holes
must be explicitly marked as holes (you can use `SetHole(true)`).
Polygon vertices can easily be ordered correctly by
calling `TPPLPoly::SetOrientation` method.

Input polygon:

Expand All @@ -14,9 +25,9 @@ Method: `TPPLPartition::Triangulate_EC`

Time/Space complexity: `O(n^2)/O(n)`

Supports holes: Yes, by calling `TPPLPartition::RemoveHoles`
Supports holes: Yes, by calling `TPPLPartition::RemoveHoles`.

Quality of solution: Satisfactory in most cases
Quality of solution: Satisfactory in most cases.

Example:

Expand All @@ -29,9 +40,11 @@ Method: `TPPLPartition::Triangulate_OPT`

Time/Space complexity: `O(n^3)/O(n^2)`

Supports holes: No. You could call `TPPLPartition::RemoveHoles` prior to calling `TPPLPartition::Triangulate_OPT`, but the solution would no longer be optimal, thus defeating the purpose
Supports holes: No. You could call `TPPLPartition::RemoveHoles` prior
to calling `TPPLPartition::Triangulate_OPT`, but the solution would no
longer be optimal, thus defeating the purpose.

Quality of solution: Optimal in terms of minimal edge length
Quality of solution: Optimal in terms of minimal edge length.

Example:

Expand All @@ -46,7 +59,7 @@ Time/Space complexity: `O(n*log(n))/O(n)`

Supports holes: Yes, by design

Quality of solution: Poor. Many thin triangles are created in most cases
Quality of solution: Poor. Many thin triangles are created in most cases.

Example:

Expand All @@ -59,9 +72,11 @@ Method: `TPPLPartition::ConvexPartition_HM`

Time/Space complexity: `O(n^2)/O(n)`

Supports holes: Yes, by calling `TPPLPartition::RemoveHoles`
Supports holes: Yes, by calling `TPPLPartition::RemoveHoles`.

Quality of solution: At most four times the minimum number of convex polygons is created. However, in practice it works much better than that and often gives optimal partition.
Quality of solution: At most four times the minimum number of convex
polygons is created. However, in practice it works much better
than that and often gives optimal partition.

Example:

Expand All @@ -74,9 +89,11 @@ Method: `TPPLPartition::ConvexPartition_OPT`

Time/Space complexity: `O(n^3)/O(n^3)`

Supports holes: No. You could call `TPPLPartition::RemoveHoles` prior to calling `TPPLPartition::Triangulate_OPT`, but the solution would no longer be optimal, thus defeating the purpose
Supports holes: No. You could call `TPPLPartition::RemoveHoles`
prior to calling `TPPLPartition::Triangulate_OPT`, but the solution
would no longer be optimal, thus defeating the purpose.

Quality of solution: Optimal. A minimum number of convex polygons is produced
Quality of solution: Optimal. A minimum number of convex polygons is produced.

Example:

Expand Down
48 changes: 18 additions & 30 deletions src/polypartition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,13 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/

#include "polypartition.h"

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <list>
#include <set>
#include <stdexcept>
#include <vector>

using namespace std;

#include "polypartition.h"

#define TPPL_VERTEXTYPE_REGULAR 0
#define TPPL_VERTEXTYPE_START 1
#define TPPL_VERTEXTYPE_END 2
#define TPPL_VERTEXTYPE_SPLIT 3
#define TPPL_VERTEXTYPE_MERGE 4

TPPLPoly::TPPLPoly() {
hole = false;
numpoints = 0;
Expand Down Expand Up @@ -98,7 +86,7 @@ TPPLPoly &TPPLPoly::operator=(const TPPLPoly &src) {
return *this;
}

int TPPLPoly::GetOrientation() const {
TPPLOrientation TPPLPoly::GetOrientation() const {
long i1, i2;
tppl_float area = 0;
for (i1 = 0; i1 < numpoints; i1++) {
Expand All @@ -109,17 +97,17 @@ int TPPLPoly::GetOrientation() const {
area += points[i1].x * points[i2].y - points[i1].y * points[i2].x;
}
if (area > 0) {
return TPPL_CCW;
return TPPL_ORIENTATION_CCW;
}
if (area < 0) {
return TPPL_CW;
return TPPL_ORIENTATION_CW;
}
return 0;
return TPPL_ORIENTATION_NONE;
}

void TPPLPoly::SetOrientation(int orientation) {
int polyorientation = GetOrientation();
if (polyorientation && (polyorientation != orientation)) {
void TPPLPoly::SetOrientation(TPPLOrientation orientation) {
TPPLOrientation polyorientation = GetOrientation();
if (polyorientation != TPPL_ORIENTATION_NONE && polyorientation != orientation) {
Invert();
}
}
Expand Down Expand Up @@ -996,8 +984,8 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
DiagonalList::iterator iter, iter2;
int ret;
TPPLPoly newpoly;
vector<long> indices;
vector<long>::iterator iiter;
std::vector<long> indices;
std::vector<long>::iterator iiter;
bool ijreal, jkreal;

n = poly->GetNumPoints();
Expand Down Expand Up @@ -1342,7 +1330,7 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
std::sort(priority, &(priority[numvertices]), VertexSorter(vertices));

// Determine vertex types.
char *vertextypes = new char[maxnumvertices];
TPPLVertexType *vertextypes = new TPPLVertexType[maxnumvertices];
for (i = 0; i < numvertices; i++) {
v = &(vertices[i]);
vprev = &(vertices[v->previous]);
Expand Down Expand Up @@ -1372,12 +1360,12 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
// Note that while set doesn't actually have to be implemented as
// a tree, complexity requirements for operations are the same as
// for the balanced binary search tree.
set<ScanLineEdge> edgeTree;
std::set<ScanLineEdge> edgeTree;
// Store iterators to the edge tree elements.
// This makes deleting existing edges much faster.
set<ScanLineEdge>::iterator *edgeTreeIterators, edgeIter;
edgeTreeIterators = new set<ScanLineEdge>::iterator[maxnumvertices];
pair<set<ScanLineEdge>::iterator, bool> edgeTreeRet;
std::set<ScanLineEdge>::iterator *edgeTreeIterators, edgeIter;
edgeTreeIterators = new std::set<ScanLineEdge>::iterator[maxnumvertices];
std::pair<std::set<ScanLineEdge>::iterator, bool> edgeTreeRet;
for (i = 0; i < numvertices; i++) {
edgeTreeIterators[i] = edgeTree.end();
}
Expand Down Expand Up @@ -1581,8 +1569,8 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto

// Adds a diagonal to the doubly-connected list of vertices.
void TPPLPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
char *vertextypes, set<ScanLineEdge>::iterator *edgeTreeIterators,
set<ScanLineEdge> *edgeTree, long *helpers) {
TPPLVertexType *vertextypes, std::set<ScanLineEdge>::iterator *edgeTreeIterators,
std::set<ScanLineEdge> *edgeTree, long *helpers) {
long newindex1, newindex2;

newindex1 = *numvertices;
Expand Down
33 changes: 23 additions & 10 deletions src/polypartition.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,19 @@

typedef double tppl_float;

#define TPPL_CCW 1
#define TPPL_CW -1
enum TPPLOrientation {
TPPL_ORIENTATION_CW = -1,
TPPL_ORIENTATION_NONE = 0,
TPPL_ORIENTATION_CCW = 1,
};

enum TPPLVertexType {
TPPL_VERTEXTYPE_REGULAR = 0,
TPPL_VERTEXTYPE_START = 1,
TPPL_VERTEXTYPE_END = 2,
TPPL_VERTEXTYPE_SPLIT = 3,
TPPL_VERTEXTYPE_MERGE = 4,
};

// 2D point structure.
struct TPPLPoint {
Expand Down Expand Up @@ -139,16 +150,18 @@ class TPPLPoly {

// Returns the orientation of the polygon.
// Possible values:
// TPPL_CCW : Polygon vertices are in counter-clockwise order.
// TPPL_CW : Polygon vertices are in clockwise order.
// 0 : The polygon has no (measurable) area.
int GetOrientation() const;
// TPPL_ORIENTATION_CCW: Polygon vertices are in counter-clockwise order.
// TPPL_ORIENTATION_CW: Polygon vertices are in clockwise order.
// TPPL_ORIENTATION_NONE: The polygon has no (measurable) area.
TPPLOrientation GetOrientation() const;

// Sets the polygon orientation.
// Possible values:
// TPPL_CCW : Sets vertices in counter-clockwise order.
// TPPL_CW : Sets vertices in clockwise order.
void SetOrientation(int orientation);
// TPPL_ORIENTATION_CCW: Sets vertices in counter-clockwise order.
// TPPL_ORIENTATION_CW: Sets vertices in clockwise order.
// TPPL_ORIENTATION_NONE: Reverses the orientation of the vertices if there
// is one, otherwise does nothing (if orientation is already NONE).
void SetOrientation(TPPLOrientation orientation);

// Checks whether a polygon is valid or not.
inline bool Valid() const { return this->numpoints >= 3; }
Expand Down Expand Up @@ -252,7 +265,7 @@ class TPPLPartition {
// Helper functions for MonotonePartition.
bool Below(TPPLPoint &p1, TPPLPoint &p2);
void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
char *vertextypes, std::set<ScanLineEdge>::iterator *edgeTreeIterators,
TPPLVertexType *vertextypes, std::set<ScanLineEdge>::iterator *edgeTreeIterators,
std::set<ScanLineEdge> *edgeTree, long *helpers);

// Triangulates a monotone polygon, used in Triangulate_MONO.
Expand Down

0 comments on commit 7bdffb4

Please sign in to comment.