Anisotropic Triangular Mesh Generation Based on Refinement

by François Labelle

University of California - Berkeley

Contents

1. Introduction
2. Implementation
3. Technical Details
4. The Meshing Art Gallery
5. Future Work


1. Introduction

What does this all mean?

"Triangular Mesh Generation" takes as input a segment-bounded Planar Straight Line Graph, which is basically just a list of vertices and segments with a well-defined interior. The technique adds vertices and edges to partition the interior region into nicely shaped triangles.

1) no meshing
2) mesh simple.poly -v40

Figure 1: Triangular mesh generation

"Anisotropic" means that it is possible to specify the desired shape and size of triangles in different portions of the mesh.

1) mesh simple.poly -hstretch -v40
2) mesh simple.poly -left -left -top -top -v40

Figure 2: Anisotropic mesh generation

"Refinement" means that the mesh is produced by inserting new vertices repeatedly.

1) mesh simple.poly -v16
2) mesh simple.poly -v17
3) mesh simple.poly -v18

Figure 3: Mesh refinement


2. Implementation

The ideas described above were implemented in a program called mesh, which is freely available. mesh was designed for unix-compatible platforms but should compile on any system supporting ANSI C. All the meshes that appear in this document were computed using this program (the command line is shown below every picture).

Source code

The program and some input files can be obtained as a gzipped tarred archive meshcode.tar.gz, or by saving the individual files below.

Program:
mesh.c the mesh generator
transform.c anisotropic transformation functions
mesh.h program header
mesh.build the compile script for unix systems

Some input files:
simple.poly
square.poly

Relevant links
More input files can be obtained from this directory.
Description of the file formats: .poly .node .ele
The Show Me visualization program to view the input and output files.

Usage

Instructions for using the code are displayed when the executable runs without any input files:
% mesh
usage: mesh -option1 -option2 [...] file.node file.poly [...]
    .node files will be triangulated (output: .ele)
    .poly files will be meshed (output: .node and .ele)
meshing options:
    -g  grading mesh (size of triangles irrelevent)
    -a# angle lower bound in degrees, only with -g option (default 30.0)
    -v# vertex upper bound (default 1000, ~184 K RAM)
    -c  convex hull edges become segments
anisotropy options: (can be combined!)
   affecting shape:
    -hstretch, -vstretch, -dstretch, -sink, -swirl
   affecting size:
    -hline, -vline, -dline, -center, -perimeter
    -left, -right, -top, -bottom
   user specified:
    -custom (the function 'T_custom' in 'transform.c')
When used on .node files, mesh becomes a simple anisotropic point-set triangulator. Furthermore, when no anisotropy option is used, mesh naturally returns the Delaunay triangulation of the point-set.

1) mesh spiral.node
2) mesh spiral.node -hstretch
3) mesh spiral.node -vstretch

Figure 4: Three triangulations of the same point-set

Meshing options

With the -g option on, mesh will only try to obtain nicely shaped triangles (and not try to obtain triangles of the same size). This is useful when an application requires small triangles only close to the boundary.
1) mesh superior.poly -g
2) mesh superior.poly

Figure 5: Grading mesh   vs   uniform mesh

Anisotropy options

Here's a catalog of the anisotropy options currently implemented. The images were computed using the command:
mesh square.poly [option] -v200

no option

-hstretch

-vstretch

-dstretch

-sink

-swirl

-hline

-vline

-dline

-center

-perimeter

-left

-right

-top

-bottom

-custom
For the top row, the options -sink -swirl were also added. This is a small hack used to break the symmetry of the square. (The two options -sink and -swirl cancel each other but introduce numerical instability.) Otherwise we get artificially regular patterns like this one:


no option
An anisotropy option can be repeated to obtain a stronger effect, and various options can be combined to obtain more effects. (Total flexibility is possible by coding a custom anisotropy function directly in transform.c.)

1) mesh square.poly -v200 -center -center -center
2) mesh square.poly -v200 -sink -sink
3) mesh square.poly -v200 -hline -hline -vline -vline -perimeter -perimeter -perimeter

Figure 6: Combining anisotropy options


3. Technical Details

Implementing anisotropy

Without anisotropy, mesh acts like Ruppert's Delaunay refinement algorithm for triangular mesh generation [1], as described in Section 3.4 of the course lecture notes.

When anisotropy is used, each point (x,y) in the plane is assigned a linear transformation T:R2->R2 that describes how the plane should stretch in the neighborhood of (x,y).

The minimum distorted angle of a triangle is defined to be the smallest angle of the triangle when distorted by the linear transformation assigned to its centroid.

Figure 7: Minimum distorted angle of a triangle

Anisotropic triangulations

By flipping edges, the program maintains a triangulation of the vertices that lexicographically maximizes the set of distorted angles of every triangle (maximizing the smallest angle first). In the isotropic case, the theory of Delaunay triangulations guarantees that we have found a global maximum (which is the Delaunay triangulation of the point-set). When anisotropy is used, the triangulation is a local maximum but not necessarily a global maximum. In practice the difference is unimportant.

The initial triangulation is computed by inserting vertices incrementally into a large bounding triangle. The convex hull edges are guaranteed to appear because I force any flip that would reduce the number of triangles that touch the vertices of the bounding triangle. (I'm unsure whether doing this completely solves all the problems inherent to the bounding triangle approach.)

Anisotropic meshing

As in Ruppert's algorithm, the program eliminates "encroached" segments by inserting vertices at their midpoint. The only difference is that encroachment is verified after applying the transformation T assigned to the midpoint of the segment.

Then, the program locks every segment, determines what is the interior region, and starts attacking internal triangles of low quality by refinement (i.e. by inserting new vertices).

When grading is used, the quality of a triangle is defined to be its minimum distorted angle. When grading is not used, large triangles are penalized by dividing the minimum angle by the (distorted) perimeter of the triangle, squared. The power at which the perimeter is raised controls how much importance is given to the size of the triangle versus its shape. The current value was arbitrarily chosen to give pleasing results.

In Ruppert's algorithm, low quality triangles are removed by inserting a vertex at the circumcenter of the triangle. In the isotropic case, the triangle is Delaunay, therefore its circumcircle is empty and the circumcenter is a good place to insert a vertex. Furthermore, a Lemma guarantees that the circumcenter falls in the inside region (using the fact that the input is segment-bounded and that no segment is encroached). However in the anisotropic case there are some problems: the circumcircle is not necessarily empty. The circumcenter may fall arbitrarily close to another vertex or edge, or may even fall in the outside region. The program solves these problems by checking if the nearest neighbor of the circumcenter is a vertex of the triangle in question (as it would be in the isotropic case). If this does not hold, then we walk toward the centroid of the triangle and try again. After some number of consecutive failures, the program finally uses the centroid.

I also implemented the modifications for handling small angles, otherwise the program cannot mesh any interesting geometries.

[1] Jim Ruppert. A Delaunay Refinement Algorithm for Quality 2-Dimensional Mesh Generation. Journal or Algorithms 18(3):548-585, May 1995.


4. The Meshing Art Gallery

There are many mesh generation techniques out there to choose from. The technique implemented in mesh is probably best at dealing with complicated geometries. I invite you to look at the following "meshing art gallery" and see if you like the results obtained for the type of problems that interests you.


mesh A.poly -bottom -bottom -v400

mesh key.poly -g -a20

mesh trix.poly -swirl -v300

mesh square.poly -custom -v1000

mesh simple.poly -dline -dline -v1000

mesh point.poly -sink -perimeter -v400

5. Future Work

Speed

As the following table shows, mesh generates meshes in time that is roughly quadratic on the size of the output. This is because the code is somewhat sloppy on running time. I may improve the time complexity to a more respectable O(n log n) in the future.
   command                  time

mesh simple.poly -v125      0.016 s
mesh simple.poly -v250      0.041 s
mesh simple.poly -v500      0.113 s
mesh simple.poly -v1000     0.337 s
mesh simple.poly -v2000     1.071 s
mesh simple.poly -v4000     4.081 s
mesh simple.poly -v8000    19.713 s
mesh simple.poly -v16000   91.383 s

Smoothing

It should be possible to improve the meshes through optimization-based smoothing, preferably still taking into account anisotropy.


About This Document

This web page is presented to Jonathan Shewchuk as part of Project II for the course:
CS294-5 Meshing and Triangulation in Graphics, Engineering, and Modeling - Fall 1999.
This document is printer friendly.

Last updated: December 4, 1999