Scientific Computing, TU Berlin, WS 2019/2020, Lecture 13
Jürgen Fuhrmann, WIAS Berlin
Definiton: A grid $\{T_1\dots T_M\}$ of $\Omega$ is admissible if
Image (Source: Braess): Left - admissible mesh, right - mesh with "hanging" nodes
Definition: A triangulation $\{T_1\dots T_M\}$ of a domain $\Omega$ is
After G. F. Voronoi, 1868-1908
Definition: Let $\mathbf p,\mathbf q\in \mathbb R^d$. The set of points $H_{\mathbf p\mathbf q}=\left\{\mathbf x\in \mathbb R^d: ||\mathbf x-\mathbf p||\leq ||\mathbf x-\mathbf q||\right\}$ is the half space of points $\mathbf x$ closer to $\mathbf p$ than to $\mathbf q$.
Definition: Given a finite set of points $S\subset \mathbb R^d$, the Voronoi region (Voronoi cell) of a point $\mathbf p\in S$ is the set of points $\mathbf x$ closer to $\mathbf p$ than to any other point $\mathbf q\in S$: $$V_\mathbf p=\left\{\mathbf x\in \mathbb R^d: ||\mathbf x-\mathbf p||\leq ||\mathbf x-\mathbf q||\,\forall \mathbf q\in S\right\}$$
The Voronoi diagram of $S$ is the collection of the Voronoi regions of the points of $S$.
Voronoi diagram of 8 points in the plane (H. Si) \end{minipage}
After B.N. Delaunay (Delone), 1890-1980
Delaunay triangulation of the convex hull of 8 points in the plane (H.Si)
Interactive example via GEOGRAM
Definition: A triangulation of the convex hull of a point set $S$ has the Delaunay property if each simplex (triangle) of the triangulation is Delaunay, i.e. its circumsphere (circumcircle) is empty wrt. $S$, i.e. it does not contain any points of $S$.
This algorithm is known to terminate after $O(n^2)$ operations. After termination, all edges will be locally Delaunay, so the output is the Delaunay triangulation of $S$.
During this course, we will focus on Triangle. It can be compiled to a standalone executable reading and writing files or to a library which can be called from applications.
Currently in Julia it is accessible as submodule of the package VoronoiFVM.jl. It is planned to become a standalone package, consolidating the use of several Julia packages which already use Triangle.
using Triangulate
using PyPlot
Plot a pair of input and output triangulateio structs
function plotpair(Plotter::Module, triin, triout;voronoi=nothing)
if Triangulate.ispyplot(Plotter)
PyPlot=Plotter
PyPlot.clf()
PyPlot.subplot(121)
PyPlot.title("In")
Triangulate.plot(PyPlot,triin)
PyPlot.subplot(122)
PyPlot.title("Out")
Triangulate.plot(PyPlot,triout,voronoi=voronoi)
end
end
triangulateio
which contains possible input
and output information
triin=Triangulate.TriangulateIO()
triin.pointlist=[ 0.0 0; 1 0; 0 1]'
(triout, vorout)=triangulate("", triin)
plotpair(PyPlot,triin,triout)
triin=Triangulate.TriangulateIO()
triin.pointlist=rand(Cdouble,2,7)
(triout, vorout)=triangulate("Qc", triin)
plotpair(PyPlot,triin,triout)
triin=Triangulate.TriangulateIO()
triin.pointlist=rand(Cdouble,2,7)
(triout, vorout)=triangulate("Qcv", triin)
plotpair(PyPlot,triin,triout,voronoi=vorout)
Definition: An admissible triangulation of a polygonal Domain $\Omega\subset \mathbb R^d$ has the boundary conforming Delaunay property if
Equivalent definition in 2D:
Corollary:
Remarks:
triin=Triangulate.TriangulateIO()
triin.pointlist=rand(Cdouble,2,7)
(triout, vorout)=triangulate("cv", triin)
plotpair(PyPlot,triin,triout,voronoi=vorout)
triin=Triangulate.TriangulateIO()
triin.pointlist=rand(Cdouble,2,7)
(triout, vorout)=triangulate("Dcv", triin)
plotpair(PyPlot,triin,triout,voronoi=vorout)
triin=Triangulate.TriangulateIO()
triin.pointlist=Matrix{Cdouble}([0.0 0.0 ; 1.0 0.0 ; 0.4 0.4 ; 0.0 1.0; 0.2 0.3]')
triin.segmentlist=Matrix{Cint}([1 2 ; 2 3 ; 3 4 ; 4 1 ]')
triin.segmentmarkerlist=Vector{Int32}([1, 2, 3, 4])
(triout, vorout)=triangulate("pv", triin)
plotpair(PyPlot,triin,triout,voronoi=vorout)
triin=Triangulate.TriangulateIO()
triin.pointlist=Matrix{Cdouble}([0.0 0.0 ; 1.0 0.0 ; 0.4 0.4 ; 0.0 1.0; 0.2 0.3]')
triin.segmentlist=Matrix{Cint}([1 2 ; 2 3 ; 3 4 ; 4 1 ]')
triin.segmentmarkerlist=Vector{Int32}([1, 2, 3, 4])
(triout, vorout)=triangulate("pvD", triin)
plotpair(PyPlot,triin,triout,voronoi=vorout)
triin=Triangulate.TriangulateIO()
triin.pointlist=Matrix{Cdouble}([0.0 0.0 ; 1.0 0.0 ; 0.4 0.4 ; 0.0 1.0; 0.2 0.3]')
triin.segmentlist=Matrix{Cint}([1 2 ; 2 3 ; 3 4 ; 4 1 ]')
triin.segmentmarkerlist=Vector{Int32}([1, 2, 3, 4])
(triout, vorout)=triangulate("pa0.1", triin)
plotpair(PyPlot,triin,triout,voronoi=vorout)
function unsuitable(x1,y1,x2,y2,x3,y3,area)
bary_x=(x1+x2+x3)/3.0
bary_y=(y1+y2+y3)/3.0
dx=bary_x-0.1
dy=bary_y-0.1
area>0.001*exp(50.0*(dx^2+dy^2))
end
triin=Triangulate.TriangulateIO()
triin.pointlist=Matrix{Cdouble}([0.0 0.0 ; 1.0 0.0 ; 0.4 0.4 ; 0.0 1.0; 0.2 0.3]')
triin.segmentlist=Matrix{Cint}([1 2 ; 2 3 ; 3 4 ; 4 1 ]')
triin.segmentmarkerlist=Vector{Int32}([1, 2, 3, 4])
triunsuitable(unsuitable)
(triout, vorout)=triangulate("pa0.1u", triin)
plotpair(PyPlot,triin,triout,voronoi=vorout)
triin=Triangulate.TriangulateIO()
triin.pointlist=Matrix{Cdouble}([0.0 0.0 ; 1.0 0.0 ; 0.4 0.4 ; 0.0 1.0; 0.2 0.3]')
triin.segmentlist=Matrix{Cint}([1 2 ; 2 3 ; 3 4 ; 4 1 ]')
triin.segmentmarkerlist=Vector{Int32}([1, 2, 3, 4])
(triout, vorout)=triangulate("pa0.1Q", triin)
plotpair(PyPlot,triin,triout,voronoi=vorout)
@show triout.pointlist
@show triout.trianglelist
@show triout.segmentlist
@show triout.segmentmarkerlist
@show triout.triangleattributelist
This notebook was generated using Literate.jl.