Git Product home page Git Product logo

earcut.hpp's Introduction

Earcut

A C++ port of earcut.js, a fast, header-only polygon triangulation library.

Travis AppVeyor Coverage Coverity Scan Average time to resolve an issue Percentage of issues still open Mourner

The library implements a modified ear slicing algorithm, optimized by z-order curve hashing and extended to handle holes, twisted polygons, degeneracies and self-intersections in a way that doesn't guarantee correctness of triangulation, but attempts to always produce acceptable results for practical data like geographical shapes.

It's based on ideas from FIST: Fast Industrial-Strength Triangulation of Polygons by Martin Held and Triangulation by Ear Clipping by David Eberly.

Usage

#include <earcut.hpp>
// The number type to use for tessellation
using Coord = double;

// The index type. Defaults to uint32_t, but you can also pass uint16_t if you know that your
// data won't have more than 65536 vertices.
using N = uint32_t;

// Create array
using Point = std::array<Coord, 2>;
std::vector<std::vector<Point>> polygon;

// Fill polygon structure with actual data. Any winding order works.
// The first polyline defines the main polygon.
polygon.push_back({{100, 0}, {100, 100}, {0, 100}, {0, 0}});
// Following polylines define holes.
polygon.push_back({{75, 25}, {75, 75}, {25, 75}, {25, 25}});

// Run tessellation
// Returns array of indices that refer to the vertices of the input polygon.
// e.g: the index 6 would refer to {25, 75} in this example.
// Three subsequent indices form a triangle. Output triangles are clockwise.
std::vector<N> indices = mapbox::earcut<N>(polygon);

Earcut can triangulate a simple, planar polygon of any winding order including holes. It will even return a robust, acceptable solution for non-simple poygons. Earcut works on a 2D plane. If you have three or more dimensions, you can project them onto a 2D surface before triangulation, or use a more suitable library for the task (e.g CGAL).

It is also possible to use your custom point type as input. There are default accessors defined for std::tuple, std::pair, and std::array. For a custom type (like Clipper's IntPoint type), do this:

// struct IntPoint {
//     int64_t X, Y;
// };

namespace mapbox {
namespace util {

template <>
struct nth<0, IntPoint> {
    inline static auto get(const IntPoint &t) {
        return t.X;
    };
};
template <>
struct nth<1, IntPoint> {
    inline static auto get(const IntPoint &t) {
        return t.Y;
    };
};

} // namespace util
} // namespace mapbox

You can also use a custom container type for your polygon. Similar to std::vector, it has to meet the requirements of Container, in particular size(), empty() and operator[].

example triangulation

Additional build instructions

In case you just want to use the earcut triangulation library; copy and include the header file <earcut.hpp> in your project and follow the steps documented in the section Usage.

If you want to build the test, benchmark and visualization programs instead, follow these instructions:

Dependencies

Before you continue, make sure to have the following tools and libraries installed:

Note: On some operating systems such as Windows, manual steps are required to add cmake and git to your PATH environment variable.

Manual compilation

git clone --recursive https://github.com/mapbox/earcut.hpp.git
cd earcut.hpp
mkdir build
cd build
cmake ..
make
# ./tests
# ./bench
# ./viz
git clone --recursive https://github.com/mapbox/earcut.hpp.git
cd earcut.hpp
mkdir project
cd project
cmake .. -G "Visual Studio 14 2015"
::you can also generate projects for "Visual Studio 12 2013", "XCode", "Eclipse CDT4 - Unix Makefiles"

After completion, open the generated project with your IDE.

Import the project from https://github.com/mapbox/earcut.hpp.git and you should be good to go!

Status

This is currently based on earcut 2.2.4.

earcut.hpp's People

Contributors

birkskyum avatar brunoabinader avatar dzen03 avatar gracicot avatar hjanetzek avatar jfirebaugh avatar kkaefer avatar mourner avatar mrgreywater avatar musicinmybrain avatar pboyer avatar springmeyer avatar tmcw avatar tmpsantos avatar tobrun avatar waldyrious avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

earcut.hpp's Issues

How to clip with an outside polygon

Hello.
Thank you for your excellent library. But I have a few questions as follows:

  • When I clip with a polygon inside the image that needs the clip, it works very well. (Image 2)
  • But if I clip with a polygon outside of the image that needs the clip, it happens to be wrong as illustrated above. (Image 3)
    (The area I want the clip to be green.)
    (The red area is the result after the clip.)
    I hope you understand what I mean, because I am not fluent in English.
    Thank you for your support.

Before Clip:
image

After Clip:
Clip Inside:
image
Clip Outside:
image

Infinite loop in cureLocalIntersections

The issue appears to be fairly simple (incorrect linked list pointers due to out of order items removal), but I'm not familiar with the code, so it might be something more serious. Patched version seem to produce correct-looking output, at least.

Diff (a PR seems rather excessive): diff.txt
And, one of the offending polygons: polygon.txt

Using custom Point class

I've tryed what the README says but the compiler keep saying:

Error C2988 unrecognizable template declaration/definition

Im compiling using VS2015
I have included my Vector2 class previously.
I am using this code:

namespace mapbox {

	namespace util {

		template <>
		struct nth<0, Vector2> {
			inline static auto get(const Vector2 &t) {
				return t.x;
			};
		};

		template <>
		struct nth<1, Vector2> {
			inline static auto get(const Vector2 &t) {
				return t.y;
			};
		};
	};
};

Thanks

[Question] Using custom std::vector<Point> class

In the documentation, there was an example of how to using a custom point class.

Is there an example that show cases a custom polygon class (i.e. std::vector)

My use case is that I have a flat array float* in memory. Which looks like this

float1, float2, float3, float4 ...
x0       y0       x1       y2

It would be great to be able to write a container class that accesses the underlying data rather than copying into a std::vector<Point>

bad tessellation in arctic ocean

As seen in mapbox/mapbox-gl-native#2444 (comment).

Minimized polygon:

{{{1500,0},{0,0},{0,1000},{1500,1000},{1500,0}},{{804,642},{814,644},{818,676},{850,690},{838,728},{806,728},{772,752},{748,746},{764,724},{728,726},{710,708},{738,656},{764,668},{784,700},{806,702},{792,666},{804,642}},{{1176,214},{1254,216},{1292,242},{1324,242},{1332,268},{1352,278},{1352,298},{1290,348},{1290,358},{1312,350},{1314,362},{1266,416},{1240,474},{1182,500},{1200,510},{1200,520},{1186,520},{1200,544},{1186,580},{1160,584},{1162,606},{1146,620},{1162,650},{1136,672},{1124,658},{1076,668},{1022,658},{1036,698},{1066,706},{1118,688},{1144,708},{1132,746},{1064,748},{1004,740},{990,668},{966,670},{946,648},{948,632},{962,628},{992,650},{1016,648},{1054,622},{1044,592},{1054,584},{1078,606},{1076,576},{1052,570},{1056,540},{1038,568},{1004,570},{976,526},{996,502},{958,496},{948,454},{962,454},{952,436},{964,390},{986,382},{974,368},{1004,376},{1018,420},{1052,434},{1060,482},{1078,490},{1062,472},{1062,442},{1104,450},{1104,436},{1142,422},{1154,402},{1110,424},{1046,416},{1022,388},{1022,344},{1002,344},{1018,318},{1060,308},{1076,272},{1104,288},{1122,246},{1140,230},{1168,234},{1176,214}},{{974,698},{986,738},{964,740},{952,714},{974,698}},{{842,596},{860,626},{848,622},{842,596}},{{798,572},{792,606},{768,614},{740,580},{758,586},{798,572}},{{892,584},{894,594},{882,588},{892,584}},{{870,500},{912,538},{922,586},{908,590},{894,568},{864,564},{854,550},{868,538},{846,520},{854,500},{870,500}}}

Earcut:

image

Libtess:

image

cc @mourner

Add github topics to description

Don't have the access to do it myself, so I'm opening an issue instead ;)
This might improve exposure and search results on google and other search engines.

Some suggestions, similar to earcut.js:
triangulation
tessellation
geometry
algorithm
rendering
vector graphics
polygon
header-only
cpp
c++11

Crash in Earcut::findHoleBridge

Hi,

Earcut::eliminateHoles contains the following loop:

    // process holes from left to right
    for (size_t i = 0; i < queue.size(); i++) {
        eliminateHole(queue[i], outerNode);
        outerNode = filterPoints(outerNode, outerNode->next);
    }

Earcut::filterPoints may return nullptr in case it reduces the polygon into a point, but findHoleBridge called by eliminateHole expects outerNode to be non-null, and crashes if filterPoints returns nullptr before the last iteration of the above for-loop on this line:

if (hy <= p->y && hy >= p->next->y && p->next->y != p->y) {

I've locally fixed/worked around the issue by modifying the loop condition in eliminateHoles as follows:

-    for (size_t i = 0; i < queue.size(); i++) {
+    for (size_t i = 0; i < queue.size() && outerNode; i++) {

and made similar modification to call-site of eliminateHoles to handle the nullptr case.

Is this the correct way around the issue?

Optimize Travis macOS builds

Build times for #79 on Travis:

image

The macOS builds take 5x more time, and most of that time is downloading and installing Ruby (regression after #77). Maybe we could avoid that step by ditching homebrew in favor of installing ccache some other way? @springmeyer

Destroy Node pointers

We're currently not destroying Node objects created during tessellation. This is of course a vast memory leak that we need to fix.

Readme outdated and erroneous

The usage in the readme is outdated, it took me some time to figure out what changed.

earcut.vertices doesn't exist anymore, instead the indices refer to the input polygon vector
https://github.com/mapbox/earcut.hpp/blame/master/README.md#L33

mapbox::Earcut<Coord, N> earcut; should be mapbox::Earcut<N> earcut; as Coord is automatically deduced
https://github.com/mapbox/earcut.hpp/blame/master/README.md#L21


template <>
struct nth<1, IntPoint> {
    inline static int64_t get(const IntPoint &t) {
        return t.X;
    };
};

should return t.Y;
https://github.com/mapbox/earcut.hpp/blame/master/README.md#L61

Incorrect triangulation of some letters, maybe wrong usage

Hello,

I started using your library for a triangulation of vector based font. I load the font via Qt functions and generate a path for every letter. Then I try to triangulate the points and render them as triangles with OpenGL.

  1. What is the correct way of specifying polygon with holes in it? What winding should I use and how does the coordinate system look (does it have reversed Y axis)? Does the library guarantee winding of output triangles and if so which one (CW, CCW, by experimenting it is CW) ? I could not find this information in the README and I think it would be very helpful.

  2. My problem is that some letters (d, e, g, q, B) are not triangulated correctly. For example letter e . Here is how I use earcut in my code. points is filled with points from the path desmos graph might be a little bit confusing due to reversed y axis in desmos and thus the winding looks also as it was different , the green ones are before content of points and the orange ones are points (triangle vertices) after triangulation. As you can see it removed/ignored quite a lot of points from that curve and I don' t know why. Should I define every polygon as separate vector and that's why it is not working or what might be the issue?

Thanks for any help :)

Code

std::vector<QPointF> TriangulatePolygon2(const std::vector<QPointF>& points) {
    using VertexIndexType = uint32_t;
    using Point2D = std::pair<double, double>;

    std::vector<Point2D> verticesToTransform;
    for (QPointF point : points) {
        verticesToTransform.push_back({point.x(), point.y()});
    }
    std::vector<VertexIndexType> trianglesIndices = mapbox::earcut<VertexIndexType>(std::vector<std::vector<Point2D>>{verticesToTransform});
    std::vector<QPointF> triangleVertices;
    for (size_t i = 0; i < trianglesIndices.size(); i += 3) {
        const QPointF pointI = points[trianglesIndices[i]];
        const QPointF pointI1 = points[trianglesIndices[i + 1]];
        const QPointF pointI2 = points[trianglesIndices[i + 2]];
        // reverse y axis coordinate, QT in 2D uses top down axis instead of right hand 3D coordinate system
        // correct counter clockwise order
        triangleVertices.push_back({pointI.x(), -pointI.y()});
        triangleVertices.push_back({pointI2.x(), -pointI2.y()});
        triangleVertices.push_back({pointI1.x(), -pointI1.y()});
    }

    return triangleVertices;
}

The order of points in the input vector. Red points are control points for bezier curves, thus the indexing.
image

Wrong rendering picture
image

Wrong rendering wireframe
image

Input points
(561.057617, -222.600586), (682.121094, -207.630371), (682.121094, -207.630371), (675.905200, -186.886860), (668.712988, -167.093633), (660.544458, -148.250688), (651.399609, -130.358027), (641.278442, -113.415649), (630.180957, -97.423555), (618.107153, -82.381743), (605.057031, -68.290215), (591.030591, -55.148970), (576.027832, -42.958008), (576.027832, -42.958008), (560.107334, -31.827979), (543.327676, -21.869531), (525.688857, -13.082666), (507.190879, -5.467383), (487.833740, 0.976318), (467.617441, 6.248438), (446.541982, 10.348975), (424.607363, 13.277930), (401.813584, 15.035303), (378.160645, 15.621094), (378.160645, 15.621094), (348.457786, 14.687083), (320.011123, 11.885049), (292.820657, 7.214993), (266.886387, 0.676914), (242.208313, -7.729187), (218.786436, -18.003311), (196.620754, -30.145457), (175.711270, -44.155625), (156.057981, -60.033816), (137.660889, -77.780029), (137.660889, -77.780029), (120.780344, -97.212019), (105.676699, -118.147539), (92.349954, -140.586589), (80.800107, -164.529170), (71.027161, -189.975281), (63.031113, -216.924922), (56.811965, -245.378093), (52.369717, -275.334795), (49.704368, -306.795027), (48.815918, -339.758789), (48.815918, -339.758789), (49.714131, -373.864844), (52.408770, -406.408789), (56.899834, -437.390625), (63.187324, -466.810352), (71.271240, -494.667969), (81.151582, -520.963477), (92.828350, -545.696875), (106.301543, -568.868164), (121.571162, -590.477344), (138.637207, -610.524414), (138.637207, -610.524414), (157.135186, -628.827129), (176.700605, -645.203242), (197.333467, -659.652754), (219.033770, -672.175664), (241.801514, -682.771973), (265.636699, -691.441680), (290.539326, -698.184785), (316.509395, -703.001289), (343.546904, -705.891191), (371.651855, -706.854492), (371.651855, -706.854492), (398.871611, -705.910718), (425.075996, -703.079395), (450.265010, -698.360522), (474.438652, -691.754102), (497.596924, -683.260132), (519.739824, -672.878613), (540.867354, -660.609546), (560.979512, -646.452930), (580.076299, -630.408765), (598.157715, -612.477051), (598.157715, -612.477051), (614.852759, -592.833525), (629.790430, -571.653926), (642.970728, -548.938252), (654.393652, -524.686504), (664.059204, -498.898682), (671.967383, -471.574785), (678.118188, -442.714814), (682.511621, -412.318770), (685.147681, -380.386650), (686.026367, -346.918457), (686.026367, -346.918457), (686.019858, -344.731504), (686.000332, -342.336270), (685.967788, -339.732754), (685.922227, -336.920957), (685.863647, -333.900879), (685.792051, -330.672520), (685.707437, -327.235879), (685.609805, -323.590957), (685.499155, -319.737754), (685.375488, -315.676270), (169.879395, -315.676270), (169.879395, -315.676270), (171.695347, -293.429229), (174.539688, -272.249629), (178.412417, -252.137471), (183.313535, -233.092754), (189.243042, -215.115479), (196.200938, -198.205645), (204.187222, -182.363252), (213.201895, -167.588301), (223.244956, -153.880791), (234.316406, -141.240723), (234.316406, -141.240723), (246.188437, -129.739692), (258.633242, -119.449297), (271.650820, -110.369536), (285.241172, -102.500410), (299.404297, -95.841919), (314.140195, -90.394063), (329.448867, -86.156841), (345.330312, -83.130254), (361.784531, -81.314302), (378.811523, -80.708984), (378.811523, -80.708984), (391.510171, -81.047441), (403.831309, -82.062813), (415.774937, -83.755098), (427.341055, -86.124297), (438.529663, -89.170410), (449.340762, -92.893438), (459.774351, -97.293379), (469.830430, -102.370234), (479.508999, -108.124004), (488.810059, -114.554688), (488.810059, -114.554688), (497.733608, -121.727373), (506.279648, -129.707148), (514.448179, -138.494014), (522.239199, -148.087969), (529.652710, -158.489014), (536.688711, -169.697148), (543.347202, -181.712373), (549.628184, -194.534688), (555.531655, -208.164092), (561.057617, -222.600586), (176.388184, -412.006348), (562.359375, -412.006348), (562.359375, -412.006348), (560.510879, -429.013813), (558.089609, -445.149102), (555.095566, -460.412212), (551.528750, -474.803145), (547.389160, -488.321899), (542.676797, -500.968477), (537.391660, -512.742876), (531.533750, -523.645098), (525.103066, -533.675142), (518.099609, -542.833008), (518.099609, -542.833008), (506.572544, -555.694375), (494.381582, -567.201914), (481.526724, -577.355625), (468.007969, -586.155508), (453.825317, -593.601562), (438.978770, -599.693789), (423.468325, -604.432188), (407.293984, -607.816758), (390.455747, -609.847500), (372.953613, -610.524414), (372.953613, -610.524414), (357.068914, -609.984185), (341.698408, -608.363496), (326.842097, -605.662349), (312.499980, -601.880742), (298.672058, -597.018677), (285.358330, -591.076152), (272.558796, -584.053169), (260.273457, -575.949727), (248.502312, -566.765825), (237.245361, -556.501465), (237.245361, -556.501465), (226.736921, -545.332383), (217.211309, -533.434316), (208.668523, -520.807266), (201.108564, -507.451230), (194.531433, -493.366211), (188.937129, -478.552207), (184.325652, -463.009219), (180.697002, -446.737246), (178.051179, -429.736289), (176.388184, -412.006348)

Triangle vertices from earcut
(675.905200, -186.886860), (660.544458, -148.250688), (668.712988, -167.093633), (660.544458, -148.250688), (641.278442, -113.415649), (651.399609, -130.358027), (641.278442, -113.415649), (618.107153, -82.381743), (630.180957, -97.423555), (618.107153, -82.381743), (591.030591, -55.148970), (605.057031, -68.290215), (560.107334, -31.827979), (525.688857, -13.082666), (543.327676, -21.869531), (525.688857, -13.082666), (487.833740, 0.976318), (507.190879, -5.467383), (487.833740, 0.976318), (446.541982, 10.348975), (467.617441, 6.248438), (446.541982, 10.348975), (401.813584, 15.035303), (424.607363, 13.277930), (348.457786, 14.687083), (292.820657, 7.214993), (320.011123, 11.885049), (292.820657, 7.214993), (242.208313, -7.729187), (266.886387, 0.676914), (242.208313, -7.729187), (196.620754, -30.145457), (218.786436, -18.003311), (196.620754, -30.145457), (156.057981, -60.033816), (175.711270, -44.155625), (120.780344, -97.212019), (92.349954, -140.586589), (105.676699, -118.147539), (92.349954, -140.586589), (71.027161, -189.975281), (80.800107, -164.529170), (71.027161, -189.975281), (56.811965, -245.378093), (63.031113, -216.924922), (56.811965, -245.378093), (49.704368, -306.795027), (52.369717, -275.334795), (49.714131, -373.864844), (56.899834, -437.390625), (52.408770, -406.408789), (56.899834, -437.390625), (71.271240, -494.667969), (63.187324, -466.810352), (71.271240, -494.667969), (92.828350, -545.696875), (81.151582, -520.963477), (92.828350, -545.696875), (121.571162, -590.477344), (106.301543, -568.868164), (157.135186, -628.827129), (197.333467, -659.652754), (176.700605, -645.203242), (197.333467, -659.652754), (241.801514, -682.771973), (219.033770, -672.175664), (241.801514, -682.771973), (290.539326, -698.184785), (265.636699, -691.441680), (290.539326, -698.184785), (343.546904, -705.891191), (316.509395, -703.001289), (398.871611, -705.910718), (450.265010, -698.360522), (425.075996, -703.079395), (450.265010, -698.360522), (497.596924, -683.260132), (474.438652, -691.754102), (497.596924, -683.260132), (540.867354, -660.609546), (519.739824, -672.878613), (540.867354, -660.609546), (580.076299, -630.408765), (560.979512, -646.452930), (614.852759, -592.833525), (642.970728, -548.938252), (629.790430, -571.653926), (642.970728, -548.938252), (664.059204, -498.898682), (654.393652, -524.686504), (664.059204, -498.898682), (678.118188, -442.714814), (671.967383, -471.574785), (678.118188, -442.714814), (685.147681, -380.386650), (682.511621, -412.318770), (686.019858, -344.731504), (685.967788, -339.732754), (686.000332, -342.336270), (685.967788, -339.732754), (685.863647, -333.900879), (685.922227, -336.920957), (685.863647, -333.900879), (685.707437, -327.235879), (685.792051, -330.672520), (685.707437, -327.235879), (685.499155, -319.737754), (685.609805, -323.590957), (675.905200, -186.886860), (641.278442, -113.415649), (660.544458, -148.250688), (641.278442, -113.415649), (591.030591, -55.148970), (618.107153, -82.381743), (560.107334, -31.827979), (487.833740, 0.976318), (525.688857, -13.082666), (487.833740, 0.976318), (401.813584, 15.035303), (446.541982, 10.348975), (348.457786, 14.687083), (242.208313, -7.729187), (292.820657, 7.214993), (242.208313, -7.729187), (156.057981, -60.033816), (196.620754, -30.145457), (120.780344, -97.212019), (71.027161, -189.975281), (92.349954, -140.586589), (71.027161, -189.975281), (49.704368, -306.795027), (56.811965, -245.378093), (49.714131, -373.864844), (71.271240, -494.667969), (56.899834, -437.390625), (71.271240, -494.667969), (121.571162, -590.477344), (92.828350, -545.696875), (157.135186, -628.827129), (241.801514, -682.771973), (197.333467, -659.652754), (241.801514, -682.771973), (343.546904, -705.891191), (290.539326, -698.184785), (398.871611, -705.910718), (497.596924, -683.260132), (450.265010, -698.360522), (497.596924, -683.260132), (580.076299, -630.408765), (540.867354, -660.609546), (614.852759, -592.833525), (664.059204, -498.898682), (642.970728, -548.938252), (664.059204, -498.898682), (685.147681, -380.386650), (678.118188, -442.714814), (686.019858, -344.731504), (685.863647, -333.900879), (685.967788, -339.732754), (685.863647, -333.900879), (685.499155, -319.737754), (685.707437, -327.235879), (675.905200, -186.886860), (591.030591, -55.148970), (641.278442, -113.415649), (560.107334, -31.827979), (401.813584, 15.035303), (487.833740, 0.976318), (348.457786, 14.687083), (156.057981, -60.033816), (242.208313, -7.729187), (120.780344, -97.212019), (49.704368, -306.795027), (71.027161, -189.975281), (49.714131, -373.864844), (121.571162, -590.477344), (71.271240, -494.667969), (157.135186, -628.827129), (343.546904, -705.891191), (241.801514, -682.771973), (398.871611, -705.910718), (580.076299, -630.408765), (497.596924, -683.260132), (614.852759, -592.833525), (685.147681, -380.386650), (664.059204, -498.898682), (686.019858, -344.731504), (685.499155, -319.737754), (685.863647, -333.900879), (686.019858, -344.731504), (685.375488, -315.676270), (685.499155, -319.737754), (614.852759, -592.833525), (686.026367, -346.918457), (685.147681, -380.386650), (686.026367, -346.918457), (685.375488, -315.676270), (686.019858, -344.731504), (682.121094, -207.630371), (591.030591, -55.148970), (675.905200, -186.886860), (591.030591, -55.148970), (560.107334, -31.827979), (576.027832, -42.958008), (560.107334, -31.827979), (378.160645, 15.621094), (401.813584, 15.035303), (378.160645, 15.621094), (156.057981, -60.033816), (348.457786, 14.687083), (156.057981, -60.033816), (120.780344, -97.212019), (137.660889, -77.780029), (120.780344, -97.212019), (48.815918, -339.758789), (49.704368, -306.795027), (48.815918, -339.758789), (121.571162, -590.477344), (49.714131, -373.864844), (121.571162, -590.477344), (157.135186, -628.827129), (138.637207, -610.524414), (157.135186, -628.827129), (371.651855, -706.854492), (343.546904, -705.891191), (371.651855, -706.854492), (580.076299, -630.408765), (398.871611, -705.910718), (580.076299, -630.408765), (614.852759, -592.833525), (598.157715, -612.477051), (614.852759, -592.833525), (685.375488, -315.676270), (686.026367, -346.918457), (682.121094, -207.630371), (560.107334, -31.827979), (591.030591, -55.148970), (560.107334, -31.827979), (156.057981, -60.033816), (378.160645, 15.621094), (156.057981, -60.033816), (48.815918, -339.758789), (120.780344, -97.212019), (48.815918, -339.758789), (157.135186, -628.827129), (121.571162, -590.477344), (157.135186, -628.827129), (580.076299, -630.408765), (371.651855, -706.854492), (580.076299, -630.408765), (685.375488, -315.676270), (614.852759, -592.833525), (156.057981, -60.033816), (157.135186, -628.827129), (48.815918, -339.758789), (580.076299, -630.408765), (560.510879, -429.013813), (562.359375, -412.006348), (561.057617, -222.600586), (560.107334, -31.827979), (682.121094, -207.630371), (580.076299, -630.408765), (558.089609, -445.149102), (560.510879, -429.013813), (176.388184, -412.006348), (560.107334, -31.827979), (561.057617, -222.600586), (580.076299, -630.408765), (555.095566, -460.412212), (558.089609, -445.149102), (176.388184, -412.006348), (156.057981, -60.033816), (560.107334, -31.827979), (580.076299, -630.408765), (551.528750, -474.803145), (555.095566, -460.412212), (176.388184, -412.006348), (157.135186, -628.827129), (156.057981, -60.033816), (580.076299, -630.408765), (547.389160, -488.321899), (551.528750, -474.803145), (178.051179, -429.736289), (157.135186, -628.827129), (176.388184, -412.006348), (580.076299, -630.408765), (542.676797, -500.968477), (547.389160, -488.321899), (180.697002, -446.737246), (157.135186, -628.827129), (178.051179, -429.736289), (580.076299, -630.408765), (537.391660, -512.742876), (542.676797, -500.968477), (184.325652, -463.009219), (157.135186, -628.827129), (180.697002, -446.737246), (580.076299, -630.408765), (531.533750, -523.645098), (537.391660, -512.742876), (188.937129, -478.552207), (157.135186, -628.827129), (184.325652, -463.009219), (580.076299, -630.408765), (525.103066, -533.675142), (531.533750, -523.645098), (194.531433, -493.366211), (157.135186, -628.827129), (188.937129, -478.552207), (580.076299, -630.408765), (518.099609, -542.833008), (525.103066, -533.675142), (201.108564, -507.451230), (157.135186, -628.827129), (194.531433, -493.366211), (580.076299, -630.408765), (506.572544, -555.694375), (518.099609, -542.833008), (208.668523, -520.807266), (157.135186, -628.827129), (201.108564, -507.451230), (580.076299, -630.408765), (494.381582, -567.201914), (506.572544, -555.694375), (217.211309, -533.434316), (157.135186, -628.827129), (208.668523, -520.807266), (580.076299, -630.408765), (481.526724, -577.355625), (494.381582, -567.201914), (226.736921, -545.332383), (157.135186, -628.827129), (217.211309, -533.434316), (580.076299, -630.408765), (468.007969, -586.155508), (481.526724, -577.355625), (237.245361, -556.501465), (157.135186, -628.827129), (226.736921, -545.332383), (580.076299, -630.408765), (453.825317, -593.601562), (468.007969, -586.155508), (248.502312, -566.765825), (157.135186, -628.827129), (237.245361, -556.501465), (580.076299, -630.408765), (438.978770, -599.693789), (453.825317, -593.601562), (260.273457, -575.949727), (157.135186, -628.827129), (248.502312, -566.765825), (580.076299, -630.408765), (423.468325, -604.432188), (438.978770, -599.693789), (272.558796, -584.053169), (157.135186, -628.827129), (260.273457, -575.949727), (580.076299, -630.408765), (407.293984, -607.816758), (423.468325, -604.432188), (285.358330, -591.076152), (157.135186, -628.827129), (272.558796, -584.053169), (580.076299, -630.408765), (390.455747, -609.847500), (407.293984, -607.816758), (298.672058, -597.018677), (157.135186, -628.827129), (285.358330, -591.076152), (157.135186, -628.827129), (390.455747, -609.847500), (580.076299, -630.408765), (312.499980, -601.880742), (157.135186, -628.827129), (298.672058, -597.018677), (157.135186, -628.827129), (372.953613, -610.524414), (390.455747, -609.847500), (326.842097, -605.662349), (157.135186, -628.827129), (312.499980, -601.880742), (157.135186, -628.827129), (357.068914, -609.984185), (372.953613, -610.524414), (341.698408, -608.363496), (157.135186, -628.827129), (326.842097, -605.662349), (157.135186, -628.827129), (341.698408, -608.363496), (357.068914, -609.984185), (562.359375, -412.006348), (685.375488, -315.676270), (580.076299, -630.408765), (561.057617, -222.600586), (562.359375, -412.006348), (176.388184, -412.006348), (562.359375, -412.006348), (169.879395, -315.676270), (685.375488, -315.676270)

"simple" shape comes out triangulated incorrectly

Hi, I'm working on integrating EarCut with Julia, and run into the following wrong triangulation:
image
(color encodes index: purple = 0, yellow = max_index)

I'd have assumed, that I'm rendering things wrong, or use the API incorrectly, but the EarCut test shape comes out fine in the same pipeline:
image

If you want to reproduce, I wrote a little c++ program with the shape embedded:
https://gist.github.com/SimonDanisch/6180a1bf2de473c9f9c152725121d329#file-shape-cc

Small scale polygons don't work well

If I try to tesselate a 24-vertex circular polygon, if the vertex data (as floats inside a custom class of mine) is numerically small (say, the bounds of the polygon are within 0.0 to 1.0) I'll often only get one or two triangles back from the tesselation function which is obviously insufficient. As I scale it up it starts to work better and better until I get a working tesselation of the full 24-vertex polygon. Is there just some tolerance value I can change in the header to make it work properly within this small range?

Non-nested polygon bug?

Hi,

I think I've found a bug in earcut.hpp. When the chains are not nested, but are disconnected outer (positively oriented) polygons, a strange triangulation is calculated.
I've added the original input and the triangulated result.
original
triangulated

Is it possible to fix this issue?

Thanks in advance.

Kind regards,

Remco Poelstra

Test against JS results

Port over the tests from the JS version, and compare the exact tessellation results against the JS output.

Incorrect triangulation on polygon without holes

Hi,

I am using Earcut for the triangulation of font glyphs and now I am implementing the inner outlines. Everything works well except this polygon without holes. It makes the triangle lines run through a non polygon area. I am generating points from bezier curves with some number of steps as a parameter. The points are little more precise, because they are double and have about 10 digits after decimal point but to_string gave me this, if it is not good enough I will post the original.

I am using enclosed polylines thus first and last point in the path is the same. Is it bad to use enclosed polylines like this for Earcut?

Could it be problem with a precision or something?

Thanks for the help

1

2

Polyline points on desmos

Polyline points in vector friendly format
{53.949310, -4.918930}, {33.122849, -7.631439}, {34.627930, -26.565918}, {34.633484, -26.398453}, {34.722870, -25.560196}, {34.882935, -24.723495}, {35.124268, -23.891434}, {35.457382, -23.072128}, {35.890213, -22.279892}, {36.424698, -21.534241}, {37.049622, -20.862045}, {37.741562, -20.282684}, {38.483948, -19.798050}, {39.263855, -19.406586}, {40.065781, -19.104767}, {40.878983, -18.885117}, {41.697449, -18.738510}, {42.519165, -18.656097}, {43.348495, -18.630112}, {44.177872, -18.656158}, {44.999969, -18.739075}, {45.819931, -18.887466}, {46.636124, -19.111389}, {47.442551, -19.421555}, {48.227310, -19.827103}, {48.972717, -20.332550}, {49.656998, -20.934311}, {50.258759, -21.618591}, {50.764206, -22.363998}, {51.169754, -23.148758}, {51.479919, -23.955185}, {51.703842, -24.771378}, {51.852234, -25.591339}, {51.935150, -26.413437}, {51.961258, -27.244598}, {51.934845, -28.063873}, {51.850800, -28.878815}, {51.701035, -29.691772}, {51.476532, -30.499985}, {51.168259, -31.296600}, {50.769257, -32.069733}, {50.277069, -32.803146}, {49.691422, -33.483597}, {49.015579, -34.094940}, {48.269852, -34.615051}, {47.481140, -35.034286}, {46.668137, -35.355911}, {45.843918, -35.588501}, {45.015564, -35.742691}, {44.185364, -35.828827}, {43.348511, -35.855835}, {42.511703, -35.828873}, {41.681992, -35.743286}, {40.855240, -35.590973}, {40.034180, -35.362839}, {39.225739, -35.049896}, {38.441696, -34.645111}, {37.698456, -34.146057}, {37.014313, -33.556839}, {36.405518, -32.887741}, {35.884827, -32.153778}, {35.459015, -31.373306}, {35.127991, -30.564133}, {34.886047, -29.740250}, {34.876251, -29.689957}, {35.792099, -41.211578}, {36.424164, -40.518631}, {37.146530, -39.858246}, {37.926651, -39.269363}, {38.764633, -38.758331}, {39.652664, -38.334366}, {40.579926, -38.004333}, {41.533859, -37.771439}, {42.502319, -37.635025}, {43.478348, -37.590881}, {44.454514, -37.635071}, {45.423431, -37.771912}, {46.378113, -38.006042}, {47.306076, -38.338516}, {48.194305, -38.766357}, {49.031296, -39.282608}, {49.808731, -39.877792}, {50.525024, -40.543900}, {51.178207, -41.273483}, {51.580643, -41.820190}, {53.949310, -4.918930}

Indexed points:
3

Triangulation code

std::vector<QPointF> TriangulatePolygon(const std::vector<Polyline>& polylines) {
    using VertexIndexType = uint32_t;
    using Point2D = std::pair<double, double>;

    std::vector<std::vector<Point2D>> polygon;
    std::vector<QPointF> points;
    for (const Polyline& polyline : polylines) {
        std::vector<Point2D> point2Dpolyline;
        for (const QPointF& point : polyline.points) {
            point2Dpolyline.push_back({point.x(), point.y()});
            points.push_back(point);
        }
        polygon.push_back(point2Dpolyline);
    }

    std::vector<VertexIndexType> trianglesIndices = mapbox::earcut<VertexIndexType>(polygon);
    std::vector<QPointF> trianglesVertices;
    for (size_t i = 0; i < trianglesIndices.size(); i += 3) {
        const QPointF pointI = points[trianglesIndices[i]];
        const QPointF pointI1 = points[trianglesIndices[i + 1]];
        const QPointF pointI2 = points[trianglesIndices[i + 2]];
        // reverse y axis coordinate, QT in 2D uses top down axis instead of right hand 3D coordinate system
        // correct counter clockwise order
        trianglesVertices.push_back({pointI.x(), -pointI.y()});
        trianglesVertices.push_back({pointI2.x(), -pointI2.y()});
        trianglesVertices.push_back({pointI1.x(), -pointI1.y()});
    }

    return trianglesVertices;
}


Missing triangles when tesselating concave polygons

I have a concave polygon with the following vertices:

0: { 20, 24 }
1: { 13, 124 }
2: { 200, 154 }
3: { 170, 24 }
4: { 130, 4 }
5: { 180, 40 }
6: { 80, 10 }

When trying to tesselate this polygon, I get the following indices:

1, 0, 6
5, 4, 3
3. 2, 1
1, 6, 5

This means, there is a triangle missing from the polygon. To help you understand how the polygon looks like, this is what it looks like when rendered (with the indices generated from this library):
image

For reference, this is what it should look like:
image

This is the code I used for inputting the vertices and then tesselating them:

#include "earcut.hpp"
#include <iostream>
#include <string>

int main() {
    using Point = std::array<double, 2>;
    std::vector<std::vector<Point>> polygon;
    std::vector<Point> points;
    Point currentPoint;
    double x, y;
    std::string next;

        do {
            std::cout << "Enter the X coordinate: ";
            std::cin >> x;
            std::cout << "Enter the Y coordinate: ";
            std::cin >> y;

            currentPoint = { x, y };
            points.push_back(currentPoint);

            std::cout << "Continue? (Y/N)";
            std::cin >> next;
        } while(next != "N" && next != "n");

        polygon.push_back(points);
        std::vector<uint16_t> indices = mapbox::earcut<uint16_t>(polygon);

    return 0;
}

I hope you can help, your implementation is the best and fastest I have seen yet and I would love to use it!

left shift of negative value

I'm getting a shift of a negative integer. The program (i.e. the polygon) which is triggering it is included below. The left shift is line 614 in the zOrder function. Firing up a debugger shows:
y = -1938
y_ = -270
minY = -170

#include <array>
#include <vector>
#include "earcut.hpp"

using namespace std;

int main()
{
	vector<vector<array<double,2>>> rings = 
	{
		{
			{{655,-27}}, {{635,-28}}, {{614,-29}}, {{553.469,-26}},
			{{496.875,-17}}, {{444.219,-2}}, {{395.5,19}}, {{350.719,46}},
			{{309.875,79}}, {{272.969,118}}, {{240,163}}, {{211.172,214.094}},
			{{186.188,271.375}}, {{165.047,334.844}}, {{147.75,404.5}},
			{{134.297,480.344}}, {{124.688,562.375}}, {{118.922,650.594}},
			{{117,745}}, {{118.922,839.641}}, {{124.688,928.062}},
			{{134.297,1010.27}}, {{147.75,1086.25}}, {{165.047,1156.02}},
			{{186.188,1219.56}}, {{211.172,1276.89}}, {{240,1328}},
			{{273,1373}}, {{310,1412}}, {{351,1445}}, {{396,1472}},
			{{445,1493}}, {{498,1508}}, {{555,1517}}, {{616,1520}},
			{{677.219,1517}}, {{734.375,1508}}, {{787.469,1493}},
			{{836.5,1472}}, {{881.469,1445}}, {{922.375,1412}},
			{{959.219,1373}}, {{992,1328}}, {{1021.06,1276.89}},
			{{1046.25,1219.56}}, {{1067.56,1156.02}}, {{1085,1086.25}},
			{{1098.56,1010.27}}, {{1108.25,928.062}}, {{1114.06,839.641}},
			{{1116,745}}, {{1114.92,673.281}}, {{1111.69,605.125}},
			{{1106.3,540.531}}, {{1098.75,479.5}}, {{1089.05,422.031}},
			{{1077.19,368.125}}, {{1063.17,317.781}}, {{1047,271}},
			{{1028.89,227.922}}, {{1008.56,188.188}}, {{986.016,151.797}},
			{{961.25,118.75}}, {{934.266,89.0469}}, {{905.062,62.6875}},
			{{873.641,39.6719}}, {{840,20}}, {{1040,-170}}, {{889,-270}}
		},
		{
			{{905,745}}, {{903.938,824.312}}, {{900.75,897.75}},
			{{895.438,965.312}}, {{888,1027}}, {{878.438,1082.81}},
			{{866.75,1132.75}}, {{852.938,1176.81}}, {{837,1215}},
			{{818.891,1248.05}}, {{798.062,1276.69}}, {{774.516,1300.92}},
			{{748.25,1320.75}}, {{719.266,1336.17}}, {{687.562,1347.19}},
			{{653.141,1353.8}}, {{616,1356}}, {{579.078,1353.8}},
			{{544.812,1347.19}}, {{513.203,1336.17}}, {{484.25,1320.75}},
			{{457.953,1300.92}}, {{434.312,1276.69}}, {{413.328,1248.05}},
			{{395,1215}}, {{379.297,1176.81}}, {{365.688,1132.75}},
			{{354.172,1082.81}}, {{344.75,1027}}, {{337.422,965.312}},
			{{332.188,897.75}}, {{329.047,824.312}}, {{328,745}},
			{{329.047,665.922}}, {{332.188,592.688}}, {{337.422,525.297}},
			{{344.75,463.75}}, {{354.172,408.047}}, {{365.688,358.188}},
			{{379.297,314.172}}, {{395,276}}, {{413.328,242.953}},
			{{434.312,214.312}}, {{457.953,190.078}}, {{484.25,170.25}},
			{{513.203,154.828}}, {{544.812,143.812}}, {{579.078,137.203}},
			{{616,135}}, {{653.141,137.188}}, {{687.562,143.75}},
			{{719.266,154.688}}, {{748.25,170}}, {{774.516,189.688}},
			{{798.062,213.75}}, {{818.891,242.188}}, {{837,275}},
			{{852.938,313.188}}, {{866.75,357.25}}, {{878.438,407.188}},
			{{888,463}}, {{895.438,524.688}}, {{900.75,592.25}},
			{{903.938,665.688}}
		}
	};
	mapbox::earcut<int>(rings);
}

Add notes about 3D to the readme

Half a year ago, I was wondering whether earcut.hpp supports 3d triangulation, you said "not at this time". I just noticed the javascript version of earcut supports that - at least since October (judging by the 2.0.7 release comment), maybe from the start.

Are there any plans or timeline for earcut.hpp to support 3d polygons?

Thanks!

Clean up interface

The public interface should be:

template <typename Polygon, typename N = uint32_t>
std::vector<N> earcut(const Polygon&);

The Coord type should be deduced, and everything else should be hidden in a detail namespace.

Extremely long compilation time for testing

Currently make takes WAY too long to compile everything (5โ€“10 minutes for a Travis/Appveyor job), and almost all the time is spent compiling fixture objects, one for each target (bench, tests, viz).

Is there anything we could do to speed this up? E.g. maybe convert fixtures to header-only? I'm not too good with C++ so any help would be appreciated. Iterating on Earcut.hpp is pretty painful with compile times this long.

Doesn't build on Windows

Hi everyone

As a beginner in C++ I could not build the project. I downloaded python V.2.7.11 and ran the command

"deps\gyp\gyp.bat" earcut.gyp --depth 5

but the error message was "config.gypi not found (...) while reading includes of common.gypi..."

Could you guide me how to build the project? Alternatively, could you provide a release that is already built? I would like to use the library in a .NET project and invoke it with PInvoke.

Kind regards

Simon

Connection between unconnected polygons

When testing a vector tile of mapbox-terrain with earcut.hpp, I noticed a small rendering artifact of two polygons that shouldn't be connected with an area between them:

64-broken

Expected:

64-xray

This definitely could be a failure on the encoding side or the rendering side, but at the moment I don't know how to test for that. @mourner any guidance for creating a useful test case here would be appreciated. cc/ @flippmoke @springmeyer @mikemorris

Don't discard unused vertices

Discarding unused vertices makes earcut.hpp output unworkable for mapbox-gl-native due to the following:

  • Fill outlines use GL_LINES with indexed vertices
  • This requires knowing which vertex indexes correspond to which polygon rings
  • We want to share the same vertex indices with fill triangles
  • Therefore the indexes used by earcut need to correspond to the input vertex order -- no removal of vertices unused by triangulation
  • Once that's the case, then we are able to loop through the vertices in input order, add them to the buffer, and add the indices of ring vertices to the line elements buffer

The JS implementation does not remove unused vertices.

cc @mourner @kkaefer to double check my logic.

Viz app broken on recent OS X

The build currently fails with >= 10.14 due to the combo of deprecation warnings + -Werror:

/Users/travis/build/mapbox/earcut.hpp/test/viz.cpp:67:9: error: 'glViewport' is deprecated: first deprecated in macOS 10.14 - OpenGL API deprecated. (Define GL_SILENCE_DEPRECATION to silence these warnings) [-Werror,-Wdeprecated-declarations]
        glViewport(0, 0, viewWidth, viewHeight);
        ^

https://travis-ci.org/mapbox/earcut.hpp/jobs/586690931#L629

This can be trigged by changing travis to test with xcode_image: 11 instead of osx_image: xcode8

Fix GCC notices

include/mapbox/earcut.hpp:669:33: warning: suggest parentheses around comparison in operand of '!=' [-Wparentheses]
     return area(p1, q1, p2) > 0 != area(p1, q1, q2) > 0 &&

Deprecation of std::allocator::construct

Since function std::allocator::construct is deprecated in c++17 and removed in C++20, i suggest to change the line 107 of earcut.hpp from:
alloc.construct(object, std::forward(args)...);
to:
new (static_cast<void*>(object)) T(std::forward(args)...);

Documentation?

I'm new to triangulation/tesselation and wonder how to use this library. Could you please add a minimum of documentation to readme.md? Some questions I have after glancing over test.cpp:

A Polygon is a vector of vector of pairs of e.g. doubles. Is the first vector in the vector the outer ring, all following vectors are holes?

Taking the dude-fixture as an example, the first point is not repeated at the end. Is it legal to repeat it?

Does it support three dimensions?

When retrieving vertices and indices, are the indices and their order intended for GL_TRIANGLE_FAN, GL_TRIANGLES, GL_TRIANGLE_STRIP? Looking at test.cpp's trianglesArea() makes me think its GL_TRIANGLES. If so, is there an easy way to transform that into a VBO for GL_TRIANGLE_STRIP?

Thank you!

Colinear point creating an issue

I have a set of points that is creating an issue, I have a triangulation that provides a face that is having an area equal to 0:

0.0795366 -0.530036
-0.176999  -0.51317
-0.687401 -0.479614
-0.607259   0.73937
-0.244585  0.715526
0.191209 0.206457
0.186494 0.134742
 0.169533 -0.123232

Basically a face is created between the point [6,7,8] (0 area face).

Screen Shot 2019-09-10 at 3 28 44 PM

I would rather prefer to have [4,8,7] and [4,7,6] created instead.

Bad tessellation in Aleutian Islands

Minimized polygon:

{
{{216,-128},{218,-98},{232,-104},{238,-98},{234,-58},{242,-32},{232,-16},{254,-2},{256,20},{268,6},{274,6},{278,20},{284,16},{284,6},{266,-4},{276,-28},{262,-64},{296,-68},{312,-60},{308,-50},{322,-46},{338,-46},{344,-52},{378,-50},{396,-16},{434,22},{446,26},{452,38},{470,42},{466,58},{450,56},{436,68},{428,102},{406,96},{408,116},{370,114},{340,96},{356,124},{358,164},{352,174},{328,186},{326,208},{342,208},{346,232},{328,232},{318,248},{306,246},{302,236},{284,238},{240,190},{218,194},{194,176},{184,124},{142,102},{134,102},{118,118},{72,118},{70,90},{52,68},{68,42},{68,24},{54,40},{36,28},{30,46},{12,48},{14,82},{30,98},{18,150},{-8,170},{-22,190},{-40,194},{-50,204},{-70,208},{-112,198},{-116,212},{-114,230},{-96,250},{-72,244},{-58,276},{-50,332},{-24,364},{-30,384},{-20,390},{-16,410},{-26,426},{-36,428},{-38,444},{-92,422},{-128,422},{-128,4224},{4224,4224},{4224,3520},{4204,3506},{4204,3498},{4212,3498},{4210,3486},{4164,3492},{4132,3478},{4104,3474},{4074,3458},{4034,3456},{3992,3428},{3928,3362},{3880,3342},{3870,3342},{3850,3360},{3814,3374},{3790,3374},{3768,3362},{3742,3360},{3706,3344},{3698,3334},{3656,3326},{3640,3314},{3592,3298},{3554,3266},{3534,3266},{3488,3252},{3464,3224},{3416,3202},{3384,3154},{3386,3142},{3398,3140},{3392,3124},{3400,3116},{3402,3094},{3392,3088},{3388,3070},{3394,3062},{3382,3052},{3378,3038},{3346,3010},{3316,2966},{3278,2938},{3278,2926},{3264,2910},{3212,2880},{3212,2866},{3220,2858},{3218,2844},{3208,2834},{3198,2836},{3184,2814},{3162,2802},{3158,2776},{3130,2768},{3090,2720},{3080,2728},{3070,2724},{3080,2698},{3044,2628},{3044,2602},{3024,2596},{3010,2580},{2992,2584},{2980,2574},{2966,2580},{2966,2608},{2972,2614},{2980,2664},{3022,2700},{3026,2718},{3056,2746},{3062,2778},{3080,2792},{3098,2824},{3112,2832},{3122,2848},{3130,2884},{3156,2922},{3156,2954},{3162,2960},{3176,2954},{3186,2960},{3202,2988},{3212,2994},{3212,3010},{3186,3026},{3170,2992},{3112,2946},{3102,2944},{3086,2926},{3090,2882},{3078,2860},{3062,2854},{3040,2832},{3018,2832},{3012,2822},{2986,2812},{2958,2782},{2960,2776},{2994,2776},{3000,2742},{2958,2696},{2928,2680},{2920,2648},{2910,2638},{2910,2624},{2900,2616},{2896,2598},{2882,2582},{2882,2566},{2862,2538},{2852,2496},{2828,2472},{2804,2464},{2796,2448},{2772,2446},{2754,2428},{2708,2424},{2702,2418},{2700,2388},{2644,2322},{2642,2304},{2648,2292},{2624,2276},{2616,2234},{2598,2224},{2590,2202},{2564,2176},{2556,2120},{2530,2086},{2542,2054},{2544,2012},{2530,1976},{2524,1928},{2542,1870},{2554,1718},{2546,1710},{2546,1668},{2540,1664},{2528,1616},{2518,1606},{2516,1576},{2524,1574},{2552,1588},{2612,1594},{2614,1588},{2606,1580},{2616,1564},{2616,1552},{2600,1528},{2586,1528},{2580,1506},{2552,1498},{2542,1480},{2534,1480},{2534,1494},{2512,1456},{2498,1452},{2498,1470},{2524,1504},{2552,1514},{2560,1520},{2564,1536},{2578,1540},{2578,1572},{2556,1576},{2498,1550},{2498,1534},{2474,1532},{2460,1514},{2434,1502},{2430,1490},{2418,1486},{2414,1472},{2402,1468},{2400,1460},{2374,1452},{2368,1428},{2350,1414},{2352,1402},{2380,1396},{2396,1412},{2418,1420},{2426,1420},{2430,1410},{2394,1396},{2378,1380},{2380,1352},{2364,1356},{2360,1350},{2360,1340},{2370,1336},{2370,1328},{2358,1328},{2356,1312},{2348,1306},{2350,1290},{2344,1284},{2332,1288},{2330,1270},{2318,1278},{2308,1264},{2314,1246},{2294,1236},{2306,1220},{2288,1220},{2278,1228},{2252,1202},{2258,1180},{2246,1174},{2246,1164},{2264,1158},{2254,1140},{2258,1112},{2232,1102},{2230,1082},{2222,1070},{2216,1070},{2220,1096},{2208,1092},{2202,1072},{2190,1068},{2196,1032},{2188,1044},{2172,1048},{2186,1068},{2182,1110},{2170,1108},{2168,1096},{2154,1084},{2144,1090},{2154,1092},{2154,1106},{2144,1108},{2130,1086},{2130,1074},{2106,1048},{2108,1042},{2122,1040},{2110,1022},{2120,1022},{2122,1014},{2102,1012},{2112,996},{2110,980},{2136,980},{2140,966},{2110,970},{2102,964},{2096,992},{2082,992},{2080,976},{2088,966},{2076,950},{2076,934},{2090,930},{2100,938},{2094,916},{2134,922},{2114,906},{2120,892},{2108,872},{2112,858},{2100,842},{2094,840},{2098,896},{2090,898},{2074,920},{2066,920},{2068,880},{2060,868},{2050,814},{2038,820},{2028,808},{2002,802},{1996,812},{1970,818},{1960,806},{1948,804},{1918,776},{1900,748},{1832,708},{1840,692},{1836,674},{1810,690},{1792,690},{1762,678},{1758,662},{1738,666},{1690,654},{1638,662},{1630,652},{1602,640},{1596,624},{1578,632},{1548,616},{1538,630},{1520,638},{1516,622},{1546,612},{1548,604},{1534,596},{1520,598},{1514,570},{1492,580},{1476,574},{1472,582},{1452,590},{1454,570},{1448,570},{1440,592},{1450,594},{1450,608},{1458,614},{1456,632},{1448,642},{1460,654},{1460,664},{1440,658},{1432,668},{1392,664},{1354,706},{1340,710},{1334,722},{1286,738},{1276,730},{1276,720},{1310,696},{1310,690},{1288,694},{1280,686},{1286,660},{1298,646},{1306,622},{1302,596},{1340,568},{1350,568},{1358,578},{1376,572},{1364,548},{1332,546},{1312,566},{1296,570},{1286,580},{1286,594},{1272,602},{1262,614},{1258,634},{1244,644},{1248,660},{1238,674},{1228,676},{1228,688},{1222,694},{1206,694},{1196,712},{1180,722},{1176,744},{1212,754},{1212,774},{1182,798},{1172,828},{1140,838},{1124,860},{1112,862},{1104,876},{1076,892},{1076,912},{1068,924},{1056,926},{1040,940},{1028,940},{1022,956},{1006,956},{1006,966},{984,970},{982,978},{990,988},{980,1002},{940,1018},{930,1034},{918,1020},{890,1044},{868,1048},{856,1058},{842,1056},{846,1040},{838,1038},{820,1078},{806,1086},{792,1082},{788,1090},{776,1090},{768,1080},{772,1092},{762,1102},{766,1108},{752,1116},{720,1118},{704,1134},{688,1132},{686,1118},{706,1092},{718,1092},{734,1082},{758,1088},{762,1076},{794,1056},{806,1030},{836,1010},{864,1008},{870,1020},{888,1016},{886,1000},{900,974},{952,938},{970,936},{976,910},{998,894},{1004,882},{1016,878},{1022,800},{1044,774},{1044,766},{1036,766},{990,786},{976,762},{970,762},{964,776},{968,800},{956,804},{928,764},{912,770},{898,760},{896,750},{888,750},{842,786},{826,786},{830,744},{820,740},{818,730},{830,704},{802,646},{794,664},{766,678},{724,678},{718,660},{702,642},{680,630},{676,616},{666,614},{682,596},{684,580},{674,574},{680,564},{674,558},{658,562},{652,544},{640,534},{644,522},{630,518},{630,510},{638,506},{634,492},{650,488},{650,460},{674,424},{688,418},{690,382},{706,354},{732,350},{756,370},{768,370},{794,346},{806,322},{818,328},{848,328},{868,310},{874,286},{866,254},{844,230},{844,220},{866,216},{872,210},{872,194},{854,182},{846,194},{814,202},{794,220},{788,236},{782,236},{778,220},{768,210},{768,230},{750,216},{710,216},{676,228},{634,216},{616,204},{618,182},{600,160},{614,150},{620,136},{570,124},{542,104},{542,96},{566,86},{570,74},{588,72},{620,38},{652,44},{644,24},{652,16},{684,8},{696,-4},{716,-10},{740,-4},{732,34},{738,48},{828,54},{840,30},{860,32},{854,18},{824,16},{826,2},{846,4},{826,-20},{826,-36},{836,-54},{820,-60},{798,-52},{748,-66},{724,-128},{216,-128}},
{{4124,4134},{4118,4136},{4120,4130},{4126,4130},{4124,4134}},
{{4086,4128},{4074,4130},{4072,4122},{4086,4118},{4086,4128}},
{{4068,4106},{4068,4112},{4060,4112},{4060,4104},{4068,4106}},
{{1032,4014},{1026,4014},{1026,4008},{1032,4014}},
{{1122,3162},{1144,3186},{1142,3198},{1124,3204},{1108,3218},{1096,3212},{1090,3176},{1098,3168},{1098,3156},{1122,3162}},
{{1088,3124},{1092,3134},{1074,3138},{1062,3126},{1064,3118},{1088,3124}},
{{1054,3114},{1038,3114},{1038,3108},{1050,3108},{1054,3114}},
{{1014,3104},{994,3102},{994,3088},{1006,3086},{1014,3104}},
{{940,3068},{934,3076},{926,3074},{922,3062},{940,3058},{940,3068}},
{{3042,2702},{3042,2710},{3034,2710},{3022,2694},{3030,2690},{3042,2702}},
{{2598,1566},{2590,1566},{2588,1558},{2594,1554},{2600,1554},{2598,1566}},
{{158,1326},{170,1326},{168,1334},{142,1342},{140,1336},{150,1318},{158,1326}},
{{100,1326},{98,1340},{90,1340},{84,1322},{100,1326}},
{{130,1336},{120,1338},{128,1326},{130,1336}},
{{-12,1318},{-14,1324},{-22,1324},{-18,1314},{-12,1318}},
{{-112,1318},{-116,1320},{-110,1312},{-112,1318}},
{{182,1314},{174,1316},{174,1310},{182,1314}},
{{272,1288},{266,1308},{234,1312},{248,1304},{260,1286},{272,1288}},
{{300,1312},{278,1308},{296,1306},{300,1312}},
{{2172,1156},{2180,1162},{2200,1160},{2188,1196},{2188,1222},{2200,1232},{2198,1260},{2208,1264},{2206,1278},{2226,1294},{2228,1310},{2208,1298},{2202,1282},{2160,1236},{2156,1210},{2142,1202},{2132,1178},{2136,1152},{2172,1156}},
{{348,1290},{346,1296},{338,1294},{342,1288},{348,1290}},
{{428,1270},{420,1272},{420,1266},{428,1270}},
{{610,1170},{626,1168},{626,1186},{616,1192},{604,1206},{588,1208},{568,1222},{552,1214},{536,1222},{518,1244},{506,1246},{512,1224},{526,1220},{532,1202},{546,1198},{554,1212},{580,1206},{590,1188},{586,1172},{596,1164},{608,1164},{610,1170}},
{{648,1152},{642,1160},{632,1158},{636,1148},{648,1152}},
{{2240,1118},{2238,1126},{2232,1124},{2234,1116},{2240,1118}},
{{806,1096},{802,1090},{808,1090},{806,1096}},
{{908,1080},{906,1076},{914,1072},{908,1080}},
{{894,1060},{884,1072},{872,1070},{876,1054},{894,1060}},
{{2024,826},{2052,836},{2048,856},{2056,876},{2054,904},{2066,948},{2062,986},{2052,980},{2044,954},{2030,938},{2028,912},{2020,922},{2010,922},{2012,894},{1976,846},{1976,834},{1988,820},{2016,816},{2024,826}}
};

Earcut:

screen shot 2015-10-08 at 11 25 47 am

Libtess:

screen shot 2015-10-08 at 11 25 28 am

Remove boost::pool dependency

#10 (comment)

Since it appears we have to dynamically allocate Nodes, an alternative to a preallocated std::unique_ptr<Node[]> is a std::list<std::array<Node, N>> with subarrays of a fixed size. std::list and std::array are chosen so that individual Node* are not at risk of invalidation, which would be the case with std::vector<Node>.

Issues with triangulating a polygon with 3d coords

I am creating a 3d polygon in Babylonjs . Captured points are right from 3d floor house.
Trying to get right winding order.
This point are in order of x,y,z total total 6 vertices data .

case 1
earcut([1321.229736328125, -678.8887939453125, 627.7532348632812, 143.97128295898438, -678.8887939453125, -1463.690185546875, -1583.582275390625, -678.8887939453125, -214.28005981445312, -867.3407592773438, -678.8887939453125, 1260.2886962890625, -129.64634704589844, -678.8887939453125, 1403.4495849609375, 1310.8477783203125, -678.8887939453125, 639.3106689453125], null, 3);
return []

case 2
earcut([1321, -678, 627, 143, -678, -1463, -1583, -678, -214, -867, -678, 1260, -129, -678, 1403, 1310, -6785, 639], null, 3);
return
[5, 0, 1, 4, 5, 1]

both are wrong

Multithreading

The algorithm looks like it could be made to run on multiple threads concurrently relatively easily. (By splitting the linked list into multiple seperate lists, and trying to split off ears in parallel). This would mean that the codebase diverges from earcut.js even more, but may lead to significant performance improvements.

Floating Point vs Integer

earcut.hpp supports both floating point and integer as vertices type, but isn't using the fastest approach in either case.

When using floating point data, lots of the min/max calculations are done using conditions, which slows them down, as x86/AMD64 both have branchless floating point min/max instructions which won't be used in that case. (see https://github.com/mapbox/earcut.hpp/blob/master/include/earcut.hpp#L286)

When using integer data, the code is casting to double quite frequently which slows things down aswell. Instead of casting to double, when expecting an overflow, it should cast to the next bigger integer type, for example with boost::int_t<size>

Loads of compile errors

I'm just trying to use earcut.hpp and stumble upon a lot of compile errors. All I have done until now is including the header file at the very beginning of my application. With this I end up with these errors:

1>\earcut.hpp(26): error C2864: 'mapbox::detail::Earcut::vertices' : only static const integral data members can be initialized within a class
1> \earcut.hpp(126) : see reference to class template instantiation 'mapbox::detail::Earcut' being compiled
1>\earcut.hpp(34): error C2253: 'Node' : pure specifier or abstract override specifier only allowed on virtual function
1> \earcut.hpp(32) : see reference to class template instantiation 'mapbox::detail::Earcut::Node' being compiled
1>\earcut.hpp(36): error C2253: 'Node' : pure specifier or abstract override specifier only allowed on virtual function
1>\earcut.hpp(44): error C2864: 'mapbox::detail::Earcut::Node::prev' : only static const integral data members can be initialized within a class
1>\earcut.hpp(45): error C2864: 'mapbox::detail::Earcut::Node::next' : only static const integral data members can be initialized within a class
1>\earcut.hpp(48): error C2864: 'mapbox::detail::Earcut::Node::z' : only static const integral data members can be initialized within a class
1>\earcut.hpp(51): error C2864: 'mapbox::detail::Earcut::Node::prevZ' : only static const integral data members can be initialized within a class
1>\earcut.hpp(52): error C2864: 'mapbox::detail::Earcut::Node::nextZ' : only static const integral data members can be initialized within a class
1>\earcut.hpp(55): error C2864: 'mapbox::detail::Earcut::Node::steiner' : only static const integral data members can be initialized within a class
1>\earcut.hpp(87): error C2864: 'mapbox::detail::Earcut::inv_size' : only static const integral data members can be initialized within a class
1>\earcut.hpp(99): error C2143: syntax error : missing ',' before '...'
1> \earcut.hpp(124) : see reference to class template instantiation 'mapbox::detail::Earcut::ObjectPool<T,Alloc>' being compiled
1>\earcut.hpp(100): error C2065: 'Args' : undeclared identifier
1>\earcut.hpp(100): error C2988: unrecognizable template declaration/definition
1>\earcut.hpp(100): error C2059: syntax error : '...'
1>\earcut.hpp(110): error C2334: unexpected token(s) preceding '{'; skipping apparent function body
1>\earcut.hpp(117): error C2061: syntax error : identifier 'blockSize'
1>\earcut.hpp(117): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>\earcut.hpp(117): warning C4183: 'reset': missing return type; assumed to be a member function returning 'int'
1>\earcut.hpp(118): error C2143: syntax error : missing ';' before 'private'
1>\earcut.hpp(771): error C4519: default template arguments are only allowed on a class template
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.