Update PolyPartition / Triangulator library
This commit is contained in:
parent
bd07c5b7a8
commit
ddd6fb37e8
|
@ -320,6 +320,12 @@ Comment: Minimal PCG32 implementation
|
||||||
Copyright: 2014, M.E. O'Neill
|
Copyright: 2014, M.E. O'Neill
|
||||||
License: Apache-2.0
|
License: Apache-2.0
|
||||||
|
|
||||||
|
Files: ./thirdparty/misc/polypartition.cpp
|
||||||
|
./thirdparty/misc/polypartition.h
|
||||||
|
Comment: PolyPartition / Triangulator
|
||||||
|
Copyright: 2011-2021, Ivan Fratric and contributors
|
||||||
|
License: Expat
|
||||||
|
|
||||||
Files: ./thirdparty/misc/r128.c
|
Files: ./thirdparty/misc/r128.c
|
||||||
./thirdparty/misc/r128.h
|
./thirdparty/misc/r128.h
|
||||||
Comment: r128 library
|
Comment: r128 library
|
||||||
|
@ -338,12 +344,6 @@ Comment: stb libraries
|
||||||
Copyright: Sean Barrett
|
Copyright: Sean Barrett
|
||||||
License: public-domain or Unlicense or Expat
|
License: public-domain or Unlicense or Expat
|
||||||
|
|
||||||
Files: ./thirdparty/misc/triangulator.cpp
|
|
||||||
./thirdparty/misc/triangulator.h
|
|
||||||
Comment: PolyPartition
|
|
||||||
Copyright: 2011, Ivan Fratric
|
|
||||||
License: Expat
|
|
||||||
|
|
||||||
Files: ./thirdparty/misc/yuv2rgb.h
|
Files: ./thirdparty/misc/yuv2rgb.h
|
||||||
Comment: YUV2RGB
|
Comment: YUV2RGB
|
||||||
Copyright: 2008-2011, Robin Watts
|
Copyright: 2008-2011, Robin Watts
|
||||||
|
|
|
@ -54,7 +54,7 @@ thirdparty_misc_sources = [
|
||||||
"smaz.c",
|
"smaz.c",
|
||||||
# C++ sources
|
# C++ sources
|
||||||
"pcg.cpp",
|
"pcg.cpp",
|
||||||
"triangulator.cpp",
|
"polypartition.cpp",
|
||||||
"clipper.cpp",
|
"clipper.cpp",
|
||||||
]
|
]
|
||||||
thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources]
|
thirdparty_misc_sources = [thirdparty_misc_dir + file for file in thirdparty_misc_sources]
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
#include "geometry_2d.h"
|
#include "geometry_2d.h"
|
||||||
|
|
||||||
#include "thirdparty/misc/clipper.hpp"
|
#include "thirdparty/misc/clipper.hpp"
|
||||||
#include "thirdparty/misc/triangulator.h"
|
#include "thirdparty/misc/polypartition.h"
|
||||||
#define STB_RECT_PACK_IMPLEMENTATION
|
#define STB_RECT_PACK_IMPLEMENTATION
|
||||||
#include "thirdparty/misc/stb_rect_pack.h"
|
#include "thirdparty/misc/stb_rect_pack.h"
|
||||||
|
|
||||||
|
@ -39,16 +39,16 @@
|
||||||
|
|
||||||
Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(Vector<Point2> polygon) {
|
Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(Vector<Point2> polygon) {
|
||||||
Vector<Vector<Vector2>> decomp;
|
Vector<Vector<Vector2>> decomp;
|
||||||
List<TriangulatorPoly> in_poly, out_poly;
|
List<TPPLPoly> in_poly, out_poly;
|
||||||
|
|
||||||
TriangulatorPoly inp;
|
TPPLPoly inp;
|
||||||
inp.Init(polygon.size());
|
inp.Init(polygon.size());
|
||||||
for (int i = 0; i < polygon.size(); i++) {
|
for (int i = 0; i < polygon.size(); i++) {
|
||||||
inp.GetPoint(i) = polygon[i];
|
inp.GetPoint(i) = polygon[i];
|
||||||
}
|
}
|
||||||
inp.SetOrientation(TRIANGULATOR_CCW);
|
inp.SetOrientation(TPPL_ORIENTATION_CCW);
|
||||||
in_poly.push_back(inp);
|
in_poly.push_back(inp);
|
||||||
TriangulatorPartition tpart;
|
TPPLPartition tpart;
|
||||||
if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { // Failed.
|
if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { // Failed.
|
||||||
ERR_PRINT("Convex decomposing failed!");
|
ERR_PRINT("Convex decomposing failed!");
|
||||||
return decomp;
|
return decomp;
|
||||||
|
@ -56,8 +56,8 @@ Vector<Vector<Vector2>> Geometry2D::decompose_polygon_in_convex(Vector<Point2> p
|
||||||
|
|
||||||
decomp.resize(out_poly.size());
|
decomp.resize(out_poly.size());
|
||||||
int idx = 0;
|
int idx = 0;
|
||||||
for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) {
|
for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) {
|
||||||
TriangulatorPoly &tp = I->get();
|
TPPLPoly &tp = I->get();
|
||||||
|
|
||||||
decomp.write[idx].resize(tp.GetNumPoints());
|
decomp.write[idx].resize(tp.GetNumPoints());
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
#include "core/string/print_string.h"
|
#include "core/string/print_string.h"
|
||||||
|
|
||||||
#include "thirdparty/misc/clipper.hpp"
|
#include "thirdparty/misc/clipper.hpp"
|
||||||
#include "thirdparty/misc/triangulator.h"
|
#include "thirdparty/misc/polypartition.h"
|
||||||
|
|
||||||
void Geometry3D::MeshData::optimize_vertices() {
|
void Geometry3D::MeshData::optimize_vertices() {
|
||||||
Map<int, int> vtx_remap;
|
Map<int, int> vtx_remap;
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include "scene/resources/mesh.h"
|
#include "scene/resources/mesh.h"
|
||||||
#include "scene/resources/surface_tool.h"
|
#include "scene/resources/surface_tool.h"
|
||||||
|
|
||||||
#include "thirdparty/misc/triangulator.h"
|
#include "thirdparty/misc/polypartition.h"
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
T collect_first(const Vector<VertexData<T>> *p_data, T p_fall_back) {
|
T collect_first(const Vector<VertexData<T>> *p_data, T p_fall_back) {
|
||||||
|
@ -930,30 +930,30 @@ void FBXMeshData::triangulate_polygon(Ref<SurfaceTool> st, Vector<int> p_polygon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TriangulatorPoly triangulator_poly;
|
TPPLPoly tppl_poly;
|
||||||
triangulator_poly.Init(polygon_vertex_count);
|
tppl_poly.Init(polygon_vertex_count);
|
||||||
std::vector<Vector2> projected_vertices(polygon_vertex_count);
|
std::vector<Vector2> projected_vertices(polygon_vertex_count);
|
||||||
for (int i = 0; i < polygon_vertex_count; i += 1) {
|
for (int i = 0; i < polygon_vertex_count; i += 1) {
|
||||||
const Vector2 pv(poly_vertices[i][axis_1_coord], poly_vertices[i][axis_2_coord]);
|
const Vector2 pv(poly_vertices[i][axis_1_coord], poly_vertices[i][axis_2_coord]);
|
||||||
projected_vertices[i] = pv;
|
projected_vertices[i] = pv;
|
||||||
triangulator_poly.GetPoint(i) = pv;
|
tppl_poly.GetPoint(i) = pv;
|
||||||
}
|
}
|
||||||
triangulator_poly.SetOrientation(TRIANGULATOR_CCW);
|
tppl_poly.SetOrientation(TPPL_ORIENTATION_CCW);
|
||||||
|
|
||||||
List<TriangulatorPoly> out_poly;
|
List<TPPLPoly> out_poly;
|
||||||
|
|
||||||
TriangulatorPartition triangulator_partition;
|
TPPLPartition tppl_partition;
|
||||||
if (triangulator_partition.Triangulate_OPT(&triangulator_poly, &out_poly) == 0) { // Good result.
|
if (tppl_partition.Triangulate_OPT(&tppl_poly, &out_poly) == 0) { // Good result.
|
||||||
if (triangulator_partition.Triangulate_EC(&triangulator_poly, &out_poly) == 0) { // Medium result.
|
if (tppl_partition.Triangulate_EC(&tppl_poly, &out_poly) == 0) { // Medium result.
|
||||||
if (triangulator_partition.Triangulate_MONO(&triangulator_poly, &out_poly) == 0) { // Really poor result.
|
if (tppl_partition.Triangulate_MONO(&tppl_poly, &out_poly) == 0) { // Really poor result.
|
||||||
ERR_FAIL_MSG("The triangulation of this polygon failed, please try to triangulate your mesh or check if it has broken polygons.");
|
ERR_FAIL_MSG("The triangulation of this polygon failed, please try to triangulate your mesh or check if it has broken polygons.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Vector2> tris(out_poly.size());
|
std::vector<Vector2> tris(out_poly.size());
|
||||||
for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) {
|
for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) {
|
||||||
TriangulatorPoly &tp = I->get();
|
TPPLPoly &tp = I->get();
|
||||||
|
|
||||||
ERR_FAIL_COND_MSG(tp.GetNumPoints() != 3, "The triangulator retuned more points, how this is possible?");
|
ERR_FAIL_COND_MSG(tp.GetNumPoints() != 3, "The triangulator retuned more points, how this is possible?");
|
||||||
// Find Index
|
// Find Index
|
||||||
|
|
|
@ -36,7 +36,7 @@
|
||||||
#include "scene/resources/concave_polygon_shape_2d.h"
|
#include "scene/resources/concave_polygon_shape_2d.h"
|
||||||
#include "scene/resources/convex_polygon_shape_2d.h"
|
#include "scene/resources/convex_polygon_shape_2d.h"
|
||||||
|
|
||||||
#include "thirdparty/misc/triangulator.h"
|
#include "thirdparty/misc/polypartition.h"
|
||||||
|
|
||||||
void CollisionPolygon2D::_build_polygon() {
|
void CollisionPolygon2D::_build_polygon() {
|
||||||
parent->shape_owner_clear_shapes(owner_id);
|
parent->shape_owner_clear_shapes(owner_id);
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
#include "navigation_2d.h"
|
#include "navigation_2d.h"
|
||||||
#include "servers/navigation_server_2d.h"
|
#include "servers/navigation_server_2d.h"
|
||||||
|
|
||||||
#include "thirdparty/misc/triangulator.h"
|
#include "thirdparty/misc/polypartition.h"
|
||||||
|
|
||||||
#ifdef TOOLS_ENABLED
|
#ifdef TOOLS_ENABLED
|
||||||
Rect2 NavigationPolygon::_edit_get_rect() const {
|
Rect2 NavigationPolygon::_edit_get_rect() const {
|
||||||
|
@ -228,7 +228,7 @@ void NavigationPolygon::make_polygons_from_outlines() {
|
||||||
MutexLock lock(navmesh_generation);
|
MutexLock lock(navmesh_generation);
|
||||||
navmesh.unref();
|
navmesh.unref();
|
||||||
}
|
}
|
||||||
List<TriangulatorPoly> in_poly, out_poly;
|
List<TPPLPoly> in_poly, out_poly;
|
||||||
|
|
||||||
Vector2 outside_point(-1e10, -1e10);
|
Vector2 outside_point(-1e10, -1e10);
|
||||||
|
|
||||||
|
@ -278,23 +278,23 @@ void NavigationPolygon::make_polygons_from_outlines() {
|
||||||
|
|
||||||
bool outer = (interscount % 2) == 0;
|
bool outer = (interscount % 2) == 0;
|
||||||
|
|
||||||
TriangulatorPoly tp;
|
TPPLPoly tp;
|
||||||
tp.Init(olsize);
|
tp.Init(olsize);
|
||||||
for (int j = 0; j < olsize; j++) {
|
for (int j = 0; j < olsize; j++) {
|
||||||
tp[j] = r[j];
|
tp[j] = r[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outer) {
|
if (outer) {
|
||||||
tp.SetOrientation(TRIANGULATOR_CCW);
|
tp.SetOrientation(TPPL_ORIENTATION_CCW);
|
||||||
} else {
|
} else {
|
||||||
tp.SetOrientation(TRIANGULATOR_CW);
|
tp.SetOrientation(TPPL_ORIENTATION_CW);
|
||||||
tp.SetHole(true);
|
tp.SetHole(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
in_poly.push_back(tp);
|
in_poly.push_back(tp);
|
||||||
}
|
}
|
||||||
|
|
||||||
TriangulatorPartition tpart;
|
TPPLPartition tpart;
|
||||||
if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed!
|
if (tpart.ConvexPartition_HM(&in_poly, &out_poly) == 0) { //failed!
|
||||||
ERR_PRINT("NavigationPolygon: Convex partition failed!");
|
ERR_PRINT("NavigationPolygon: Convex partition failed!");
|
||||||
return;
|
return;
|
||||||
|
@ -304,8 +304,8 @@ void NavigationPolygon::make_polygons_from_outlines() {
|
||||||
vertices.resize(0);
|
vertices.resize(0);
|
||||||
|
|
||||||
Map<Vector2, int> points;
|
Map<Vector2, int> points;
|
||||||
for (List<TriangulatorPoly>::Element *I = out_poly.front(); I; I = I->next()) {
|
for (List<TPPLPoly>::Element *I = out_poly.front(); I; I = I->next()) {
|
||||||
TriangulatorPoly &tp = I->get();
|
TPPLPoly &tp = I->get();
|
||||||
|
|
||||||
struct Polygon p;
|
struct Polygon p;
|
||||||
|
|
||||||
|
|
|
@ -424,6 +424,11 @@ Collection of single-file libraries used in Godot components.
|
||||||
* Upstream: http://www.pcg-random.org
|
* Upstream: http://www.pcg-random.org
|
||||||
* Version: minimal C implementation, http://www.pcg-random.org/download.html
|
* Version: minimal C implementation, http://www.pcg-random.org/download.html
|
||||||
* License: Apache 2.0
|
* License: Apache 2.0
|
||||||
|
- `polypartition.{cpp,h}`
|
||||||
|
* Upstream: https://github.com/ivanfratric/polypartition (`src/polypartition.{cpp,h}`)
|
||||||
|
* Version: git (7bdffb428b2b19ad1c43aa44c714dcc104177e84, 2021)
|
||||||
|
* Modifications: Change from STL to Godot types (see provided patch).
|
||||||
|
* License: MIT
|
||||||
- `r128.h`
|
- `r128.h`
|
||||||
* Upstream: https://github.com/fahickman/r128
|
* Upstream: https://github.com/fahickman/r128
|
||||||
* Version: 1.4.4 (cf2e88fc3e7d7dfe99189686f914874cd0bda15e, 2020)
|
* Version: 1.4.4 (cf2e88fc3e7d7dfe99189686f914874cd0bda15e, 2020)
|
||||||
|
@ -441,10 +446,6 @@ Collection of single-file libraries used in Godot components.
|
||||||
* Upstream: https://github.com/nothings/stb
|
* Upstream: https://github.com/nothings/stb
|
||||||
* Version: 1.20 (314d0a6f9af5af27e585336eecea333e95c5a2d8, 2020)
|
* Version: 1.20 (314d0a6f9af5af27e585336eecea333e95c5a2d8, 2020)
|
||||||
* License: Public Domain or Unlicense or MIT
|
* License: Public Domain or Unlicense or MIT
|
||||||
- `triangulator.{cpp,h}`
|
|
||||||
* Upstream: https://github.com/ivanfratric/polypartition (`src/polypartition.cpp`)
|
|
||||||
* Version: TBD, class was renamed
|
|
||||||
* License: MIT
|
|
||||||
- `yuv2rgb.h`
|
- `yuv2rgb.h`
|
||||||
* Upstream: http://wss.co.uk/pinknoise/yuv2rgb/ (to check)
|
* Upstream: http://wss.co.uk/pinknoise/yuv2rgb/ (to check)
|
||||||
* Version: ?
|
* Version: ?
|
||||||
|
|
|
@ -0,0 +1,819 @@
|
||||||
|
diff --git a/thirdparty/misc/polypartition.cpp b/thirdparty/misc/polypartition.cpp
|
||||||
|
index 3a8a6efa8319..4f1b6dcb21d8 100644
|
||||||
|
--- a/thirdparty/misc/polypartition.cpp
|
||||||
|
+++ b/thirdparty/misc/polypartition.cpp
|
||||||
|
@@ -23,10 +23,7 @@
|
||||||
|
|
||||||
|
#include "polypartition.h"
|
||||||
|
|
||||||
|
-#include <math.h>
|
||||||
|
-#include <string.h>
|
||||||
|
#include <algorithm>
|
||||||
|
-#include <vector>
|
||||||
|
|
||||||
|
TPPLPoly::TPPLPoly() {
|
||||||
|
hole = false;
|
||||||
|
@@ -186,7 +183,7 @@ int TPPLPartition::Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TP
|
||||||
|
// Removes holes from inpolys by merging them with non-holes.
|
||||||
|
int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
|
||||||
|
TPPLPolyList polys;
|
||||||
|
- TPPLPolyList::iterator holeiter, polyiter, iter, iter2;
|
||||||
|
+ TPPLPolyList::Element *holeiter, *polyiter, *iter, *iter2;
|
||||||
|
long i, i2, holepointindex, polypointindex;
|
||||||
|
TPPLPoint holepoint, polypoint, bestpolypoint;
|
||||||
|
TPPLPoint linep1, linep2;
|
||||||
|
@@ -198,15 +195,15 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
|
||||||
|
|
||||||
|
// Check for the trivial case of no holes.
|
||||||
|
hasholes = false;
|
||||||
|
- for (iter = inpolys->begin(); iter != inpolys->end(); iter++) {
|
||||||
|
- if (iter->IsHole()) {
|
||||||
|
+ for (iter = inpolys->front(); iter; iter = iter->next()) {
|
||||||
|
+ if (iter->get().IsHole()) {
|
||||||
|
hasholes = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!hasholes) {
|
||||||
|
- for (iter = inpolys->begin(); iter != inpolys->end(); iter++) {
|
||||||
|
- outpolys->push_back(*iter);
|
||||||
|
+ for (iter = inpolys->front(); iter; iter = iter->next()) {
|
||||||
|
+ outpolys->push_back(iter->get());
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
@@ -216,8 +213,8 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
|
||||||
|
while (1) {
|
||||||
|
// Find the hole point with the largest x.
|
||||||
|
hasholes = false;
|
||||||
|
- for (iter = polys.begin(); iter != polys.end(); iter++) {
|
||||||
|
- if (!iter->IsHole()) {
|
||||||
|
+ for (iter = polys.front(); iter; iter = iter->next()) {
|
||||||
|
+ if (!iter->get().IsHole()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -227,8 +224,8 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
|
||||||
|
holepointindex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (i = 0; i < iter->GetNumPoints(); i++) {
|
||||||
|
- if (iter->GetPoint(i).x > holeiter->GetPoint(holepointindex).x) {
|
||||||
|
+ for (i = 0; i < iter->get().GetNumPoints(); i++) {
|
||||||
|
+ if (iter->get().GetPoint(i).x > holeiter->get().GetPoint(holepointindex).x) {
|
||||||
|
holeiter = iter;
|
||||||
|
holepointindex = i;
|
||||||
|
}
|
||||||
|
@@ -237,24 +234,24 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
|
||||||
|
if (!hasholes) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- holepoint = holeiter->GetPoint(holepointindex);
|
||||||
|
+ holepoint = holeiter->get().GetPoint(holepointindex);
|
||||||
|
|
||||||
|
pointfound = false;
|
||||||
|
- for (iter = polys.begin(); iter != polys.end(); iter++) {
|
||||||
|
- if (iter->IsHole()) {
|
||||||
|
+ for (iter = polys.front(); iter; iter = iter->next()) {
|
||||||
|
+ if (iter->get().IsHole()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- for (i = 0; i < iter->GetNumPoints(); i++) {
|
||||||
|
- if (iter->GetPoint(i).x <= holepoint.x) {
|
||||||
|
+ for (i = 0; i < iter->get().GetNumPoints(); i++) {
|
||||||
|
+ if (iter->get().GetPoint(i).x <= holepoint.x) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- if (!InCone(iter->GetPoint((i + iter->GetNumPoints() - 1) % (iter->GetNumPoints())),
|
||||||
|
- iter->GetPoint(i),
|
||||||
|
- iter->GetPoint((i + 1) % (iter->GetNumPoints())),
|
||||||
|
+ if (!InCone(iter->get().GetPoint((i + iter->get().GetNumPoints() - 1) % (iter->get().GetNumPoints())),
|
||||||
|
+ iter->get().GetPoint(i),
|
||||||
|
+ iter->get().GetPoint((i + 1) % (iter->get().GetNumPoints())),
|
||||||
|
holepoint)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- polypoint = iter->GetPoint(i);
|
||||||
|
+ polypoint = iter->get().GetPoint(i);
|
||||||
|
if (pointfound) {
|
||||||
|
v1 = Normalize(polypoint - holepoint);
|
||||||
|
v2 = Normalize(bestpolypoint - holepoint);
|
||||||
|
@@ -263,13 +260,13 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pointvisible = true;
|
||||||
|
- for (iter2 = polys.begin(); iter2 != polys.end(); iter2++) {
|
||||||
|
- if (iter2->IsHole()) {
|
||||||
|
+ for (iter2 = polys.front(); iter2; iter2->next()) {
|
||||||
|
+ if (iter2->get().IsHole()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- for (i2 = 0; i2 < iter2->GetNumPoints(); i2++) {
|
||||||
|
- linep1 = iter2->GetPoint(i2);
|
||||||
|
- linep2 = iter2->GetPoint((i2 + 1) % (iter2->GetNumPoints()));
|
||||||
|
+ for (i2 = 0; i2 < iter2->get().GetNumPoints(); i2++) {
|
||||||
|
+ linep1 = iter2->get().GetPoint(i2);
|
||||||
|
+ linep2 = iter2->get().GetPoint((i2 + 1) % (iter2->get().GetNumPoints()));
|
||||||
|
if (Intersects(holepoint, polypoint, linep1, linep2)) {
|
||||||
|
pointvisible = false;
|
||||||
|
break;
|
||||||
|
@@ -292,18 +289,18 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- newpoly.Init(holeiter->GetNumPoints() + polyiter->GetNumPoints() + 2);
|
||||||
|
+ newpoly.Init(holeiter->get().GetNumPoints() + polyiter->get().GetNumPoints() + 2);
|
||||||
|
i2 = 0;
|
||||||
|
for (i = 0; i <= polypointindex; i++) {
|
||||||
|
- newpoly[i2] = polyiter->GetPoint(i);
|
||||||
|
+ newpoly[i2] = polyiter->get().GetPoint(i);
|
||||||
|
i2++;
|
||||||
|
}
|
||||||
|
- for (i = 0; i <= holeiter->GetNumPoints(); i++) {
|
||||||
|
- newpoly[i2] = holeiter->GetPoint((i + holepointindex) % holeiter->GetNumPoints());
|
||||||
|
+ for (i = 0; i <= holeiter->get().GetNumPoints(); i++) {
|
||||||
|
+ newpoly[i2] = holeiter->get().GetPoint((i + holepointindex) % holeiter->get().GetNumPoints());
|
||||||
|
i2++;
|
||||||
|
}
|
||||||
|
- for (i = polypointindex; i < polyiter->GetNumPoints(); i++) {
|
||||||
|
- newpoly[i2] = polyiter->GetPoint(i);
|
||||||
|
+ for (i = polypointindex; i < polyiter->get().GetNumPoints(); i++) {
|
||||||
|
+ newpoly[i2] = polyiter->get().GetPoint(i);
|
||||||
|
i2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -312,8 +309,8 @@ int TPPLPartition::RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys) {
|
||||||
|
polys.push_back(newpoly);
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (iter = polys.begin(); iter != polys.end(); iter++) {
|
||||||
|
- outpolys->push_back(*iter);
|
||||||
|
+ for (iter = polys.front(); iter; iter = iter->next()) {
|
||||||
|
+ outpolys->push_back(iter->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
@@ -524,13 +521,13 @@ int TPPLPartition::Triangulate_EC(TPPLPoly *poly, TPPLPolyList *triangles) {
|
||||||
|
|
||||||
|
int TPPLPartition::Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles) {
|
||||||
|
TPPLPolyList outpolys;
|
||||||
|
- TPPLPolyList::iterator iter;
|
||||||
|
+ TPPLPolyList::Element *iter;
|
||||||
|
|
||||||
|
if (!RemoveHoles(inpolys, &outpolys)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
- for (iter = outpolys.begin(); iter != outpolys.end(); iter++) {
|
||||||
|
- if (!Triangulate_EC(&(*iter), triangles)) {
|
||||||
|
+ for (iter = outpolys.front(); iter; iter = iter->next()) {
|
||||||
|
+ if (!Triangulate_EC(&(iter->get()), triangles)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -543,7 +540,7 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) {
|
||||||
|
}
|
||||||
|
|
||||||
|
TPPLPolyList triangles;
|
||||||
|
- TPPLPolyList::iterator iter1, iter2;
|
||||||
|
+ TPPLPolyList::Element *iter1, *iter2;
|
||||||
|
TPPLPoly *poly1 = NULL, *poly2 = NULL;
|
||||||
|
TPPLPoly newpoly;
|
||||||
|
TPPLPoint d1, d2, p1, p2, p3;
|
||||||
|
@@ -578,19 +575,19 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) {
|
||||||
|
- poly1 = &(*iter1);
|
||||||
|
+ for (iter1 = triangles.front(); iter1; iter1 = iter1->next()) {
|
||||||
|
+ poly1 = &(iter1->get());
|
||||||
|
for (i11 = 0; i11 < poly1->GetNumPoints(); i11++) {
|
||||||
|
d1 = poly1->GetPoint(i11);
|
||||||
|
i12 = (i11 + 1) % (poly1->GetNumPoints());
|
||||||
|
d2 = poly1->GetPoint(i12);
|
||||||
|
|
||||||
|
isdiagonal = false;
|
||||||
|
- for (iter2 = iter1; iter2 != triangles.end(); iter2++) {
|
||||||
|
+ for (iter2 = iter1; iter2; iter2 = iter2->next()) {
|
||||||
|
if (iter1 == iter2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
- poly2 = &(*iter2);
|
||||||
|
+ poly2 = &(iter2->get());
|
||||||
|
|
||||||
|
for (i21 = 0; i21 < poly2->GetNumPoints(); i21++) {
|
||||||
|
if ((d2.x != poly2->GetPoint(i21).x) || (d2.y != poly2->GetPoint(i21).y)) {
|
||||||
|
@@ -660,16 +657,16 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) {
|
||||||
|
}
|
||||||
|
|
||||||
|
triangles.erase(iter2);
|
||||||
|
- *iter1 = newpoly;
|
||||||
|
- poly1 = &(*iter1);
|
||||||
|
+ iter1->get() = newpoly;
|
||||||
|
+ poly1 = &(iter1->get());
|
||||||
|
i11 = -1;
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- for (iter1 = triangles.begin(); iter1 != triangles.end(); iter1++) {
|
||||||
|
- parts->push_back(*iter1);
|
||||||
|
+ for (iter1 = triangles.front(); iter1; iter1 = iter1->next()) {
|
||||||
|
+ parts->push_back(iter1->get());
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
@@ -677,13 +674,13 @@ int TPPLPartition::ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts) {
|
||||||
|
|
||||||
|
int TPPLPartition::ConvexPartition_HM(TPPLPolyList *inpolys, TPPLPolyList *parts) {
|
||||||
|
TPPLPolyList outpolys;
|
||||||
|
- TPPLPolyList::iterator iter;
|
||||||
|
+ TPPLPolyList::Element *iter;
|
||||||
|
|
||||||
|
if (!RemoveHoles(inpolys, &outpolys)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
- for (iter = outpolys.begin(); iter != outpolys.end(); iter++) {
|
||||||
|
- if (!ConvexPartition_HM(&(*iter), parts)) {
|
||||||
|
+ for (iter = outpolys.front(); iter; iter = iter->next()) {
|
||||||
|
+ if (!ConvexPartition_HM(&(iter->get()), parts)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -824,8 +821,8 @@ int TPPLPartition::Triangulate_OPT(TPPLPoly *poly, TPPLPolyList *triangles) {
|
||||||
|
newdiagonal.index1 = 0;
|
||||||
|
newdiagonal.index2 = n - 1;
|
||||||
|
diagonals.push_back(newdiagonal);
|
||||||
|
- while (!diagonals.empty()) {
|
||||||
|
- diagonal = *(diagonals.begin());
|
||||||
|
+ while (!diagonals.is_empty()) {
|
||||||
|
+ diagonal = diagonals.front()->get();
|
||||||
|
diagonals.pop_front();
|
||||||
|
bestvertex = dpstates[diagonal.index2][diagonal.index1].bestvertex;
|
||||||
|
if (bestvertex == -1) {
|
||||||
|
@@ -873,10 +870,10 @@ void TPPLPartition::UpdateState(long a, long b, long w, long i, long j, DPState2
|
||||||
|
pairs->push_front(newdiagonal);
|
||||||
|
dpstates[a][b].weight = w;
|
||||||
|
} else {
|
||||||
|
- if ((!pairs->empty()) && (i <= pairs->begin()->index1)) {
|
||||||
|
+ if ((!pairs->is_empty()) && (i <= pairs->front()->get().index1)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
- while ((!pairs->empty()) && (pairs->begin()->index2 >= j)) {
|
||||||
|
+ while ((!pairs->is_empty()) && (pairs->front()->get().index2 >= j)) {
|
||||||
|
pairs->pop_front();
|
||||||
|
}
|
||||||
|
pairs->push_front(newdiagonal);
|
||||||
|
@@ -885,7 +882,7 @@ void TPPLPartition::UpdateState(long a, long b, long w, long i, long j, DPState2
|
||||||
|
|
||||||
|
void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) {
|
||||||
|
DiagonalList *pairs = NULL;
|
||||||
|
- DiagonalList::iterator iter, lastiter;
|
||||||
|
+ DiagonalList::Element *iter, *lastiter;
|
||||||
|
long top;
|
||||||
|
long w;
|
||||||
|
|
||||||
|
@@ -902,23 +899,23 @@ void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPS
|
||||||
|
}
|
||||||
|
if (j - i > 1) {
|
||||||
|
pairs = &(dpstates[i][j].pairs);
|
||||||
|
- iter = pairs->end();
|
||||||
|
- lastiter = pairs->end();
|
||||||
|
- while (iter != pairs->begin()) {
|
||||||
|
+ iter = pairs->back();
|
||||||
|
+ lastiter = pairs->back();
|
||||||
|
+ while (iter != pairs->front()) {
|
||||||
|
iter--;
|
||||||
|
- if (!IsReflex(vertices[iter->index2].p, vertices[j].p, vertices[k].p)) {
|
||||||
|
+ if (!IsReflex(vertices[iter->get().index2].p, vertices[j].p, vertices[k].p)) {
|
||||||
|
lastiter = iter;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- if (lastiter == pairs->end()) {
|
||||||
|
+ if (lastiter == pairs->back()) {
|
||||||
|
w++;
|
||||||
|
} else {
|
||||||
|
- if (IsReflex(vertices[k].p, vertices[i].p, vertices[lastiter->index1].p)) {
|
||||||
|
+ if (IsReflex(vertices[k].p, vertices[i].p, vertices[lastiter->get().index1].p)) {
|
||||||
|
w++;
|
||||||
|
} else {
|
||||||
|
- top = lastiter->index1;
|
||||||
|
+ top = lastiter->get().index1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -927,7 +924,7 @@ void TPPLPartition::TypeA(long i, long j, long k, PartitionVertex *vertices, DPS
|
||||||
|
|
||||||
|
void TPPLPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates) {
|
||||||
|
DiagonalList *pairs = NULL;
|
||||||
|
- DiagonalList::iterator iter, lastiter;
|
||||||
|
+ DiagonalList::Element *iter, *lastiter;
|
||||||
|
long top;
|
||||||
|
long w;
|
||||||
|
|
||||||
|
@@ -946,21 +943,21 @@ void TPPLPartition::TypeB(long i, long j, long k, PartitionVertex *vertices, DPS
|
||||||
|
if (k - j > 1) {
|
||||||
|
pairs = &(dpstates[j][k].pairs);
|
||||||
|
|
||||||
|
- iter = pairs->begin();
|
||||||
|
- if ((!pairs->empty()) && (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->index1].p))) {
|
||||||
|
+ iter = pairs->front();
|
||||||
|
+ if ((!pairs->is_empty()) && (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->get().index1].p))) {
|
||||||
|
lastiter = iter;
|
||||||
|
- while (iter != pairs->end()) {
|
||||||
|
- if (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->index1].p)) {
|
||||||
|
+ while (iter) {
|
||||||
|
+ if (!IsReflex(vertices[i].p, vertices[j].p, vertices[iter->get().index1].p)) {
|
||||||
|
lastiter = iter;
|
||||||
|
- iter++;
|
||||||
|
+ iter = iter->next();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
- if (IsReflex(vertices[lastiter->index2].p, vertices[k].p, vertices[i].p)) {
|
||||||
|
+ if (IsReflex(vertices[lastiter->get().index2].p, vertices[k].p, vertices[i].p)) {
|
||||||
|
w++;
|
||||||
|
} else {
|
||||||
|
- top = lastiter->index2;
|
||||||
|
+ top = lastiter->get().index2;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
w++;
|
||||||
|
@@ -981,11 +978,11 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
|
||||||
|
DiagonalList diagonals, diagonals2;
|
||||||
|
Diagonal diagonal, newdiagonal;
|
||||||
|
DiagonalList *pairs = NULL, *pairs2 = NULL;
|
||||||
|
- DiagonalList::iterator iter, iter2;
|
||||||
|
+ DiagonalList::Element *iter, *iter2;
|
||||||
|
int ret;
|
||||||
|
TPPLPoly newpoly;
|
||||||
|
- std::vector<long> indices;
|
||||||
|
- std::vector<long>::iterator iiter;
|
||||||
|
+ List<long> indices;
|
||||||
|
+ List<long>::Element *iiter;
|
||||||
|
bool ijreal, jkreal;
|
||||||
|
|
||||||
|
n = poly->GetNumPoints();
|
||||||
|
@@ -1110,35 +1107,35 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
|
||||||
|
newdiagonal.index1 = 0;
|
||||||
|
newdiagonal.index2 = n - 1;
|
||||||
|
diagonals.push_front(newdiagonal);
|
||||||
|
- while (!diagonals.empty()) {
|
||||||
|
- diagonal = *(diagonals.begin());
|
||||||
|
+ while (!diagonals.is_empty()) {
|
||||||
|
+ diagonal = diagonals.front()->get();
|
||||||
|
diagonals.pop_front();
|
||||||
|
if ((diagonal.index2 - diagonal.index1) <= 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
|
||||||
|
- if (pairs->empty()) {
|
||||||
|
+ if (pairs->is_empty()) {
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!vertices[diagonal.index1].isConvex) {
|
||||||
|
- iter = pairs->end();
|
||||||
|
+ iter = pairs->back();
|
||||||
|
iter--;
|
||||||
|
- j = iter->index2;
|
||||||
|
+ j = iter->get().index2;
|
||||||
|
newdiagonal.index1 = j;
|
||||||
|
newdiagonal.index2 = diagonal.index2;
|
||||||
|
diagonals.push_front(newdiagonal);
|
||||||
|
if ((j - diagonal.index1) > 1) {
|
||||||
|
- if (iter->index1 != iter->index2) {
|
||||||
|
+ if (iter->get().index1 != iter->get().index2) {
|
||||||
|
pairs2 = &(dpstates[diagonal.index1][j].pairs);
|
||||||
|
while (1) {
|
||||||
|
- if (pairs2->empty()) {
|
||||||
|
+ if (pairs2->is_empty()) {
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- iter2 = pairs2->end();
|
||||||
|
+ iter2 = pairs2->back();
|
||||||
|
iter2--;
|
||||||
|
- if (iter->index1 != iter2->index1) {
|
||||||
|
+ if (iter->get().index1 != iter2->get().index1) {
|
||||||
|
pairs2->pop_back();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
@@ -1153,21 +1150,21 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
|
||||||
|
diagonals.push_front(newdiagonal);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- iter = pairs->begin();
|
||||||
|
- j = iter->index1;
|
||||||
|
+ iter = pairs->front();
|
||||||
|
+ j = iter->get().index1;
|
||||||
|
newdiagonal.index1 = diagonal.index1;
|
||||||
|
newdiagonal.index2 = j;
|
||||||
|
diagonals.push_front(newdiagonal);
|
||||||
|
if ((diagonal.index2 - j) > 1) {
|
||||||
|
- if (iter->index1 != iter->index2) {
|
||||||
|
+ if (iter->get().index1 != iter->get().index2) {
|
||||||
|
pairs2 = &(dpstates[j][diagonal.index2].pairs);
|
||||||
|
while (1) {
|
||||||
|
- if (pairs2->empty()) {
|
||||||
|
+ if (pairs2->is_empty()) {
|
||||||
|
ret = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- iter2 = pairs2->begin();
|
||||||
|
- if (iter->index2 != iter2->index2) {
|
||||||
|
+ iter2 = pairs2->front();
|
||||||
|
+ if (iter->get().index2 != iter2->get().index2) {
|
||||||
|
pairs2->pop_front();
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
@@ -1197,8 +1194,8 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
|
||||||
|
newdiagonal.index1 = 0;
|
||||||
|
newdiagonal.index2 = n - 1;
|
||||||
|
diagonals.push_front(newdiagonal);
|
||||||
|
- while (!diagonals.empty()) {
|
||||||
|
- diagonal = *(diagonals.begin());
|
||||||
|
+ while (!diagonals.is_empty()) {
|
||||||
|
+ diagonal = diagonals.front()->get();
|
||||||
|
diagonals.pop_front();
|
||||||
|
if ((diagonal.index2 - diagonal.index1) <= 1) {
|
||||||
|
continue;
|
||||||
|
@@ -1210,8 +1207,8 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
|
||||||
|
indices.push_back(diagonal.index2);
|
||||||
|
diagonals2.push_front(diagonal);
|
||||||
|
|
||||||
|
- while (!diagonals2.empty()) {
|
||||||
|
- diagonal = *(diagonals2.begin());
|
||||||
|
+ while (!diagonals2.is_empty()) {
|
||||||
|
+ diagonal = diagonals2.front()->get();
|
||||||
|
diagonals2.pop_front();
|
||||||
|
if ((diagonal.index2 - diagonal.index1) <= 1) {
|
||||||
|
continue;
|
||||||
|
@@ -1220,16 +1217,16 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
|
||||||
|
jkreal = true;
|
||||||
|
pairs = &(dpstates[diagonal.index1][diagonal.index2].pairs);
|
||||||
|
if (!vertices[diagonal.index1].isConvex) {
|
||||||
|
- iter = pairs->end();
|
||||||
|
+ iter = pairs->back();
|
||||||
|
iter--;
|
||||||
|
- j = iter->index2;
|
||||||
|
- if (iter->index1 != iter->index2) {
|
||||||
|
+ j = iter->get().index2;
|
||||||
|
+ if (iter->get().index1 != iter->get().index2) {
|
||||||
|
ijreal = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
- iter = pairs->begin();
|
||||||
|
- j = iter->index1;
|
||||||
|
- if (iter->index1 != iter->index2) {
|
||||||
|
+ iter = pairs->front();
|
||||||
|
+ j = iter->get().index1;
|
||||||
|
+ if (iter->get().index1 != iter->get().index2) {
|
||||||
|
jkreal = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -1253,11 +1250,12 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
|
||||||
|
indices.push_back(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
- std::sort(indices.begin(), indices.end());
|
||||||
|
+ //std::sort(indices.begin(), indices.end());
|
||||||
|
+ indices.sort();
|
||||||
|
newpoly.Init((long)indices.size());
|
||||||
|
k = 0;
|
||||||
|
- for (iiter = indices.begin(); iiter != indices.end(); iiter++) {
|
||||||
|
- newpoly[k] = vertices[*iiter].p;
|
||||||
|
+ for (iiter = indices.front(); iiter != indices.back(); iiter = iiter->next()) {
|
||||||
|
+ newpoly[k] = vertices[iiter->get()].p;
|
||||||
|
k++;
|
||||||
|
}
|
||||||
|
parts->push_back(newpoly);
|
||||||
|
@@ -1281,7 +1279,7 @@ int TPPLPartition::ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts) {
|
||||||
|
// "Computational Geometry: Algorithms and Applications"
|
||||||
|
// by Mark de Berg, Otfried Cheong, Marc van Kreveld, and Mark Overmars.
|
||||||
|
int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monotonePolys) {
|
||||||
|
- TPPLPolyList::iterator iter;
|
||||||
|
+ TPPLPolyList::Element *iter;
|
||||||
|
MonotoneVertex *vertices = NULL;
|
||||||
|
long i, numvertices, vindex, vindex2, newnumvertices, maxnumvertices;
|
||||||
|
long polystartindex, polyendindex;
|
||||||
|
@@ -1291,11 +1289,8 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
|
||||||
|
bool error = false;
|
||||||
|
|
||||||
|
numvertices = 0;
|
||||||
|
- for (iter = inpolys->begin(); iter != inpolys->end(); iter++) {
|
||||||
|
- if (!iter->Valid()) {
|
||||||
|
- return 0;
|
||||||
|
- }
|
||||||
|
- numvertices += iter->GetNumPoints();
|
||||||
|
+ for (iter = inpolys->front(); iter; iter++) {
|
||||||
|
+ numvertices += iter->get().GetNumPoints();
|
||||||
|
}
|
||||||
|
|
||||||
|
maxnumvertices = numvertices * 3;
|
||||||
|
@@ -1303,8 +1298,8 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
|
||||||
|
newnumvertices = numvertices;
|
||||||
|
|
||||||
|
polystartindex = 0;
|
||||||
|
- for (iter = inpolys->begin(); iter != inpolys->end(); iter++) {
|
||||||
|
- poly = &(*iter);
|
||||||
|
+ for (iter = inpolys->front(); iter; iter++) {
|
||||||
|
+ poly = &(iter->get());
|
||||||
|
polyendindex = polystartindex + poly->GetNumPoints() - 1;
|
||||||
|
for (i = 0; i < poly->GetNumPoints(); i++) {
|
||||||
|
vertices[i + polystartindex].p = poly->GetPoint(i);
|
||||||
|
@@ -1360,14 +1355,14 @@ 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.
|
||||||
|
- std::set<ScanLineEdge> edgeTree;
|
||||||
|
+ Set<ScanLineEdge> edgeTree;
|
||||||
|
// Store iterators to the edge tree elements.
|
||||||
|
// This makes deleting existing edges much faster.
|
||||||
|
- std::set<ScanLineEdge>::iterator *edgeTreeIterators, edgeIter;
|
||||||
|
- edgeTreeIterators = new std::set<ScanLineEdge>::iterator[maxnumvertices];
|
||||||
|
- std::pair<std::set<ScanLineEdge>::iterator, bool> edgeTreeRet;
|
||||||
|
+ Set<ScanLineEdge>::Element **edgeTreeIterators, *edgeIter;
|
||||||
|
+ edgeTreeIterators = new Set<ScanLineEdge>::Element *[maxnumvertices];
|
||||||
|
+ //Pair<Set<ScanLineEdge>::iterator, bool> edgeTreeRet;
|
||||||
|
for (i = 0; i < numvertices; i++) {
|
||||||
|
- edgeTreeIterators[i] = edgeTree.end();
|
||||||
|
+ edgeTreeIterators[i] = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For each vertex.
|
||||||
|
@@ -1387,13 +1382,14 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
|
||||||
|
newedge.p1 = v->p;
|
||||||
|
newedge.p2 = vertices[v->next].p;
|
||||||
|
newedge.index = vindex;
|
||||||
|
- edgeTreeRet = edgeTree.insert(newedge);
|
||||||
|
- edgeTreeIterators[vindex] = edgeTreeRet.first;
|
||||||
|
+ //edgeTreeRet = edgeTree.insert(newedge);
|
||||||
|
+ //edgeTreeIterators[vindex] = edgeTreeRet.first;
|
||||||
|
+ edgeTreeIterators[vindex] = edgeTree.insert(newedge);
|
||||||
|
helpers[vindex] = vindex;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TPPL_VERTEXTYPE_END:
|
||||||
|
- if (edgeTreeIterators[v->previous] == edgeTree.end()) {
|
||||||
|
+ if (edgeTreeIterators[v->previous] == edgeTree.back()) {
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -1412,29 +1408,30 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
|
||||||
|
newedge.p1 = v->p;
|
||||||
|
newedge.p2 = v->p;
|
||||||
|
edgeIter = edgeTree.lower_bound(newedge);
|
||||||
|
- if (edgeIter == edgeTree.begin()) {
|
||||||
|
+ if (edgeIter == edgeTree.front()) {
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
edgeIter--;
|
||||||
|
// Insert the diagonal connecting vi to helper(e_j) in D.
|
||||||
|
- AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->index],
|
||||||
|
+ AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->get().index],
|
||||||
|
vertextypes, edgeTreeIterators, &edgeTree, helpers);
|
||||||
|
vindex2 = newnumvertices - 2;
|
||||||
|
v2 = &(vertices[vindex2]);
|
||||||
|
// helper(e_j) in v_i.
|
||||||
|
- helpers[edgeIter->index] = vindex;
|
||||||
|
+ helpers[edgeIter->get().index] = vindex;
|
||||||
|
// Insert e_i in T and set helper(e_i) to v_i.
|
||||||
|
newedge.p1 = v2->p;
|
||||||
|
newedge.p2 = vertices[v2->next].p;
|
||||||
|
newedge.index = vindex2;
|
||||||
|
- edgeTreeRet = edgeTree.insert(newedge);
|
||||||
|
- edgeTreeIterators[vindex2] = edgeTreeRet.first;
|
||||||
|
+ //edgeTreeRet = edgeTree.insert(newedge);
|
||||||
|
+ //edgeTreeIterators[vindex2] = edgeTreeRet.first;
|
||||||
|
+ edgeTreeIterators[vindex2] = edgeTree.insert(newedge);
|
||||||
|
helpers[vindex2] = vindex2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TPPL_VERTEXTYPE_MERGE:
|
||||||
|
- if (edgeTreeIterators[v->previous] == edgeTree.end()) {
|
||||||
|
+ if (edgeTreeIterators[v->previous] == edgeTree.back()) {
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -1452,25 +1449,25 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
|
||||||
|
newedge.p1 = v->p;
|
||||||
|
newedge.p2 = v->p;
|
||||||
|
edgeIter = edgeTree.lower_bound(newedge);
|
||||||
|
- if (edgeIter == edgeTree.begin()) {
|
||||||
|
+ if (edgeIter == edgeTree.front()) {
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
edgeIter--;
|
||||||
|
// If helper(e_j) is a merge vertex.
|
||||||
|
- if (vertextypes[helpers[edgeIter->index]] == TPPL_VERTEXTYPE_MERGE) {
|
||||||
|
+ if (vertextypes[helpers[edgeIter->get().index]] == TPPL_VERTEXTYPE_MERGE) {
|
||||||
|
// Insert the diagonal connecting v_i to helper(e_j) in D.
|
||||||
|
- AddDiagonal(vertices, &newnumvertices, vindex2, helpers[edgeIter->index],
|
||||||
|
+ AddDiagonal(vertices, &newnumvertices, vindex2, helpers[edgeIter->get().index],
|
||||||
|
vertextypes, edgeTreeIterators, &edgeTree, helpers);
|
||||||
|
}
|
||||||
|
// helper(e_j) <- v_i
|
||||||
|
- helpers[edgeIter->index] = vindex2;
|
||||||
|
+ helpers[edgeIter->get().index] = vindex2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TPPL_VERTEXTYPE_REGULAR:
|
||||||
|
// If the interior of P lies to the right of v_i.
|
||||||
|
if (Below(v->p, vertices[v->previous].p)) {
|
||||||
|
- if (edgeTreeIterators[v->previous] == edgeTree.end()) {
|
||||||
|
+ if (edgeTreeIterators[v->previous] == edgeTree.back()) {
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -1488,27 +1485,28 @@ int TPPLPartition::MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monoto
|
||||||
|
newedge.p1 = v2->p;
|
||||||
|
newedge.p2 = vertices[v2->next].p;
|
||||||
|
newedge.index = vindex2;
|
||||||
|
- edgeTreeRet = edgeTree.insert(newedge);
|
||||||
|
- edgeTreeIterators[vindex2] = edgeTreeRet.first;
|
||||||
|
+ //edgeTreeRet = edgeTree.insert(newedge);
|
||||||
|
+ //edgeTreeIterators[vindex2] = edgeTreeRet.first;
|
||||||
|
+ edgeTreeIterators[vindex2] = edgeTree.insert(newedge);
|
||||||
|
helpers[vindex2] = vindex;
|
||||||
|
} else {
|
||||||
|
// Search in T to find the edge e_j directly left of v_i.
|
||||||
|
newedge.p1 = v->p;
|
||||||
|
newedge.p2 = v->p;
|
||||||
|
edgeIter = edgeTree.lower_bound(newedge);
|
||||||
|
- if (edgeIter == edgeTree.begin()) {
|
||||||
|
+ if (edgeIter == edgeTree.front()) {
|
||||||
|
error = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
- edgeIter--;
|
||||||
|
+ edgeIter = edgeIter->prev();
|
||||||
|
// If helper(e_j) is a merge vertex.
|
||||||
|
- if (vertextypes[helpers[edgeIter->index]] == TPPL_VERTEXTYPE_MERGE) {
|
||||||
|
+ if (vertextypes[helpers[edgeIter->get().index]] == TPPL_VERTEXTYPE_MERGE) {
|
||||||
|
// Insert the diagonal connecting v_i to helper(e_j) in D.
|
||||||
|
- AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->index],
|
||||||
|
+ AddDiagonal(vertices, &newnumvertices, vindex, helpers[edgeIter->get().index],
|
||||||
|
vertextypes, edgeTreeIterators, &edgeTree, helpers);
|
||||||
|
}
|
||||||
|
// helper(e_j) <- v_i.
|
||||||
|
- helpers[edgeIter->index] = vindex;
|
||||||
|
+ helpers[edgeIter->get().index] = vindex;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
@@ -1569,8 +1567,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,
|
||||||
|
- TPPLVertexType *vertextypes, std::set<ScanLineEdge>::iterator *edgeTreeIterators,
|
||||||
|
- std::set<ScanLineEdge> *edgeTree, long *helpers) {
|
||||||
|
+ TPPLVertexType *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators,
|
||||||
|
+ Set<ScanLineEdge> *edgeTree, long *helpers) {
|
||||||
|
long newindex1, newindex2;
|
||||||
|
|
||||||
|
newindex1 = *numvertices;
|
||||||
|
@@ -1597,14 +1595,14 @@ void TPPLPartition::AddDiagonal(MonotoneVertex *vertices, long *numvertices, lon
|
||||||
|
vertextypes[newindex1] = vertextypes[index1];
|
||||||
|
edgeTreeIterators[newindex1] = edgeTreeIterators[index1];
|
||||||
|
helpers[newindex1] = helpers[index1];
|
||||||
|
- if (edgeTreeIterators[newindex1] != edgeTree->end()) {
|
||||||
|
- edgeTreeIterators[newindex1]->index = newindex1;
|
||||||
|
+ if (edgeTreeIterators[newindex1] != edgeTree->back()) {
|
||||||
|
+ edgeTreeIterators[newindex1]->get().index = newindex1;
|
||||||
|
}
|
||||||
|
vertextypes[newindex2] = vertextypes[index2];
|
||||||
|
edgeTreeIterators[newindex2] = edgeTreeIterators[index2];
|
||||||
|
helpers[newindex2] = helpers[index2];
|
||||||
|
- if (edgeTreeIterators[newindex2] != edgeTree->end()) {
|
||||||
|
- edgeTreeIterators[newindex2]->index = newindex2;
|
||||||
|
+ if (edgeTreeIterators[newindex2] != edgeTree->back()) {
|
||||||
|
+ edgeTreeIterators[newindex2]->get().index = newindex2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -1830,13 +1828,13 @@ int TPPLPartition::TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles
|
||||||
|
|
||||||
|
int TPPLPartition::Triangulate_MONO(TPPLPolyList *inpolys, TPPLPolyList *triangles) {
|
||||||
|
TPPLPolyList monotone;
|
||||||
|
- TPPLPolyList::iterator iter;
|
||||||
|
+ TPPLPolyList::Element *iter;
|
||||||
|
|
||||||
|
if (!MonotonePartition(inpolys, &monotone)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
- for (iter = monotone.begin(); iter != monotone.end(); iter++) {
|
||||||
|
- if (!TriangulateMonotone(&(*iter), triangles)) {
|
||||||
|
+ for (iter = monotone.front(); iter; iter = iter->next()) {
|
||||||
|
+ if (!TriangulateMonotone(&(iter->get()), triangles)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
diff --git a/thirdparty/misc/polypartition.h b/thirdparty/misc/polypartition.h
|
||||||
|
index f163f5d2173f..b2d905a3ef76 100644
|
||||||
|
--- a/thirdparty/misc/polypartition.h
|
||||||
|
+++ b/thirdparty/misc/polypartition.h
|
||||||
|
@@ -24,8 +24,9 @@
|
||||||
|
#ifndef POLYPARTITION_H
|
||||||
|
#define POLYPARTITION_H
|
||||||
|
|
||||||
|
-#include <list>
|
||||||
|
-#include <set>
|
||||||
|
+#include "core/math/vector2.h"
|
||||||
|
+#include "core/templates/list.h"
|
||||||
|
+#include "core/templates/set.h"
|
||||||
|
|
||||||
|
typedef double tppl_float;
|
||||||
|
|
||||||
|
@@ -44,49 +45,7 @@ enum TPPLVertexType {
|
||||||
|
};
|
||||||
|
|
||||||
|
// 2D point structure.
|
||||||
|
-struct TPPLPoint {
|
||||||
|
- tppl_float x;
|
||||||
|
- tppl_float y;
|
||||||
|
- // User-specified vertex identifier. Note that this isn't used internally
|
||||||
|
- // by the library, but will be faithfully copied around.
|
||||||
|
- int id;
|
||||||
|
-
|
||||||
|
- TPPLPoint operator+(const TPPLPoint &p) const {
|
||||||
|
- TPPLPoint r;
|
||||||
|
- r.x = x + p.x;
|
||||||
|
- r.y = y + p.y;
|
||||||
|
- return r;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- TPPLPoint operator-(const TPPLPoint &p) const {
|
||||||
|
- TPPLPoint r;
|
||||||
|
- r.x = x - p.x;
|
||||||
|
- r.y = y - p.y;
|
||||||
|
- return r;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- TPPLPoint operator*(const tppl_float f) const {
|
||||||
|
- TPPLPoint r;
|
||||||
|
- r.x = x * f;
|
||||||
|
- r.y = y * f;
|
||||||
|
- return r;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- TPPLPoint operator/(const tppl_float f) const {
|
||||||
|
- TPPLPoint r;
|
||||||
|
- r.x = x / f;
|
||||||
|
- r.y = y / f;
|
||||||
|
- return r;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- bool operator==(const TPPLPoint &p) const {
|
||||||
|
- return ((x == p.x) && (y == p.y));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- bool operator!=(const TPPLPoint &p) const {
|
||||||
|
- return !((x == p.x) && (y == p.y));
|
||||||
|
- }
|
||||||
|
-};
|
||||||
|
+typedef Vector2 TPPLPoint;
|
||||||
|
|
||||||
|
// Polygon implemented as an array of points with a "hole" flag.
|
||||||
|
class TPPLPoly {
|
||||||
|
@@ -168,9 +127,9 @@ class TPPLPoly {
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef TPPL_ALLOCATOR
|
||||||
|
-typedef std::list<TPPLPoly, TPPL_ALLOCATOR(TPPLPoly)> TPPLPolyList;
|
||||||
|
+typedef List<TPPLPoly, TPPL_ALLOCATOR(TPPLPoly)> TPPLPolyList;
|
||||||
|
#else
|
||||||
|
-typedef std::list<TPPLPoly> TPPLPolyList;
|
||||||
|
+typedef List<TPPLPoly> TPPLPolyList;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class TPPLPartition {
|
||||||
|
@@ -209,9 +168,9 @@ public:
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef TPPL_ALLOCATOR
|
||||||
|
- typedef std::list<Diagonal, TPPL_ALLOCATOR(Diagonal)> DiagonalList;
|
||||||
|
+ typedef List<Diagonal, TPPL_ALLOCATOR(Diagonal)> DiagonalList;
|
||||||
|
#else
|
||||||
|
- typedef std::list<Diagonal> DiagonalList;
|
||||||
|
+ typedef List<Diagonal> DiagonalList;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Dynamic programming state for minimum-weight triangulation.
|
||||||
|
@@ -265,8 +224,8 @@ public:
|
||||||
|
// Helper functions for MonotonePartition.
|
||||||
|
bool Below(TPPLPoint &p1, TPPLPoint &p2);
|
||||||
|
void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
|
||||||
|
- TPPLVertexType *vertextypes, std::set<ScanLineEdge>::iterator *edgeTreeIterators,
|
||||||
|
- std::set<ScanLineEdge> *edgeTree, long *helpers);
|
||||||
|
+ TPPLVertexType *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators,
|
||||||
|
+ Set<ScanLineEdge> *edgeTree, long *helpers);
|
||||||
|
|
||||||
|
// Triangulates a monotone polygon, used in Triangulate_MONO.
|
||||||
|
int TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles);
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,378 @@
|
||||||
|
/*************************************************************************/
|
||||||
|
/* Copyright (c) 2011-2021 Ivan Fratric and contributors. */
|
||||||
|
/* */
|
||||||
|
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||||
|
/* a copy of this software and associated documentation files (the */
|
||||||
|
/* "Software"), to deal in the Software without restriction, including */
|
||||||
|
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||||
|
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||||
|
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||||
|
/* the following conditions: */
|
||||||
|
/* */
|
||||||
|
/* The above copyright notice and this permission notice shall be */
|
||||||
|
/* included in all copies or substantial portions of the Software. */
|
||||||
|
/* */
|
||||||
|
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||||
|
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||||
|
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
|
||||||
|
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||||
|
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||||
|
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||||
|
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||||
|
/*************************************************************************/
|
||||||
|
|
||||||
|
#ifndef POLYPARTITION_H
|
||||||
|
#define POLYPARTITION_H
|
||||||
|
|
||||||
|
#include "core/math/vector2.h"
|
||||||
|
#include "core/templates/list.h"
|
||||||
|
#include "core/templates/set.h"
|
||||||
|
|
||||||
|
typedef double tppl_float;
|
||||||
|
|
||||||
|
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.
|
||||||
|
typedef Vector2 TPPLPoint;
|
||||||
|
|
||||||
|
// Polygon implemented as an array of points with a "hole" flag.
|
||||||
|
class TPPLPoly {
|
||||||
|
protected:
|
||||||
|
TPPLPoint *points;
|
||||||
|
long numpoints;
|
||||||
|
bool hole;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Constructors and destructors.
|
||||||
|
TPPLPoly();
|
||||||
|
~TPPLPoly();
|
||||||
|
|
||||||
|
TPPLPoly(const TPPLPoly &src);
|
||||||
|
TPPLPoly &operator=(const TPPLPoly &src);
|
||||||
|
|
||||||
|
// Getters and setters.
|
||||||
|
long GetNumPoints() const {
|
||||||
|
return numpoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsHole() const {
|
||||||
|
return hole;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetHole(bool hole) {
|
||||||
|
this->hole = hole;
|
||||||
|
}
|
||||||
|
|
||||||
|
TPPLPoint &GetPoint(long i) {
|
||||||
|
return points[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
const TPPLPoint &GetPoint(long i) const {
|
||||||
|
return points[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
TPPLPoint *GetPoints() {
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
TPPLPoint &operator[](int i) {
|
||||||
|
return points[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
const TPPLPoint &operator[](int i) const {
|
||||||
|
return points[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clears the polygon points.
|
||||||
|
void Clear();
|
||||||
|
|
||||||
|
// Inits the polygon with numpoints vertices.
|
||||||
|
void Init(long numpoints);
|
||||||
|
|
||||||
|
// Creates a triangle with points p1, p2, and p3.
|
||||||
|
void Triangle(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3);
|
||||||
|
|
||||||
|
// Inverts the orfer of vertices.
|
||||||
|
void Invert();
|
||||||
|
|
||||||
|
// Returns the orientation of the polygon.
|
||||||
|
// Possible values:
|
||||||
|
// 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_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; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef TPPL_ALLOCATOR
|
||||||
|
typedef List<TPPLPoly, TPPL_ALLOCATOR(TPPLPoly)> TPPLPolyList;
|
||||||
|
#else
|
||||||
|
typedef List<TPPLPoly> TPPLPolyList;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class TPPLPartition {
|
||||||
|
protected:
|
||||||
|
struct PartitionVertex {
|
||||||
|
bool isActive;
|
||||||
|
bool isConvex;
|
||||||
|
bool isEar;
|
||||||
|
|
||||||
|
TPPLPoint p;
|
||||||
|
tppl_float angle;
|
||||||
|
PartitionVertex *previous;
|
||||||
|
PartitionVertex *next;
|
||||||
|
|
||||||
|
PartitionVertex();
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MonotoneVertex {
|
||||||
|
TPPLPoint p;
|
||||||
|
long previous;
|
||||||
|
long next;
|
||||||
|
};
|
||||||
|
|
||||||
|
class VertexSorter {
|
||||||
|
MonotoneVertex *vertices;
|
||||||
|
|
||||||
|
public:
|
||||||
|
VertexSorter(MonotoneVertex *v) :
|
||||||
|
vertices(v) {}
|
||||||
|
bool operator()(long index1, long index2);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Diagonal {
|
||||||
|
long index1;
|
||||||
|
long index2;
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef TPPL_ALLOCATOR
|
||||||
|
typedef List<Diagonal, TPPL_ALLOCATOR(Diagonal)> DiagonalList;
|
||||||
|
#else
|
||||||
|
typedef List<Diagonal> DiagonalList;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Dynamic programming state for minimum-weight triangulation.
|
||||||
|
struct DPState {
|
||||||
|
bool visible;
|
||||||
|
tppl_float weight;
|
||||||
|
long bestvertex;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Dynamic programming state for convex partitioning.
|
||||||
|
struct DPState2 {
|
||||||
|
bool visible;
|
||||||
|
long weight;
|
||||||
|
DiagonalList pairs;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Edge that intersects the scanline.
|
||||||
|
struct ScanLineEdge {
|
||||||
|
mutable long index;
|
||||||
|
TPPLPoint p1;
|
||||||
|
TPPLPoint p2;
|
||||||
|
|
||||||
|
// Determines if the edge is to the left of another edge.
|
||||||
|
bool operator<(const ScanLineEdge &other) const;
|
||||||
|
|
||||||
|
bool IsConvex(const TPPLPoint &p1, const TPPLPoint &p2, const TPPLPoint &p3) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Standard helper functions.
|
||||||
|
bool IsConvex(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3);
|
||||||
|
bool IsReflex(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3);
|
||||||
|
bool IsInside(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p);
|
||||||
|
|
||||||
|
bool InCone(TPPLPoint &p1, TPPLPoint &p2, TPPLPoint &p3, TPPLPoint &p);
|
||||||
|
bool InCone(PartitionVertex *v, TPPLPoint &p);
|
||||||
|
|
||||||
|
int Intersects(TPPLPoint &p11, TPPLPoint &p12, TPPLPoint &p21, TPPLPoint &p22);
|
||||||
|
|
||||||
|
TPPLPoint Normalize(const TPPLPoint &p);
|
||||||
|
tppl_float Distance(const TPPLPoint &p1, const TPPLPoint &p2);
|
||||||
|
|
||||||
|
// Helper functions for Triangulate_EC.
|
||||||
|
void UpdateVertexReflexity(PartitionVertex *v);
|
||||||
|
void UpdateVertex(PartitionVertex *v, PartitionVertex *vertices, long numvertices);
|
||||||
|
|
||||||
|
// Helper functions for ConvexPartition_OPT.
|
||||||
|
void UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates);
|
||||||
|
void TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
|
||||||
|
void TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
|
||||||
|
|
||||||
|
// Helper functions for MonotonePartition.
|
||||||
|
bool Below(TPPLPoint &p1, TPPLPoint &p2);
|
||||||
|
void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
|
||||||
|
TPPLVertexType *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators,
|
||||||
|
Set<ScanLineEdge> *edgeTree, long *helpers);
|
||||||
|
|
||||||
|
// Triangulates a monotone polygon, used in Triangulate_MONO.
|
||||||
|
int TriangulateMonotone(TPPLPoly *inPoly, TPPLPolyList *triangles);
|
||||||
|
|
||||||
|
public:
|
||||||
|
// Simple heuristic procedure for removing holes from a list of polygons.
|
||||||
|
// It works by creating a diagonal from the right-most hole vertex
|
||||||
|
// to some other visible vertex.
|
||||||
|
// Time complexity: O(h*(n^2)), h is the # of holes, n is the # of vertices.
|
||||||
|
// Space complexity: O(n)
|
||||||
|
// params:
|
||||||
|
// inpolys:
|
||||||
|
// A list of polygons that can contain holes.
|
||||||
|
// Vertices of all non-hole polys have to be in counter-clockwise order.
|
||||||
|
// Vertices of all hole polys have to be in clockwise order.
|
||||||
|
// outpolys:
|
||||||
|
// A list of polygons without holes.
|
||||||
|
// Returns 1 on success, 0 on failure.
|
||||||
|
int RemoveHoles(TPPLPolyList *inpolys, TPPLPolyList *outpolys);
|
||||||
|
|
||||||
|
// Triangulates a polygon by ear clipping.
|
||||||
|
// Time complexity: O(n^2), n is the number of vertices.
|
||||||
|
// Space complexity: O(n)
|
||||||
|
// params:
|
||||||
|
// poly:
|
||||||
|
// An input polygon to be triangulated.
|
||||||
|
// Vertices have to be in counter-clockwise order.
|
||||||
|
// triangles:
|
||||||
|
// A list of triangles (result).
|
||||||
|
// Returns 1 on success, 0 on failure.
|
||||||
|
int Triangulate_EC(TPPLPoly *poly, TPPLPolyList *triangles);
|
||||||
|
|
||||||
|
// Triangulates a list of polygons that may contain holes by ear clipping
|
||||||
|
// algorithm. It first calls RemoveHoles to get rid of the holes, and then
|
||||||
|
// calls Triangulate_EC for each resulting polygon.
|
||||||
|
// Time complexity: O(h*(n^2)), h is the # of holes, n is the # of vertices.
|
||||||
|
// Space complexity: O(n)
|
||||||
|
// params:
|
||||||
|
// inpolys:
|
||||||
|
// A list of polygons to be triangulated (can contain holes).
|
||||||
|
// Vertices of all non-hole polys have to be in counter-clockwise order.
|
||||||
|
// Vertices of all hole polys have to be in clockwise order.
|
||||||
|
// triangles:
|
||||||
|
// A list of triangles (result).
|
||||||
|
// Returns 1 on success, 0 on failure.
|
||||||
|
int Triangulate_EC(TPPLPolyList *inpolys, TPPLPolyList *triangles);
|
||||||
|
|
||||||
|
// Creates an optimal polygon triangulation in terms of minimal edge length.
|
||||||
|
// Time complexity: O(n^3), n is the number of vertices
|
||||||
|
// Space complexity: O(n^2)
|
||||||
|
// params:
|
||||||
|
// poly:
|
||||||
|
// An input polygon to be triangulated.
|
||||||
|
// Vertices have to be in counter-clockwise order.
|
||||||
|
// triangles:
|
||||||
|
// A list of triangles (result).
|
||||||
|
// Returns 1 on success, 0 on failure.
|
||||||
|
int Triangulate_OPT(TPPLPoly *poly, TPPLPolyList *triangles);
|
||||||
|
|
||||||
|
// Triangulates a polygon by first partitioning it into monotone polygons.
|
||||||
|
// Time complexity: O(n*log(n)), n is the number of vertices.
|
||||||
|
// Space complexity: O(n)
|
||||||
|
// params:
|
||||||
|
// poly:
|
||||||
|
// An input polygon to be triangulated.
|
||||||
|
// Vertices have to be in counter-clockwise order.
|
||||||
|
// triangles:
|
||||||
|
// A list of triangles (result).
|
||||||
|
// Returns 1 on success, 0 on failure.
|
||||||
|
int Triangulate_MONO(TPPLPoly *poly, TPPLPolyList *triangles);
|
||||||
|
|
||||||
|
// Triangulates a list of polygons by first
|
||||||
|
// partitioning them into monotone polygons.
|
||||||
|
// Time complexity: O(n*log(n)), n is the number of vertices.
|
||||||
|
// Space complexity: O(n)
|
||||||
|
// params:
|
||||||
|
// inpolys:
|
||||||
|
// A list of polygons to be triangulated (can contain holes).
|
||||||
|
// Vertices of all non-hole polys have to be in counter-clockwise order.
|
||||||
|
// Vertices of all hole polys have to be in clockwise order.
|
||||||
|
// triangles:
|
||||||
|
// A list of triangles (result).
|
||||||
|
// Returns 1 on success, 0 on failure.
|
||||||
|
int Triangulate_MONO(TPPLPolyList *inpolys, TPPLPolyList *triangles);
|
||||||
|
|
||||||
|
// Creates a monotone partition of a list of polygons that
|
||||||
|
// can contain holes. Triangulates a set of polygons by
|
||||||
|
// first partitioning them into monotone polygons.
|
||||||
|
// Time complexity: O(n*log(n)), n is the number of vertices.
|
||||||
|
// Space complexity: O(n)
|
||||||
|
// params:
|
||||||
|
// inpolys:
|
||||||
|
// A list of polygons to be triangulated (can contain holes).
|
||||||
|
// Vertices of all non-hole polys have to be in counter-clockwise order.
|
||||||
|
// Vertices of all hole polys have to be in clockwise order.
|
||||||
|
// monotonePolys:
|
||||||
|
// A list of monotone polygons (result).
|
||||||
|
// Returns 1 on success, 0 on failure.
|
||||||
|
int MonotonePartition(TPPLPolyList *inpolys, TPPLPolyList *monotonePolys);
|
||||||
|
|
||||||
|
// Partitions a polygon into convex polygons by using the
|
||||||
|
// Hertel-Mehlhorn algorithm. The algorithm gives at most four times
|
||||||
|
// the number of parts as the optimal algorithm, however, in practice
|
||||||
|
// it works much better than that and often gives optimal partition.
|
||||||
|
// It uses triangulation obtained by ear clipping as intermediate result.
|
||||||
|
// Time complexity O(n^2), n is the number of vertices.
|
||||||
|
// Space complexity: O(n)
|
||||||
|
// params:
|
||||||
|
// poly:
|
||||||
|
// An input polygon to be partitioned.
|
||||||
|
// Vertices have to be in counter-clockwise order.
|
||||||
|
// parts:
|
||||||
|
// Resulting list of convex polygons.
|
||||||
|
// Returns 1 on success, 0 on failure.
|
||||||
|
int ConvexPartition_HM(TPPLPoly *poly, TPPLPolyList *parts);
|
||||||
|
|
||||||
|
// Partitions a list of polygons into convex parts by using the
|
||||||
|
// Hertel-Mehlhorn algorithm. The algorithm gives at most four times
|
||||||
|
// the number of parts as the optimal algorithm, however, in practice
|
||||||
|
// it works much better than that and often gives optimal partition.
|
||||||
|
// It uses triangulation obtained by ear clipping as intermediate result.
|
||||||
|
// Time complexity O(n^2), n is the number of vertices.
|
||||||
|
// Space complexity: O(n)
|
||||||
|
// params:
|
||||||
|
// inpolys:
|
||||||
|
// An input list of polygons to be partitioned. Vertices of
|
||||||
|
// all non-hole polys have to be in counter-clockwise order.
|
||||||
|
// Vertices of all hole polys have to be in clockwise order.
|
||||||
|
// parts:
|
||||||
|
// Resulting list of convex polygons.
|
||||||
|
// Returns 1 on success, 0 on failure.
|
||||||
|
int ConvexPartition_HM(TPPLPolyList *inpolys, TPPLPolyList *parts);
|
||||||
|
|
||||||
|
// Optimal convex partitioning (in terms of number of resulting
|
||||||
|
// convex polygons) using the Keil-Snoeyink algorithm.
|
||||||
|
// For reference, see M. Keil, J. Snoeyink, "On the time bound for
|
||||||
|
// convex decomposition of simple polygons", 1998.
|
||||||
|
// Time complexity O(n^3), n is the number of vertices.
|
||||||
|
// Space complexity: O(n^3)
|
||||||
|
// params:
|
||||||
|
// poly:
|
||||||
|
// An input polygon to be partitioned.
|
||||||
|
// Vertices have to be in counter-clockwise order.
|
||||||
|
// parts:
|
||||||
|
// Resulting list of convex polygons.
|
||||||
|
// Returns 1 on success, 0 on failure.
|
||||||
|
int ConvexPartition_OPT(TPPLPoly *poly, TPPLPolyList *parts);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,306 +0,0 @@
|
||||||
//Copyright (C) 2011 by Ivan Fratric
|
|
||||||
//
|
|
||||||
//Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
//of this software and associated documentation files (the "Software"), to deal
|
|
||||||
//in the Software without restriction, including without limitation the rights
|
|
||||||
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
//copies of the Software, and to permit persons to whom the Software is
|
|
||||||
//furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
//The above copyright notice and this permission notice shall be included in
|
|
||||||
//all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
//THE SOFTWARE.
|
|
||||||
|
|
||||||
#ifndef TRIANGULATOR_H
|
|
||||||
#define TRIANGULATOR_H
|
|
||||||
|
|
||||||
#include "core/templates/list.h"
|
|
||||||
#include "core/math/vector2.h"
|
|
||||||
#include "core/templates/set.h"
|
|
||||||
|
|
||||||
//2D point structure
|
|
||||||
|
|
||||||
#define TRIANGULATOR_CCW 1
|
|
||||||
#define TRIANGULATOR_CW -1
|
|
||||||
//Polygon implemented as an array of points with a 'hole' flag
|
|
||||||
class TriangulatorPoly {
|
|
||||||
protected:
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Vector2 *points;
|
|
||||||
long numpoints;
|
|
||||||
bool hole;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//constructors/destructors
|
|
||||||
TriangulatorPoly();
|
|
||||||
~TriangulatorPoly();
|
|
||||||
|
|
||||||
TriangulatorPoly(const TriangulatorPoly &src);
|
|
||||||
TriangulatorPoly& operator=(const TriangulatorPoly &src);
|
|
||||||
|
|
||||||
//getters and setters
|
|
||||||
long GetNumPoints() {
|
|
||||||
return numpoints;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsHole() {
|
|
||||||
return hole;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetHole(bool hole) {
|
|
||||||
this->hole = hole;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 &GetPoint(long i) {
|
|
||||||
return points[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2 *GetPoints() {
|
|
||||||
return points;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector2& operator[] (int i) {
|
|
||||||
return points[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
//clears the polygon points
|
|
||||||
void Clear();
|
|
||||||
|
|
||||||
//inits the polygon with numpoints vertices
|
|
||||||
void Init(long numpoints);
|
|
||||||
|
|
||||||
//creates a triangle with points p1,p2,p3
|
|
||||||
void Triangle(Vector2 &p1, Vector2 &p2, Vector2 &p3);
|
|
||||||
|
|
||||||
//inverts the orfer of vertices
|
|
||||||
void Invert();
|
|
||||||
|
|
||||||
//returns the orientation of the polygon
|
|
||||||
//possible values:
|
|
||||||
// Triangulator_CCW : polygon vertices are in counter-clockwise order
|
|
||||||
// Triangulator_CW : polygon vertices are in clockwise order
|
|
||||||
// 0 : the polygon has no (measurable) area
|
|
||||||
int GetOrientation();
|
|
||||||
|
|
||||||
//sets the polygon orientation
|
|
||||||
//orientation can be
|
|
||||||
// Triangulator_CCW : sets vertices in counter-clockwise order
|
|
||||||
// Triangulator_CW : sets vertices in clockwise order
|
|
||||||
void SetOrientation(int orientation);
|
|
||||||
};
|
|
||||||
|
|
||||||
class TriangulatorPartition {
|
|
||||||
protected:
|
|
||||||
struct PartitionVertex {
|
|
||||||
bool isActive;
|
|
||||||
bool isConvex;
|
|
||||||
bool isEar;
|
|
||||||
|
|
||||||
Vector2 p;
|
|
||||||
real_t angle;
|
|
||||||
PartitionVertex *previous;
|
|
||||||
PartitionVertex *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MonotoneVertex {
|
|
||||||
Vector2 p;
|
|
||||||
long previous;
|
|
||||||
long next;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct VertexSorter{
|
|
||||||
mutable MonotoneVertex *vertices;
|
|
||||||
bool operator() (long index1, long index2) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Diagonal {
|
|
||||||
long index1;
|
|
||||||
long index2;
|
|
||||||
};
|
|
||||||
|
|
||||||
//dynamic programming state for minimum-weight triangulation
|
|
||||||
struct DPState {
|
|
||||||
bool visible;
|
|
||||||
real_t weight;
|
|
||||||
long bestvertex;
|
|
||||||
};
|
|
||||||
|
|
||||||
//dynamic programming state for convex partitioning
|
|
||||||
struct DPState2 {
|
|
||||||
bool visible;
|
|
||||||
long weight;
|
|
||||||
List<Diagonal> pairs;
|
|
||||||
};
|
|
||||||
|
|
||||||
//edge that intersects the scanline
|
|
||||||
struct ScanLineEdge {
|
|
||||||
mutable long index;
|
|
||||||
Vector2 p1;
|
|
||||||
Vector2 p2;
|
|
||||||
|
|
||||||
//determines if the edge is to the left of another edge
|
|
||||||
bool operator< (const ScanLineEdge & other) const;
|
|
||||||
|
|
||||||
bool IsConvex(const Vector2& p1, const Vector2& p2, const Vector2& p3) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
//standard helper functions
|
|
||||||
bool IsConvex(Vector2& p1, Vector2& p2, Vector2& p3);
|
|
||||||
bool IsReflex(Vector2& p1, Vector2& p2, Vector2& p3);
|
|
||||||
bool IsInside(Vector2& p1, Vector2& p2, Vector2& p3, Vector2 &p);
|
|
||||||
|
|
||||||
bool InCone(Vector2 &p1, Vector2 &p2, Vector2 &p3, Vector2 &p);
|
|
||||||
bool InCone(PartitionVertex *v, Vector2 &p);
|
|
||||||
|
|
||||||
int Intersects(Vector2 &p11, Vector2 &p12, Vector2 &p21, Vector2 &p22);
|
|
||||||
|
|
||||||
Vector2 Normalize(const Vector2 &p);
|
|
||||||
real_t Distance(const Vector2 &p1, const Vector2 &p2);
|
|
||||||
|
|
||||||
//helper functions for Triangulate_EC
|
|
||||||
void UpdateVertexReflexity(PartitionVertex *v);
|
|
||||||
void UpdateVertex(PartitionVertex *v,PartitionVertex *vertices, long numvertices);
|
|
||||||
|
|
||||||
//helper functions for ConvexPartition_OPT
|
|
||||||
void UpdateState(long a, long b, long w, long i, long j, DPState2 **dpstates);
|
|
||||||
void TypeA(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
|
|
||||||
void TypeB(long i, long j, long k, PartitionVertex *vertices, DPState2 **dpstates);
|
|
||||||
|
|
||||||
//helper functions for MonotonePartition
|
|
||||||
bool Below(Vector2 &p1, Vector2 &p2);
|
|
||||||
void AddDiagonal(MonotoneVertex *vertices, long *numvertices, long index1, long index2,
|
|
||||||
char *vertextypes, Set<ScanLineEdge>::Element **edgeTreeIterators,
|
|
||||||
Set<ScanLineEdge> *edgeTree, long *helpers);
|
|
||||||
|
|
||||||
//triangulates a monotone polygon, used in Triangulate_MONO
|
|
||||||
int TriangulateMonotone(TriangulatorPoly *inPoly, List<TriangulatorPoly> *triangles);
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
//simple heuristic procedure for removing holes from a list of polygons
|
|
||||||
//works by creating a diagonal from the rightmost hole vertex to some visible vertex
|
|
||||||
//time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices
|
|
||||||
//space complexity: O(n)
|
|
||||||
//params:
|
|
||||||
// inpolys : a list of polygons that can contain holes
|
|
||||||
// vertices of all non-hole polys have to be in counter-clockwise order
|
|
||||||
// vertices of all hole polys have to be in clockwise order
|
|
||||||
// outpolys : a list of polygons without holes
|
|
||||||
//returns 1 on success, 0 on failure
|
|
||||||
int RemoveHoles(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *outpolys);
|
|
||||||
|
|
||||||
//triangulates a polygon by ear clipping
|
|
||||||
//time complexity O(n^2), n is the number of vertices
|
|
||||||
//space complexity: O(n)
|
|
||||||
//params:
|
|
||||||
// poly : an input polygon to be triangulated
|
|
||||||
// vertices have to be in counter-clockwise order
|
|
||||||
// triangles : a list of triangles (result)
|
|
||||||
//returns 1 on success, 0 on failure
|
|
||||||
int Triangulate_EC(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles);
|
|
||||||
|
|
||||||
//triangulates a list of polygons that may contain holes by ear clipping algorithm
|
|
||||||
//first calls RemoveHoles to get rid of the holes, and then Triangulate_EC for each resulting polygon
|
|
||||||
//time complexity: O(h*(n^2)), h is the number of holes, n is the number of vertices
|
|
||||||
//space complexity: O(n)
|
|
||||||
//params:
|
|
||||||
// inpolys : a list of polygons to be triangulated (can contain holes)
|
|
||||||
// vertices of all non-hole polys have to be in counter-clockwise order
|
|
||||||
// vertices of all hole polys have to be in clockwise order
|
|
||||||
// triangles : a list of triangles (result)
|
|
||||||
//returns 1 on success, 0 on failure
|
|
||||||
int Triangulate_EC(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *triangles);
|
|
||||||
|
|
||||||
//creates an optimal polygon triangulation in terms of minimal edge length
|
|
||||||
//time complexity: O(n^3), n is the number of vertices
|
|
||||||
//space complexity: O(n^2)
|
|
||||||
//params:
|
|
||||||
// poly : an input polygon to be triangulated
|
|
||||||
// vertices have to be in counter-clockwise order
|
|
||||||
// triangles : a list of triangles (result)
|
|
||||||
//returns 1 on success, 0 on failure
|
|
||||||
int Triangulate_OPT(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles);
|
|
||||||
|
|
||||||
//triangulates a polygons by firstly partitioning it into monotone polygons
|
|
||||||
//time complexity: O(n*log(n)), n is the number of vertices
|
|
||||||
//space complexity: O(n)
|
|
||||||
//params:
|
|
||||||
// poly : an input polygon to be triangulated
|
|
||||||
// vertices have to be in counter-clockwise order
|
|
||||||
// triangles : a list of triangles (result)
|
|
||||||
//returns 1 on success, 0 on failure
|
|
||||||
int Triangulate_MONO(TriangulatorPoly *poly, List<TriangulatorPoly> *triangles);
|
|
||||||
|
|
||||||
//triangulates a list of polygons by firstly partitioning them into monotone polygons
|
|
||||||
//time complexity: O(n*log(n)), n is the number of vertices
|
|
||||||
//space complexity: O(n)
|
|
||||||
//params:
|
|
||||||
// inpolys : a list of polygons to be triangulated (can contain holes)
|
|
||||||
// vertices of all non-hole polys have to be in counter-clockwise order
|
|
||||||
// vertices of all hole polys have to be in clockwise order
|
|
||||||
// triangles : a list of triangles (result)
|
|
||||||
//returns 1 on success, 0 on failure
|
|
||||||
int Triangulate_MONO(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *triangles);
|
|
||||||
|
|
||||||
//creates a monotone partition of a list of polygons that can contain holes
|
|
||||||
//time complexity: O(n*log(n)), n is the number of vertices
|
|
||||||
//space complexity: O(n)
|
|
||||||
//params:
|
|
||||||
// inpolys : a list of polygons to be triangulated (can contain holes)
|
|
||||||
// vertices of all non-hole polys have to be in counter-clockwise order
|
|
||||||
// vertices of all hole polys have to be in clockwise order
|
|
||||||
// monotonePolys : a list of monotone polygons (result)
|
|
||||||
//returns 1 on success, 0 on failure
|
|
||||||
int MonotonePartition(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *monotonePolys);
|
|
||||||
|
|
||||||
//partitions a polygon into convex polygons by using Hertel-Mehlhorn algorithm
|
|
||||||
//the algorithm gives at most four times the number of parts as the optimal algorithm
|
|
||||||
//however, in practice it works much better than that and often gives optimal partition
|
|
||||||
//uses triangulation obtained by ear clipping as intermediate result
|
|
||||||
//time complexity O(n^2), n is the number of vertices
|
|
||||||
//space complexity: O(n)
|
|
||||||
//params:
|
|
||||||
// poly : an input polygon to be partitioned
|
|
||||||
// vertices have to be in counter-clockwise order
|
|
||||||
// parts : resulting list of convex polygons
|
|
||||||
//returns 1 on success, 0 on failure
|
|
||||||
int ConvexPartition_HM(TriangulatorPoly *poly, List<TriangulatorPoly> *parts);
|
|
||||||
|
|
||||||
//partitions a list of polygons into convex parts by using Hertel-Mehlhorn algorithm
|
|
||||||
//the algorithm gives at most four times the number of parts as the optimal algorithm
|
|
||||||
//however, in practice it works much better than that and often gives optimal partition
|
|
||||||
//uses triangulation obtained by ear clipping as intermediate result
|
|
||||||
//time complexity O(n^2), n is the number of vertices
|
|
||||||
//space complexity: O(n)
|
|
||||||
//params:
|
|
||||||
// inpolys : an input list of polygons to be partitioned
|
|
||||||
// vertices of all non-hole polys have to be in counter-clockwise order
|
|
||||||
// vertices of all hole polys have to be in clockwise order
|
|
||||||
// parts : resulting list of convex polygons
|
|
||||||
//returns 1 on success, 0 on failure
|
|
||||||
int ConvexPartition_HM(List<TriangulatorPoly> *inpolys, List<TriangulatorPoly> *parts);
|
|
||||||
|
|
||||||
//optimal convex partitioning (in terms of number of resulting convex polygons)
|
|
||||||
//using the Keil-Snoeyink algorithm
|
|
||||||
//M. Keil, J. Snoeyink, "On the time bound for convex decomposition of simple polygons", 1998
|
|
||||||
//time complexity O(n^3), n is the number of vertices
|
|
||||||
//space complexity: O(n^3)
|
|
||||||
// poly : an input polygon to be partitioned
|
|
||||||
// vertices have to be in counter-clockwise order
|
|
||||||
// parts : resulting list of convex polygons
|
|
||||||
//returns 1 on success, 0 on failure
|
|
||||||
int ConvexPartition_OPT(TriangulatorPoly *poly, List<TriangulatorPoly> *parts);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue