Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/hiulit/Delaunator-GDScript

A GDScript port of Delaunator: A fast library for Delaunay triangulation of 2D points.
https://github.com/hiulit/Delaunator-GDScript

2d algorithm computational-geometry delaunator delaunay fast gdscript mapbox triangulation

Last synced: 3 months ago
JSON representation

A GDScript port of Delaunator: A fast library for Delaunay triangulation of 2D points.

Lists

README

        

# Delaunator GDScript

![Godot v3.x](https://img.shields.io/badge/Godot-v3.x-%23478cbf?logo=godot-engine&logoColor=white&style=flat-square) ![GitHub release (latest by date)](https://img.shields.io/github/v/release/hiulit/Delaunator-GDScript?&style=flat-square) ![GitHub license](https://img.shields.io/github/license/hiulit/Delaunator-GDScript?&style=flat-square)

A GDScript port of Delaunator: A fast library for [Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) of 2D points.

* [Guide to data structures](/DATA_STRUCTURES.md).

This is a port of [Mapbox's Delaunator](https://github.com/mapbox/delaunator).

**Note**: It seems like GDScript is not that *fast* (in reference of the slogan above, taken from the original library). See the [performance benchmarks](#performance).

![Delaunay triangulation](/examples/00-a-delaunay-triangulation.png)
*Delaunay triangulation*

![Voronoi cells](/examples/00-b-voronoi-cells.png)
*Voronoi cells*

## 🚀 Usage

```gdscript
const Delaunator = preload("res://Delaunator.gd")

var points = PoolVector2Array([
Vector2(0, 0), Vector2(1024, 0), Vector2(1024, 600), Vector2(0, 600), Vector2(29, 390), Vector2(859, 300), Vector2(65, 342), Vector2(86, 333), Vector2(962, 212), Vector2(211, 351), Vector2(3, 594), Vector2(421, 278), Vector2(608, 271), Vector2(230, 538), Vector2(870, 454), Vector2(850, 351), Vector2(583, 385), Vector2(907, 480), Vector2(749, 533), Vector2(877, 232), Vector2(720, 546), Vector2(1003, 541), Vector2(696, 594), Vector2(102, 306)
])

var delaunay = Delaunator.new(points)

print(delaunay.triangles)
# >> [11, 16, 12, 11, 13, 16, 22, 20, 16, 16, 15, 12, 20, 18, 16, 13, 22, 16, 20, 22, 18, 18, 15, 16, 15, 5, 12, 9, 13, 11, 8, 19, 5, 5, 19, 12, 12, 0, 11, 18, 14, 15, 15, 8, 5, 17, 14, 18, 0, 23, 11, 11, 23, 9, 9, 4, 13, 14, 17, 15, 21, 17, 2, 23, 7, 9, 23, 6, 7, 7, 4, 9, 17, 8, 15, 19, 1, 12, 6, 4, 7, 2, 17, 18, 17, 21, 8, 22, 2, 18, 21, 1, 8, 4, 10, 13, 13, 3, 22, 22, 3, 2, 4, 3, 10, 10, 3, 13, 2, 1, 21, 8, 1, 19, 1, 0, 12, 23, 0, 6, 6, 0, 4, 4, 0, 3]

print(delaunay.halfedges)
# >> [5, 11, 38, 28, 17, 0, 18, 14, 16, 22, 26, 1, 20, 23, 7, 98, 8, 4, 6, 89, 12, 41, 9, 13, 44, 35, 10, 56, 3, 53, 113, 33, 43, 31, 77, 25, 115, 50, 2, 46, 59, 21, 73, 32, 24, 57, 39, 82, 117, 51, 37, 49, 65, 29, 70, 95, 27, 45, 74, 40, 84, 81, 110, 68, 71, 52, 119, 80, 63, 79, 54, 64, 86, 42, 58, 112, 116, 34, 122, 69, 67, 61, 47, 88, 60, 92, 72, 101, 83, 19, 109, 111, 85, 104, 107, 55, 106, 99, 15, 97, -1, 87, 125, 105, 93, 103, 96, 94, -1, 90, 62, 91, 75, 30, -1, 36, 76, 48, 120, 66, 118, 123, 78, 121, -1, 102]

print(delaunay.hull)
# >> [1, 0, 3, 2]

print(delaunay.coords)
# >> [0, 0, 1024, 0, 1024, 600, 0, 600, 29, 390, 859, 300, 65, 342, 86, 333, 962, 212, 211, 351, 3, 594, 421, 278, 608, 271, 230, 538, 870, 454, 850, 351, 583, 385, 907, 480, 749, 533, 877, 232, 720, 546, 1003, 541, 696, 594, 102, 306]

```

## 📑 API Reference

### Delaunator.new(points)

Constructs a Delaunay triangulation object given an array of points (`Vector2(x, y)`). Duplicate points are skipped.

### Delaunator.new(points).triangles

An array of triangle vertex indices (each group of three numbers forms a triangle). All triangles are directed counterclockwise.

To get the coordinates of all triangles, use:

```gdscript
var coordinates = []

for i in range(0, triangles.size(), 3):
coordinates.append([
points[triangles[i]],
points[triangles[i + 1]],
points[triangles[i + 2]]
])
```

### Delaunator.new(points).halfedges

An array of triangle half-edge indices that allows you to traverse the triangulation.
`i`-th half-edge in the array corresponds to vertex `triangles[i]` the half-edge is coming from.
`halfedges[i]` is the index of a twin half-edge in an adjacent triangle (or `-1` for outer half-edges on the convex hull).

The flat array-based data structures might be counterintuitive, but they're one of the key reasons this library is fast.

### Delaunator.new(points).hull

An array of indices that reference points on the convex hull of the input data, counter-clockwise.

### Delaunator.new(points).coords

An array of input coordinates in the form `[x0, y0, x1, y1, ...]`, of the type provided in the constructor.

### Delaunator.new(points).update()

Updates the triangulation if you modified `Delaunator.new(points).coords` values in place, avoiding expensive memory allocations. Useful for iterative relaxation algorithms such as [Lloyd's](https://en.wikipedia.org/wiki/Lloyd%27s_algorithm).

## 📈 Performance

Benchmark results performed on a Macbook Pro Retina 15" 2015 with Godot 3.2 and 3.3 using this method:

```gdscript
var start = OS.get_ticks_msec()
var delaunay = Delaunator.new(points)
var elapsed = OS.get_ticks_msec() - start
print(elapsed)
```

| | 10 points | 100 points | 1.000 points | 10.000 points | 100.000 points |
| :-- | --: | --: | --: | --: | --: |
| **Godot 3.2** | ~1ms | ~6ms | ~67ms | ~760ms | ~9.4s |
| **Godot 3.3** | ~1ms | ~8ms | ~77ms | ~850ms | ~10.0s |

## 🗒️ Changelog

See [CHANGELOG](/CHANGELOG.md).

## 👤 Author

**hiulit**

- Twitter: [@hiulit](https://twitter.com/hiulit)
- GitHub: [@hiulit](https://github.com/hiulit)

## 🤝 Contributing

Feel free to:

- [Open an issue](https://github.com/hiulit/Delaunator-GDScript/issues) if you find a bug.
- [Create a pull request](https://github.com/hiulit/Delaunator-GDScript/pulls) if you have a new cool feature to add to the project.
- [Start a new discussion](https://github.com/hiulit/Delaunator-GDScript/discussions) about a feature request.

## 🙌 Supporting this project

If you love this project or find it helpful, please consider supporting it through any size donations to help make it better ❤️.

[![Become a patron](https://img.shields.io/badge/Become_a_patron-ff424d?logo=Patreon&style=for-the-badge&logoColor=white)](https://www.patreon.com/hiulit)

[![Suppor me on Ko-Fi](https://img.shields.io/badge/Support_me_on_Ko--fi-F16061?logo=Ko-fi&style=for-the-badge&logoColor=white)](https://ko-fi.com/F2F7136ND)

[![Buy me a coffee](https://img.shields.io/badge/Buy_me_a_coffee-FFDD00?logo=buy-me-a-coffee&style=for-the-badge&logoColor=black)](https://www.buymeacoffee.com/hiulit)

[![Donate Paypal](https://img.shields.io/badge/PayPal-00457C?logo=PayPal&style=for-the-badge&label=Donate)](https://www.paypal.com/paypalme/hiulit)

If you can't, consider sharing it with the world...

[![](https://img.shields.io/badge/Share_on_Twitter-1DA1F2?style=for-the-badge&logo=twitter&logoColor=white)](https://twitter.com/intent/tweet?url=https%3A%2F%2Fgithub.com%2Fhiulit%2FDelaunator-GDScript&text=%22Delaunator-GDScript%22%0AA%20GDScript%20port%20of%20Delaunator%3A%20A%20fast%20library%20for%20Delaunay%20triangulation%20of%202D%20points%20by%20%40hiulit)

... or giving it a [star ⭐️](https://github.com/hiulit/Delaunator-GDScript/stargazers).

## 👏 Credits

Thanks to:

- [Vladimir Agafonkin](https://github.com/mourner) - For creating [Delaunator](https://github.com/mapbox/delaunator), the original JavaScript library.
- [Amit Patel](https://github.com/redblobgames) - For the [Delaunator guide](https://mapbox.github.io/delaunator/), which my data structures guide is based of.
- [Hakan Seven](https://github.com/HakanSeven12) - For the [Delaunator-Python](https://github.com/HakanSeven12/Delaunator-Python) port, which I used for some reference code.

## 📝 Licenses

- Source code: [MIT License](/LICENSE).
- Mapbox's Delaunator: [ISC License](/LICENSE_MABOX_DELAUNATOR.txt).