Skip to content

Commit

Permalink
Added a fix from the fix from [mapbox/earcut#91](mapbox/earcut#91)
Browse files Browse the repository at this point in the history
Updated LICENSE to be in-line with Mapbox's ISC requirements
  • Loading branch information
JaffaKetchup committed Jan 31, 2024
1 parent 6eabe0c commit 3f430ba
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 22 deletions.
16 changes: 16 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,19 @@ 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.

ISC License

Copyright (c) 2016, Mapbox

Permission to use, copy, modify, and/or distribute this software for any purpose
with or without fee is hereby granted, provided that the above copyright notice
and this permission notice appear in all copies.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
THIS SOFTWARE.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# dart_earcut

Ear-clipping (earcutting) triangulation algorithm, ported (with minor API differences) from [earcut4j/earcut4j](https://github.com/earcut4j/earcut4j) and [mapbox/earcut](https://github.com/mapbox/earcut).
Ear-clipping (earcutting) triangulation algorithm, ported (with minor API differences) from [earcut4j/earcut4j](https://github.com/earcut4j/earcut4j) and [mapbox/earcut](https://github.com/mapbox/earcut). Also includes the fix from [mapbox/earcut#91](https://github.com/mapbox/earcut/pull/91).

## Usage

Expand Down
60 changes: 52 additions & 8 deletions lib/dart_earcut.dart
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,14 @@ abstract final class Earcut {
final int outerLen =
hasHoles ? holeIndices[0] * dimensions : polygonVertices.length;

_Node? outerNode =
_linkedList(polygonVertices, 0, outerLen, dimensions, clockwise: true);
_Node? outerNode = _linkedList(
polygonVertices,
0,
outerLen,
dimensions,
null,
clockwise: true,
);

final triangles = <int>[];

Expand Down Expand Up @@ -546,11 +552,15 @@ abstract final class Earcut {
) {
final queue = <_Node>[];

int holeId = 0;

final int len = holeIndices.length;
for (int i = 0; i < len; i++) {
final int start = holeIndices[i] * dim;
final int end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;
final _Node? list = _linkedList(data, start, end, dim, clockwise: false);
holeId = i + 1;
final _Node? list =
_linkedList(data, start, end, dim, holeId, clockwise: false);
if (list == list?.next) list?.steiner = true;
queue.add(_getLeftmost(list!));
}
Expand Down Expand Up @@ -582,8 +592,36 @@ abstract final class Earcut {
do {
again = false;

if (!p.steiner && _equals(p, p.next!) ||
_area(p.prev!, p, p.next!) == 0) {
final prevHole = p.prev!.holeId;
final currentHole = p.holeId;
final nextHole = p.next!.holeId;

var toRemove = false;

if (!p.steiner) {
if (_equals(p, p.next!) || _equals(p.prev!, p)) {
toRemove = true;
} else if ((prevHole != null || prevHole != 0) ||
(nextHole != null || nextHole != 0) ||
prevHole == nextHole ||
prevHole != currentHole) {
// When `p.prev, p & p.next` are collinear,
// If `p.prev, p & p.next` are on holes (not outer edge) ,
// And `p.prev & p` are on the same hole ,
// Then do NOT remove `p` .

// In other words,
// When `p.prev, p & p.next` are collinear,
// If `p.prev, p & p.next` are on the outer edge,
// Or `p.prev & p` are on different holes ,
// Then do REMOVE `p`
if (_area(p.prev!, p, p.next!) == 0) {
toRemove = true;
}
}
}

if (toRemove) {
_removeNode(p);
p = (end = p.prev)!;
if (p == p.next) {
Expand Down Expand Up @@ -620,6 +658,9 @@ abstract final class Earcut {
final an = a.next!;
final bp = b.prev!;

a2.holeId = a.holeId;
b2.holeId = b.holeId;

a.next = b;
b.prev = a;

Expand Down Expand Up @@ -760,23 +801,25 @@ abstract final class Earcut {
List<double> data,
int start,
int end,
int dim, {
int dim,
int? holeId, {
required bool clockwise,
}) {
_Node? last;
if (clockwise == (_signedArea(data, start, end, dim) > 0)) {
for (int i = start; i < end; i += dim) {
last = _insertNode(i, data[i], data[i + 1], last);
last = _insertNode(i, data[i], data[i + 1], last)..holeId = holeId;
}
} else {
for (int i = end - dim; i >= start; i -= dim) {
last = _insertNode(i, data[i], data[i + 1], last);
last = _insertNode(i, data[i], data[i + 1], last)..holeId = holeId;
}
}

if (last != null && _equals(last, last.next!)) {
_removeNode(last);
last = last.next;
last?.holeId = holeId;
}

return last;
Expand Down Expand Up @@ -829,6 +872,7 @@ final class _Node {
_Node? next;
_Node? prevZ;
_Node? nextZ;
int? holeId;

_Node(this.i, this.x, this.y)
: z = 4.9E-324,
Expand Down
18 changes: 5 additions & 13 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: "0816708f5fbcacca324d811297153fe3c8e047beb5c6752e12292d2974c17045"
sha256: eb376e9acf6938204f90eb3b1f00b578640d3188b4c8a8ec054f9f479af8d051
url: "https://pub.dev"
source: hosted
version: "62.0.0"
version: "64.0.0"
analyzer:
dependency: transitive
description:
name: analyzer
sha256: "21862995c9932cd082f89d72ae5f5e2c110d1a0204ad06e4ebaee8307b76b834"
sha256: "69f54f967773f6c26c7dcb13e93d7ccee8b17a641689da39e878d5cf13b06893"
url: "https://pub.dev"
source: hosted
version: "6.0.0"
version: "6.2.0"
args:
dependency: transitive
description:
Expand Down Expand Up @@ -73,14 +73,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "3.0.3"
dart_internal:
dependency: transitive
description:
name: dart_internal
sha256: "689dccc3d5f62affd339534cca548dce12b3a6b32f0f10861569d3025efc0567"
url: "https://pub.dev"
source: hosted
version: "0.2.9"
file:
dependency: transitive
description:
Expand Down Expand Up @@ -378,4 +370,4 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.0.0 <3.3.0"
dart: ">=3.0.0 <4.0.0"

0 comments on commit 3f430ba

Please sign in to comment.