Navigation: Up, Table of Contents, Bibliography, Index, Title Page

Triangulations

Introduction

A simplicial complex is a set C of simplices which satisfy two conditions:

  1. Any face of a simplex in C is also a simplex in C
  2. Two simplices in C either do not intersect or their intersection is a simplex of smaller dimension which is their common face of maximal dimension.
The dimension of a complex C is the maximal dimension of the simplices of C. A complex of dimension d is said to be pure if any simplex in C is a face of a d-dimensional simplex of C. The domain of a complex C is the union of the simplices in C. A complex is said to be connected if its domain is connected.

A triangulation is a 2-dimensional simplicial complex which is pure connected and without singularities. Thus a triangulation can be viewed as a collection of triangular faces, such that two faces either have an empty intersection or share an edge or a vertex. The absence of singularities means that each edge belongs to at most two triangles and that each vertex belongs to a set of faces whose union forms a topological disk.

Each face of a triangulation can be given an orientation (clockwise or counterclockwise) which in turn induces an orientation on the edges incident to that face. The orientation of two adjacent faces are said to be consistent if they induce opposite orientations on their common incident edge. A triangulation is said to be orientable if the orientation of each face can be chosen in such a way that all pairs of incident faces have consistent orientations.

In this chapter we present a framework to represent orientable triangulations which may be embedded in a plane or in a higher dimensional space. Examples of such triangulations are triangulations of a simple polygons in the plane, the Delaunay triangulations of points in the plane, or triangulated irregular networks (TINs) which are used as terrain model in GIS. Any such triangulation can be described as a set of vertices and triangular faces, with incidence and adjacence relations: two facets or two vertices are said to be adjacent (or neighboring) if they are incident to the same edge, a facet and a vertex are said to be incident if they are incident to the same edge.

On top of this abstract view of a triangulation come different geometric layers which define the geometric information associated to a vertex (e.g., two-dimensional points for triangulations in the plane, or three-dimensional points for TINs) or to a face and which define the functionality of the triangulation. For example, the insertion of a point into a Delaunay triangulation or into TIN requires different update steps.

Design Rationale

Because a triangulation is merely a set of triangular faces with constant size complexity, triangulations are not implemented as a layer on top of a planar map. CGAL uses a proper internal representation of triangulations based on faces and vertices rather than on edges. Such a representation allows to save storage space and results in faster algorithms.

Thus the basic elements of the representation are vertices and faces. Each triangular face gives access to its three incident vertices and to its three adjacent faces. Each vertex gives access to one of its incident faces and through that face to the circular list of its incident faces. The edges are not explicitely represented, they are only represented through the adjacencies relations of two faces.

Figure:  The three layer design of triangulations.

Three_levels

The triangulations in CGAL are represented by a three layer structure analog to the design used for polyhedral surfaces, see Figure reference. In the bottom layer, the base classes for vertices and faces store some geometric informations such as the coordinate of vertices and any other attribute (such as color, constraint edges etc.) needed by the application. The base classes handle incidence and adjacency relations in term of void* pointers. The use of void* pointers in the bottom layer allows to easily change one of the base class, to deal with an extra attribute like a color for example, without having to change the rest of the structure. The advantages of strong type checking is reestablished in the next layer where the triangulation data structure can be thought of as a container for faces and vertices which can take care of all the combinatorial aspects of the triangulation. The triangulation data structure implements adjacency and incidence relations with type safe pointer operations and maintains the combinatorial integrity of the triangulation. For that purpose, the triangulation data structure defines its own face and vertex classes which are derived from the corresponding base classes so that geometric and additional information on vertices and faces are simply inherited. At last, at the top layer, the triangulation class implements the user interface with the triangulation. This classes offer to the user the high level functionalities that can be expected from a triangulation: insertion or removal of a vertex, traversal of the faces, enumeration of the vertices, traversal of the faces incident to a given vertex, location of a given point etc. The triangulation class defines its own vertex and face classes derived from the corresponding class of the triangulation data structure. The vertices and faces of the triangulation class are only accessed through high levels concepts such as handles, iterators, or circulators, according to the required functionalities of the access. The top layer triangulation class is responsible for the geometric embedding of the triangulation and comes in different flavors according to the kind of triangulation represented: planar triangulation of a set of points, Delaunay or regular or constrained triangulations etc.

The triangulation classes of CGAL depends on two template parameters. The first template parameter stands for a geometric traits class which is assumed to provide the geometric objects (points, segments and triangles) forming the triangulation and the geometric predicates on those objects. The second template parameter stands for a model of triangulation data structure acting as a container for faces and vertices while taking care of the combinatorial aspects of the triangulation. The triangulation data structure class is itself a template class parametrized by the base classes for faces and vertices.

Organization of this chapter

Section reference introduces the basic triangulation class of CGAL, Triangulation_2<Gt, Tds>, its local Vertex and Face classes and gives some examples for a simple use of this class. The Triangulation_2<Gt, Tds> class is merely designed to represent a triangulation for a set of points in the plane. The next section reference describes the requirements for the geometric traits class and presents some default implementations for this traits class offered in CGAL. Section reference presents the requirements for the triangulation data structure class, its local Vertex and Face classes and the default triangulation data structure class provided by CGAL. Section reference describes the requirements for the base classes Vertex_base and Face_base together with the defaults provided for these classes. The remaining sections of this chapter introduce several classes derived from the basic triangulation class and designed to handle more specific triangulations. Section reference present a class to maintain the Delaunay triangulation of a set of points in the plane. Section reference describe a class to maintain regular triangulations. While the Delaunay triangulation of a set of points is the dual of the Voronoi diagram of these points, regular triangulations are dual to weighted points power diagrams and appear as a generalization of Delaunay triangulations. Section reference describes a class to handle a constrained triangulation, that is a triangulation in which certain edges are enforced. Constrained triangulations allow in particular to deal with the triangulations of a planar polygons.

Triangulation of points in the plane

The basic triangulation class of CGAL is primarily designed to represent the triangulations of a set of points A in the plane. Such a triangulation has as its vertices the points of A and its domain covers the convex hull of A. It can be viewed as a planar partition of the plane whoses bounded faces are triangular. and cover the convex hull of A. The single unbounded face of this partition is the complementary of the convex hull of A. In many applications, such as Kirkpatrick's hierarchy or incremental Delaunay construction, it is convenient to deal only with triangular faces. Therefore, we add to the triangulation a fictitious vertex, called the infinite vertex and we make each convex hull edge incident to an infinite face having as third vertex the infinite vertex. In that way, each edge is incident to exactly two faces and special cases at the boundary of the convex hull are simpler to deal with.

Figure:  The infinite vertex.

Vertices at
infinity

The class Triangulation_2<Gt,Tds> implements this point of view and therefore considers the triangulation of the set of points as a set of triangular, finite and infinite faces. Although it is convenient to draw a triangulation as in figure reference, note that the infinite vertex has no significant coordinates and that no geometric predicate can be applied on it or on an infinite face.

A triangulation is a collection of vertices and faces that are linked together through incidence and adjacency relations. Each face give access to its three incident vertices and to its three adjacent faces. Each vertex give access to one of its incident faces.

The three vertices of a face are indexed with 0, 1 and 2 in counterclockwise order. The neighbor of a face are also indexed with 0,1,2 in such a way that the neighbor indexed by i is opposite to the vertex with the same index.

Many of the classes in the triangulation package offer two functions int cw(int i) and int ccw(int i) which given the index of a vertex in a face compute the index of the next vertex of the same face in clockwise or counterclockwise order. Thus, for example the neighbor neighbor(cw(i)) is the neighbor of f which is next to neighbor(i) turning clockwise around f. The face neighbor(cw(i)) is also the first face encountered after f when turning clockwise around vertex i of f.

Figure:  Vertices and neighbors.

Neighbors


A triangulation is valid from the combinatorial point of view if the following is true.
(a) Two adjacent faces have neighbor pointers to each other and they have two vertices in common. The faces have a coherent orientation, that is, they index their common vertices in opposite order.
(b) All faces that are incident to a vertex v must be linked with neighbor pointers. Vertex v points to an arbitrary incident face.

Furthermore, it is said to be geometrically valid iff
(c) Any face has its vertices indexed according to counterclockwise order.


Figure:  Validity test.

Validity

The Geometric Traits Class

The first template parameter of the triangulation classes of CGAL is the geometric traits class which provides the geometric objects (points, segments and triangles) building up the triangulation together with the geometric predicates on those objects. The first subsection of this section describes the requirements that the geometric traits class of the basic triangulation class Triangulation_2<Gt, Tds> has to fulfill. The second subsection presents some predefined geometric traits classes available in CGAL.

Requirements for the Geometric Traits Class

Predefined Geometric Traits Classes

The CGAL library provides some predefined geometric traits classes for the triangulations using the kernel geometric objects and predicates. These classes are themselves templated with a representation class.

CGAL provides also predefined geometric traits class Triangulation_euclidean_traits_yz_3<R> and Triangulation_euclidean_traits_zx_3<R> to deal with projections on the xz- or the yz-plane, respectively.

#include <CGAL/Triangulation_euclidean_traits_xz_3.h>
#include <CGAL/Triangulation_euclidean_traits_yz_3.h>

The Triangulation Data Structure

The second template parameter of the basic triangulation class Triangulation_2<Gt,Tds> is a triangulation data structure class. This class can be seen has a container for the faces and vertices maintaining incidence and adjacency relations. The triangulation data structure class is responsible for the combinatorial integrity of the triangulation (i. e. proper incidence and adjacency relations among vertices and faces) while allowing to perform combinatorial modifications such has insertion of a new vertex in a face, or in an edge, suppression of a vertex of degree three, flip of two edges. The term combinatorial means that those operation are purely topological and do not depend on the geometric embedding.

The triangulation data structure is itself a template class parametrized by the base classes Vertex_base and Face_base, and derives from thoses base classes its own vertex and face classes. This design allows to restore at the triangulation data structure level the strong type checking which does not exists at the base classes levels.

The following subsections list the requirements for a triangulation data structure and for its nested vertex and face classes. The default triangulation data structure provided by CGAL is describe next.

Requirements for a Triangulation Data Structure Class

Requirements for the Vertex Class of a Triangulation Data Strucure

Requirements for the Face Class of a Triangulation Data Structure

The Default Triangulation Data Structure

The Base Classes Vertex_base and Face_base

Requirements for the Vertex_base Class

Requirements for the Face_base Class

The Default Base Classes

CGAL provides two default base classes Triangulation_face_base_2<Gt> and Triangulation_vertex_base_2<Gt> which model respectively the Vertex_base and the Face_base concept. Both of them are templated by a geometric traits class. Using for these traits class, the geometric traits class used for the triangulation class is strongly recommended. It ensures that the point type defined by Triangulation_vertex_base_2<Gt> is the same as the point type defined the geometric traits class of the triangulation.

These default base classes can be used directly or can serve as a base to derive other base classes with some additional attribute (a color for example) tuned for a specific application.

#include <CGAL/Triangulation_face_base_2.h>
#include <CGAL/Triangulation_vertex_base_2.h>

Examples

Example

The following code creates a valid triangulation traits class for a triangulation of 2D points in usual Euclidean space and use it to define a triangulation class.


typedef Cartesian<double> Rp;
typedef Triangulation_euclidean_traits_2<Rp> Gt;
typedef Triangulation_vertex_base_2<Gt> Vb;
typedef Triangulation_face_base_2<Gt> Fb;
typedef Triangulation_default_data_structure_2<Gt,Vb,Fb > Tds;
typedef Triangulation_2<Gt,Tds> Triangulation;

Example

The following example derives a new Face_base class from the default one and add a color to the faces of the triangulation. The face of the triangulation data structure and the face of the triangulation will inherit the new data member and its functionality. Any kind of additional fonctionality can thus be added to faces or vertices of a triangulation as long as this functionality does not involve additional pointers to vertices or faces (because the base classes use only void* pointer and have no knowledge of the vertex or face types.).

/*  colored_face.C   */     
/*  ---------------- */
#include <CGAL/basic.h>
#include <CGAL/Cartesian.h>
#include <CGAL/IO/Color.h>
#include <CGAL/Triangulation_euclidean_traits_2.h>
#include <CGAL/Triangulation_default_data_structure_2.h>
#include <CGAL/Triangulation_2.h>

using namespace CGAL;
using namespace std;

/* A facet with a color member variable. */
template < class Gt >
class My_face_base : public Triangulation_face_base_2<Gt>
{
public:
  Color color;
  My_face_base() :
    Triangulation_face_base_2<Gt>() {}
  My_face_base(void* v0, void* v1, void* v2) : 
    Triangulation_face_base_2<Gt>(v0,v1,v2) {}
  My_face_base(void* v0, void* v1, void* v2, void* n0, void* n1, void* n2) : 
    Triangulation_face_base_2<Gt>(v0,v1,v2,n0,n1,n2) {}
};

typedef Cartesian<double> Rp;
typedef Triangulation_euclidean_traits_2<Rp> Gt;
typedef Triangulation_vertex_base_2<Gt> Vb;
typedef My_face_base<Gt> Fb;
typedef Triangulation_default_data_structure_2<Gt,Vb,Fb > Tds;
typedef Triangulation_2<Gt,Tds> Triangulation;
typedef Triangulation::Face_handle Face_handle;
typedef Triangulation::Face_iterator Face_iterator;
typedef Triangulation::Vertex_handle Vertex_handle;
typedef Point_2<Rp>  Point;

int main() {
  Triangulation t;
  Point p;

  while (std::cin >> p){
    t.insert(p);
  }
  Face_iterator fc = t.faces_begin();
  while (fc != t.faces_end()) {
    fc->color = BLUE;
    ++fc;
  }
  return 1;
}

Delaunay Triangulations

The Class Delaunay_triangulation_2<Gt,Tds>

Requirements for the Geometric Traits of a Delaunay Triangulation

In addition to the requirements described in section reference for the geometrics traits of any triangulation, the geometrics traits of a Delaunay triangulation has to provide a side_of_oriented_circle test and some additional types. The in_circle test is the test used to maintain the empty circle property and actually defines the triangulation. The additional types Line, Direction and Ray are used to describe the dual Voronoi diagram. The additional Distance type is only used by the nearest_vertex(..) query and the requirements for this type are given below.

Requirements for the Line, Direction and Ray Classes

Each of the three classes Line, Direction and Ray must know the two others. In addition, the Line class is required to have the two following member functions:

The Ray class must define a Point class which is the same as Gt::Point is required to have the following constructor:

Predefined Geometric Traits Class

The class Triangulation_euclidean_traits_2<R> introduced in section reference is designed to be the geometric traits class of a Delaunay triangulation. It implements the usual Euclidean metric for the two dimensional points Points_2<R>. Three traits classes are provided to deal with the Delaunay triangulation of two dimensional points which are the xy, yz or zx projections of three dimensional points:
Triangulation_euclidean_traits_xy_3<R>,
Triangulation_euclidean_traits_yz_3<R>, and
Triangulation_euclidean_traits_zx_3<R>
The requirements for the duality functions are not yet satisfied by these last three classes.

Regular triangulations

Let PW = {(pi, wi), i = 1, ..., n } be a set of weighted points where each pi is a point and each wi is a scalar called the weight of point pi. Alternatively, each weighted point (pi, wi) can be regarded as a two dimensional sphere with center pi and radius ri=sqrt(wi).

The power diagram of the set PW is a planar partition such that each cell corresponds to sphere (pi, wi) of PW and is the locus of points p whose power with respect to (pi, wi) is less than its power with respect to any other sphere (pj, wj) in PW. The dual of this diagram is a triangulation whose domain covers the convex hull of the set P= { pi, i = 1, ..., n } of center points and whose vertices are a subset of P. Such a triangulation is called a regular triangulation. The three points pi, pj and pk of P form a triangle in the regular triangulation of PW iff there is a point p of the plane whose powers with respect to (pi, wi), (pj, wj) and (pk, wk) are equal and less than the power of p with respect to any other sphere in PW.

Let us defined the power product of two weighted points (pi, wi) and (pj, wj) as:

(pi, wi,pj, wj) = pipj 2 - wi - wj .

(pi, wi,pj, 0) is simply the power of point pj with respect to the sphere (pi, wi), and two weighted points are said to be orthogonal if their power product is null. The power circle of three weighted points (pi, wi), (pj, wj) and (pk, wk) is defined as the unique circle (, ) orthogonal to (pi, wi), (pj, wj) and (pk, wk).

The regular triangulation of the sets PW satisfies the following regular property (which just reduces to the Delaunay property when all the weights are null): a triangle pipjpk of the regular triangulation of PW is such that the power product of any weighted point (pl, wl) of PW with the power circle of (pi, wi), (pj, wj) is (pk, wk) is positive or null. We call power test of the weighted point (pl, wl) with respect to the face pipjpk, the predicates which amount to compute the sign of the power product of (pl, wl) with respect to the power circle of (pi, wi), (pj, wj) is (pk, wk), which is given by the following determinant

|
1 1 1 1
xi xj xk xl
yi yj yk yl
xi 2 + yi 2 -wi xj 2 + yj 2 - wj xk 2 + yk 2 - wk xl 2 + yl 2 -wl
|

A pair of neighboring faces pipjpk and pipjpl is said to be locally regular (with respect to the weights in PW) if the power test of (pl,wl) with respect to pipjpk is positive. A classical result of computational geometry establishes that a triangulation of the convex hull of P such that any pair of neighboring faces is regular with respect to PW, is a regular triangulation of PW.

Alternatively, the regular triangulation of the weighted points set PW can be obtained as the projection on the two dimensional plane of the convex hull of the set of three dimensional points P'= { (pi,pi 2 - wi ), i = 1, ..., n }.

The Regular Triangulation Class

Example

The following code fragment creates a regular triangulation of a set of weighted points.

/*     regular.C */
/*-------------- */
#include <CGAL/basic.h>
#include <iostream>
#include <CGAL/Cartesian.h>
#include <CGAL/Regular_triangulation_euclidean_traits_2.h>
#include <CGAL/Regular_triangulation_2.h>

using namespace CGAL;

typedef Cartesian<double> Rp;
typedef double W;
typedef Regular_triangulation_euclidean_traits_2<Rp,W>  Gt;
typedef Triangulation_vertex_base_2<Gt> Vb;
typedef Regular_triangulation_face_base_2<Gt> Fb;
typedef Triangulation_default_data_structure_2<Gt,Vb,Fb > Tds;
typedef Regular_triangulation_2<Gt, Tds> Regular_triangulation;

int main()
{
   Regular_triangulation rt;

   Gt::Weighted_point wp;
   while(std::cin >> wp){
     std::cout << wp << std::endl;
     rt.insert(wp);
   }
   rt.is_valid();
   return 1;	
}

The Base Face Type of a Regular Triangulation

The regular triangulation of a set of weighted point does not necessarily have one vertex for each of the input points. Some of the input weigthed points have no cell in the dual power diagrams and therefore do not correspond to a vertex of the regular triangulation. Those weighted point are said to be hidden points. A point which is hidden at a given time may appear later as a vertex of the regular triangulation upon removal on some other weighted point. Therefore, hidden points have to be stored somewhere. A hidden point can appear as vertex of the triangulation only when the two dimensional face where its point component is located (the face which hides it) is removed. Therefore we decided to store each hidden point in the face which hides it and the nested face type of a regular triangulation is assumed to include a list of hidden weighted points. This list of weighted point is in fact included in the base face of a regular triangulation.

Requirements for the Base Face Class of a Regular Triangulation

The base face type of a regular triangulation has to fulfiils the following requirements in addition to those of section reference

A Default Base Face Class for Regular Triangulations.

CGAL provides the templated class Regular_triangulation_face_base_2<Gt> which derives from Triangulation_face_base_2<Gt> and can be used as a default base class for faces of regular triangulations.

#include <CGAL/Regular_triangulation_face_base_2.h>

The Geometric Traits class of a Regular Triangulation

Requirements

A Predefined Geometric Traits Class

CGAL provides the predefined geometric traits class
Regular_triangulation_euclidean_traits_2<Rep,Weight>. This traits class is templated by a representation class Rep and a weight type Weight. This class inherits from Triangulation_euclidean_traits_2 <Rep > and uses a Weighted_point type derived from the type Point of Triangulation_euclidean_traits_2 < R >.

Weighted Points

requirements for a weighted-point

Default Class for a Weighted Point

CGAL provides the class Weighted_point<Point,Weight> as a default type for a weighted two dimensional point. This default type has two template parameters Point and Weight which have to be instantiated respectively with a point type and a weight type. The class Weighted_point<Point,Weight> inherits from Point.

Constrained Triangulations

A constrained triangulation is a triangulation of a set of points which has to include among its edges a given set of segments joining the points. The corresponding edges are called constrained edges.

The set of points defining the vertices of the triangulation includes the set of constrained edges endpoints. It may include other points (considered as null length constrained edges) as well. The set of constrained edges forms a set of segments which do not intersect except possibly at their endpoints. Any number of constrained edges are allowed to share the same endpoint. Vertical constrained edges or constrained edges with null length are allowed.

A set of
constraints and its constrained triangulation

The Face Type of a Constrained Triangulation

The information about constrained edges is store in the faces of the triangulation. Thus the nested Face type of a constrained triangulation offers additonnal functionalities to deal with this information. This additional functionalities related to the constraints are requirements which have to be fulfilled by the base face a constrained triangulation in addition to the functionalities required in section reference They are listed below as such.

Of course CGAL provides a default Face_base class for the constrained triangulation. The class Constrained_triangulation_face_base_2<Gt> simply derived from Triangulation_face_base_2<Gt> and override the functions reorient(), ccw_permute() and cw_permute().

#include <CGAL/Constrained_triangulation_face_base_2.h>

A Constrained Triangulation Class for Animation Purposes

Constrained Delaunay Triangulations

A constrained Delaunay triangulation is a triangulation with constrained edges which tries to be as much Delaunay as possible. As constrained edges are not necessarily Delaunay edges, the triangles of a constrained Delaunay triangulation do not necessarily fulfill the empty circle property but they fulfill a weaker constrained empty circle property. To state this property, it is convenient to think of constrained edges as blocking the view. Then, a triangulation is constrained Delaunay if the circumscribing circle of any of its triangular faces includes in its interior no vertex that is visible from the interior of the triangle.

The Class Constrained_Delaunay_triangulation_2<Gt,Tds>


Navigation: Up, Table of Contents, Bibliography, Index, Title Page
The GALIA project. Jan 18, 2000.