• Stars
    star
    123
  • Rank 280,380 (Top 6 %)
  • Language
    Julia
  • License
    Other
  • Created over 9 years ago
  • Updated 11 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Fast and robust Voronoi & Delaunay tessellation creation with Julia

VoronoiDelaunay.jl

⚠️ This package is in maintenance mode. Please consider newer packages such as DelaunayTriangulation.jl

Fast, robust construction of 2D Delaunay and Voronoi tessellations on generic point types. Implementation follows algorithms described in the Arepo paper and used (for e.g.) in the Illustris Simulation. License: MIT. Bug reports welcome!

How does it work?

Incrementally insert points to a valid Delaunay tessallation, while restoring Delaunayhood by flipping triangles. Point location (i.e. which triangle should it divide into three) is accelerated by spatial sorting. Spatial sorting allows to add points which are close in space thus walking the tesselation is fast. Initial tessalletion includes two triangles built by 4 points which are outside of the allowed region for users. These "external" triangles are skipped when iterating over Delaunay/Voronoy edges. Fast and robust predicates are provided by the GeometricalPredicates package. Benchmarks suggest this package is a bit faster than CGAL, see here benchmark of an older version which is also a bit slower than current.

Current limitations

  • Due to numerical restrictions the point coordinates must be within min_coord <= x <= max_coord where min_coord=1.0+eps(Float64) and max_coord=2.0-2eps(Float64). Note this is a bit different than what is required by the GeometricalPredicates package.
  • The following features are not implemented, but are in the TODO list; In order of priority: centroid tessellations (Lloy's method), Weighted generators (both power and sum), bounding, maybe restricting. Hierarchal tessellations for fast random locatings; Distributed tessellation construction. 3D. Order of priority may change of course :)

How to use?

Installation

]add VoronoiDelaunay

Building a tessellation

Define and push individual points like this:

using VoronoiDelaunay
tess = DelaunayTessellation()
push!(tess, Point(1.5, 1.5))

creation of points is explained in the GeometricalPredicates package documentation.

Pushing arrays of points is more efficient:

width = max_coord - min_coord
a = Point2D[Point(min_coord + rand() * width, min_coord + rand() * width) for i in 1:100]
push!(tess, a)

notice care taken for correct range of coordinates. min_coord and max_coord are defined in the package. We can further optimize by giving a sizehint at time of construction:

tess = DelaunayTessellation(100)

or at any later point:

sizehint(tess, 100)

Iterating

Delaunay tesselations need at least 3 points to be well defined. Voronoi need 4. Remember this when iterating or plotting. Iterating over Delaunay edges is done like this:

i = 0
for edge in delaunayedges(tess)
    i += 1
    # or, do something more useful :)
end

a DelaunayEdge contains two points a and b, they can be accessed with geta(edge) and getb(edge). Iterating over Voronoi edges is similar:

i = 0
for edge in voronoiedges(tess)
    i += 1
    # or, do something more useful :)
end

a VoronoiEdge is a bit different than a DelaunayEdge: here a and b are Point2D and not the generators, as they have different coordinates. To get the generators use getgena(edge) and getgenb(edge) these give the relevant AbstractPoint2D which were used to create the edge.

If the generators are not needed when iterating over the Voronoi edges (e.g. when plotting) then a more efficient way to iterate is:

i = 0
e = Nothing
for edge in voronoiedgeswithoutgenerators(tess)
    i += 1
    # do something more useful here :)
end

here edge is a VoronoiEdgeWithoutGenerators, the points a and b can be accessed as usual.

Iterating over Delaunay triangles:

i = 0
for delaunaytriangle in tess
    i += 1
    # or, do something more useful :)
end

delaunaytriangle here is of type DelaunayTriangle which is a subtype of AbstractNegativelyOrientedTriangle. To get the generators of this triangle use the geta, getb, and getc methods. You can do all other operations and predicate tests on this triangle as explained in GeometricalPredicates

Navigating

Locating a point, i.e. finding the triangle it is inside:

t = locate(tess, Point(1.2, 1.3))

if the point is outside of the tessellation then isexternal(t) == true holds. This is good for type stability, at least better than returning a Nothing. It is assumed that the point we want to locate is actually in the allowed points region. Performance is best when locating points close to each other (this is also why spatial sorting is used). Future versions may implement a hierarchal approach for fast random locations.

Navigating from a triangle to its neighbours is done like this:

t = movea(tess, t)  # move to the direction infront of generator a
t = moveb(tess, t)  # move to the direction infront of generator b
t = movec(tess, t)  # move to the direction infront of generator c

Plotting

The following retrieves a couple of vectors ready to plot Voronoi edges:

x, y = getplotxy(voronoiedges(tess))

and for Delaunay edges:

x, y = getplotxy(delaunayedges(tess))

Now plotting can be done with your favorite plotting package, for e.g.:

using Gadfly
plot(x=x, y=y, Geom.path)

To make a nice looking plot remember to limit the axes and aspect ratio. For e.g.:

set_default_plot_size(15cm, 15cm)
plot(x=x, y=y, Geom.path, Scale.x_continuous(minvalue=1.0, maxvalue=2.0), Scale.y_continuous(minvalue=1.0, maxvalue=2.0))

From an image

You can create a tesselation from an image, just like the tesselation of the julia logo at the top of this README. This was created from a png with from_file (see examples/img_to_vorono.jl):

import Images: imread
img = imread("julia.png")
tess = from_image(img, 25000)

More Repositories

1

Meshes.jl

Computational geometry and meshing algorithms in Julia
Julia
346
star
2

CoordinateTransformations.jl

A fresh approach to coordinate transformations...
Julia
177
star
3

Rotations.jl

Julia implementations for different rotation parameterizations
Julia
171
star
4

GeometryBasics.jl

Basic Geometry Types
Julia
162
star
5

Quaternions.jl

A Julia implementation of quaternions
Julia
115
star
6

RegionTrees.jl

Quadtrees, Octrees, and more in Julia
Julia
109
star
7

GeometryTypes.jl

Geometry types for Julia
Julia
67
star
8

GeometricalPredicates.jl

Fast and robust 2D & 3D incircle/intriangle/etc. for Julia
Julia
56
star
9

Meshing.jl

Meshing and isosurface extraction algorithms
Julia
55
star
10

MeshViz.jl

Makie.jl recipes for visualization of Meshes.jl
Julia
54
star
11

DelaunayTriangulation.jl

Delaunay triangulations and Voronoi tessellations of planar point sets.
Julia
46
star
12

Descartes.jl

Software Defined Solid Modeling
Julia
43
star
13

Contour.jl

Calculating contour curves for 2D scalar fields in Julia
Julia
39
star
14

Triangulate.jl

Julia Wrapper for the Triangle Mesh Generator
Julia
38
star
15

TetGen.jl

Julia's TetGen wrapper
Julia
37
star
16

VoronoiCells.jl

Voronoi tesselations in Julia
Julia
33
star
17

Clipper.jl

Julia wrapping of clipper
Julia
30
star
18

KDTrees.jl

KDTrees for julia
Julia
25
star
19

OldImmutableArrays.jl

Statically-sized immutable vectors and matrices.
Julia
21
star
20

PolygonOps.jl

Generic Polygon Operations
Julia
21
star
21

Delaunator.jl

Delaunator in Julia
Julia
21
star
22

DistMesh.jl

Tetrahedral meshing of distance functions in Julia
Julia
20
star
23

OldMeshes.jl

A collection of tools for working with Meshes
Julia
20
star
24

PlyIO.jl

Read and write polygon ply files from julia
Julia
20
star
25

MarchingCubes.jl

Efficient Implementation of Marching Cubes' Cases with Topological Guarantees
C
19
star
26

TriangleIntersect.jl

Fast ray-triangle intersections for raytracing
Julia
12
star
27

OctTrees.jl

Fast quad and oct-trees for Julia
Julia
12
star
28

RayTraceEllipsoid.jl

Ray trace ellipsoid-shaped domes. Find intersection points and refract/reflect according to the refractive indices.
Julia
11
star
29

Packing.jl

Algorithms for packing problems
Julia
9
star
30

Octonions.jl

A Julia implementation of octonions
Julia
8
star
31

meta

For discussion centered around the JuliaGeometry organization
8
star
32

Bullet3.jl

Wrapper for Bullet3 physics engine
Julia
7
star
33

EarCut.jl

Wrapper for Mapbox's earcut.hpp for polygon triangulation
Julia
6
star
34

tetgen.dependency

tetgen unmodified source and binary for win & linux
C++
5
star
35

MeshPlots.jl

Plots.jl recipes for Meshes.jl
Julia
2
star
36

Intervals.jl

Interval arithmetic and algebra in Julia (not maintained, or ever published)
Julia
1
star
37

TriangleBuilder

Julia
1
star
38

TetgenBuilder

binaries for Tetgen
Julia
1
star
39

juliageometry.github.io

The juliageometry.org website
HTML
1
star
40

QuadricMeshSimplification.jl

Quadric Mesh Simplification for reducing triangle counts
Julia
1
star
41

Libfive.jl

Wrapper for the Libfive library for generative design
Julia
1
star