{"id":22647918,"url":"https://github.com/juliageometry/delaunator.jl","last_synced_at":"2026-01-23T21:31:41.808Z","repository":{"id":65561902,"uuid":"234665396","full_name":"JuliaGeometry/Delaunator.jl","owner":"JuliaGeometry","description":"Delaunator in Julia","archived":false,"fork":false,"pushed_at":"2025-03-03T02:03:19.000Z","size":1166,"stargazers_count":20,"open_issues_count":3,"forks_count":6,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-18T23:47:09.711Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Julia","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JuliaGeometry.png","metadata":{"files":{"readme":"README.jmd","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-01-18T01:32:58.000Z","updated_at":"2025-03-03T02:01:52.000Z","dependencies_parsed_at":"2024-04-16T14:26:36.324Z","dependency_job_id":"a015e930-9b05-492f-bbe1-f2767a1895e9","html_url":"https://github.com/JuliaGeometry/Delaunator.jl","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaGeometry%2FDelaunator.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaGeometry%2FDelaunator.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaGeometry%2FDelaunator.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaGeometry%2FDelaunator.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JuliaGeometry","download_url":"https://codeload.github.com/JuliaGeometry/Delaunator.jl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":249598578,"owners_count":21297465,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-09T07:35:46.239Z","updated_at":"2026-01-23T21:31:41.779Z","avatar_url":"https://github.com/JuliaGeometry.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Delaunator\n\n[![Stable](https://img.shields.io/badge/docs-stable-blue.svg)](https://juliageometry.github.io/Delaunator.jl/stable)\n[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://juliageometry.github.io/Delaunator.jl/dev)\n[![Codecov](https://codecov.io/gh/juliageometry/Delaunator.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/juliageometry/Delaunator.jl)\n[![Coveralls](https://coveralls.io/repos/github/juliageometry/Delaunator.jl/badge.svg?branch=master)](https://coveralls.io/github/juliageometry/Delaunator.jl?branch=master)\n\nA port of [Mapbox's Delaunator](https://github.com/mapbox/delaunator) to Julia.\n\n\u003e An incredibly fast and robust Javascript library for\n\u003e [Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) of 2D points.\n\nThe Delaunator algorithm computes a simple 2d triangulation of an arbitrary set of points in the plane _quickly_. This package provides a Julia implementation of the algorithm along with a number of supporting routines that operate on the Delaunator data structures. \n\nOn a 2020 M1 Macbook Air, the `Delaunator.jl` package will triangulate a million points in about 500ms, including computing circumcenters for the triangles for the closest site diagram. \n\n```julia\nusing GeometryBasics, Delaunator, StableRNGs, CairoMakie, Statistics, LinearAlgebra\n\n# generate random points. \nipts = randn(StableRNG(1), ComplexF64, 100)\nipts = sqrt.(abs.(ipts)).*ipts./abs.(ipts)\npts = Point2f.(zip(real(ipts),imag(ipts)))\nt = triangulate(pts) # triangulate them! \nf = Figure()\nax = Axis(f[1,1])\nhidespines!(ax); hidedecorations!(ax) \nrdata = rand(StableRNG(1), length(triangles(t)))\n# work over all triangles\nfor (i,tri) in enumerate(triangles(t))\n  tripts = pts[collect(tri)]\n  poly!(ax, tripts, color=norm(mean(tripts))*(1+0.5*rdata[i])*[1,1,1],\n    colorrange=(0,3), \n    colormap=map(c-\u003eRGBAf(c.r,c.g,c.b,0.9), Makie.to_colormap(:matter)))\nend\nscatter!(ax, pts, color=:black, markersize=5)\nf\n```\n\nSynopsis\n--------\n```julia \nusing Delaunator, GeometryBasics, StableRNGs\nt = triangulate(rand(StableRNG(1), Point2f, 10))\nfor i in eachindex(t) # iterate over each point index \n  @show i, inhull(t, i) # this gives 0 or a pointer into t.hull\nend\n##  \nfor n in neighbors(t, 1) # iterate over neighbors of i\nend \nfor (i,j) in edges(t) # iterate over all edges in triangulation\nend \n\n##\ncollect(triangles(t, 1)) # get the triangles that touch point 1. \n```\n\n### Drawing the triangulation \n```julia\nusing CairoMakie\nf = linesegments(collect(edgelines(t)), color=:black, linewidth=0.75) # draw the edges \nhidespines!(f.axis); hidedecorations!(f.axis) \npoly!(f.axis, collect(hullpoly(t)), color=:transparent, strokewidth=1); f\n```\n\n### Dual cells, aka Voronoi cells \n```julia \n## dual cells, aka Voronoi cells (this interface is still a bit rough)\n# get an infinite poly description of the points nearest cell i \np = dualcell(t, 9) \n@show contains(p, (1.0,2.0)) # test if a point (x,y) is in the polygon\n@show isfinite(p) # test if it's finite or infinite \nbbox = margin_bbox(t, 0.05) \ncp = clippedpoly(p, bbox) # produce a finite polygon\npoly!(f.axis, cp, color=Cycled(1), strokewidth=1)\npoly!(f.axis, clippedpoly(dualcell(t, 1), bbox), color=Cycled(2), strokewidth=1)\nf\n```\n\nExample uses\n------------\n```julia\n# Draw the key edges in the dual cells of a triangulation, aka the Voronoi diagram\npts = rand(StableRNG(1), Point2f, 15)\nrval = triangulate(pts)\nf = scatter(pts); hidespines!(f.axis); hidedecorations!(f.axis) \ntext!(f.axis, pts, text=map(i-\u003e\"$i\", 1:length(pts)))\nfor i in eachindex(rval) \n  local p = Delaunator.dualcell(rval, i)\n  # use clipped poly to get closed polygons\n  # for the dualcells... \n  linesegments!(f.axis, collect(segments(p)),\n    xautolimits=false,yautolimits=false, color=:black)\nend \nf\n```\n\nPhilosophy\n----------\nWhen possible, everything is lazy and returns iterators and generators instead of arrays. \nPut simply: if you could have implemented something without copies / output arrays, we'd \nlike to make it possible to do the same thing. Sometimes this is really tricky, like with\nthe `clippedpoly` scenario. So there, we allow you to provide any data type you want\nto consume the points we are adding. This would enable one to implement something like\nan area computation without any allocations. \n\nIn the future\n-------------\nIn the future, we hope to make things like this work! \n```julia; eval=false \n## Searching (NOT IMPLEMENTED)\nfindtriangle(t, pt) \nnearestpoint(t, pt) \n\n## nearest point cell diagram aka Voronoi diagram. (NOT IMPLEMENTED)\n# you can get much of this with the \"dualcell/clippedpoly\" featuers\n# this will compute and store the info in a more compact way. \nbc = boundedcells(t; margin=0.05) # get the nearest point cells\ncellarea(bc, i)\ncellpoly(bc, i) \nneighbors(bc, i) # get an iterator over neighbors of the bounded cells \n```\n\nWant to help?\n-------------\n- implement the searching routines \"findtriangle\" and \"nearestpoint\"\n- use of `ExactPredicates.jl` to get better results on the robustness test cases \n- use the new Julia 1.9 package extensions to implement plotting routines for Makie/Plots.jl\n\nComparison to other packages\n----------------------------\n\nThere are a variety of other Delaunay and Voronoi packages in the Julia ecosystem.\n\n- [`VoronoiDelaunay.jl`](https://github.com/JuliaGeometry/VoronoiDelaunay.jl)\n- [`VoronoiCells.jl`](https://github.com/JuliaGeometry/VoronoiCells.jl)\n- [`DelaunayTriangulation.jl`](https://github.com/JuliaGeometry/DelaunayTriangulation.jl)\n- [`MiniQhull.jl`](https://github.com/gridap/MiniQhull.jl)\n- [`DirectQhull.jl`](https://github.com/JuhaHeiskala/DirectQhull.jl)\n\nBoth MiniQhull and DirectQhull wrap the Qhull binary library. This is extremely accurate but is much slower\nthan many other methods. \n\nThe others are pure Julia packages. \n- `VoronoiDelaunay.jl` uses the [`GeometricalPredicates.jl`](https://github.com/JuliaGeometry/GeometricalPredicates.jl)\nto ensure accurate geometry. This package then imposes a restriction of points to the interval [1,2] to guarantee accuracy\nof floating point computations. \n- There is limited support for dual cells / Voronoi cells in `VoronoiDelaunay` and \na good deal of this functionality is provided by the package `VoronoiCells.jl`. \n- The `DelaunayTriangulation.jl` package that \nuses [`AdaptivePredicates.jl`](https://github.com/JuliaGeometry/AdaptivePredicates.jl) and [`ExactPredicates.jl`](https://github.com/lairez/ExactPredicates.jl) to implement various \ncomputational geometry tests. This package is under active development and implements a number of methods for unconstrained and constrained Delaunay triangulations and Voronoi tessellations.\n\nIn comparison, the `Delaunator.jl` package seeks to mirror the javascript d3-delaunay codes that give good\nenough triangulations for many pixel-level graphics applications and are fast for 2d problems, rather than those that \nmight be suitable for those with computational geometry applications that need better guarantees\n(although we do hope to improve this in the future). The underlying Delaunator javascript library does use the\naccurate primitives, although these are relaxed slightly in the d3-delaunay usage -- especially in terms of the\nVoronoi cells. \n\nRobust orientation\n==================\nThe Delaunator.jl code direct includes the `robust_orient` function from \n[`AdaptivePredicates.jl`](https://github.com/vchuravy/AdaptivePredicates.jl), which \nports the  \n[robust orientation routines from Jonathan Richard Shewchuk](https://www.cs.cmu.edu/~quake/robust.html)\n\n\u003e This readme is auto-generated by weave from `README.jmd`\n```julia; eval=false, echo=false \nweave(\"README.jmd\", doctype = \"github\", fig_path = \"docs\")\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuliageometry%2Fdelaunator.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjuliageometry%2Fdelaunator.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuliageometry%2Fdelaunator.jl/lists"}