Triangulations in
It is not easy to implement these algorithms.
- Utrecht University, The Netherlands
- ETH Zurich, Switzerland
- Free University Berlin, Germany
- INRIA Sophia-Antipolis, France
- Max-Planck Institute Saarbrucken, Germany
- RISC Linz, Austria
- Tel Aviv University, Israel
Top
ON CGAL...
Consists of primitive, constant size geometric objects, such as points,
lines,
spheres, etc. and predicates on them, such as orientation test for points,
intersection tests, etc.
2.Standard Library
Contains standard geometric algorithms and data structures such as convex
hull,
smallest enclosing circle, and triangulation.
3.Support Library
Contains a support library, for example for I/O, visualization, and random
generators.
Currently the library contains mainly 2D or 3D objects but in the future
it will
support objects of arbitrary dimensions.
"A correct result of an algorithm can only be guaranteed if geometric predicates
are evaluated exactly."
Because of this, in CGAL there is strong emphasis on the specification
of
algorithms. It is always clear for which inputs and for which number types
a
correct result is guaranteed.
2.GENERALITY
To make the library as general as possible, C++ templates are heavily used.
This allows the user to choose an appropriate number type for doing
computations. To some extent it is even possible to replace a CGAL data
type with a user defined one.
3.EFFICIENCY
Such a CG library must be efficient to be really useful. Whenever possible
the
most efficient version of algorithm is used. Because a library algorithm
cannot be the best solution for every application, so sometimes multiple
versions of an algorithm are supplied.
4.EASE OF USE
The abundant uses of templates seem to make the library difficult to use
for
some people, but this can mostly be solved by using appropriate C++ typedefs.
The algorithms in the library contain many pre and post condition checks
that
help a lot when debugging. To facilitate using CGAL with existing code,
CGAL
types and algorithms are placed in namespace CGAL_.
Top
ON TRIANGULATION...
Bottom level - the base classes for vertices and faces store
geometric information such as the coordinates
of vertices and any other attribute needed by application.
- handle incidence and adjacency relations in terms of void* pointers,
allows easy change of
base classes w/out changing the rest of the structure.
Next level - the advantages for strong type
checking is reestablished.
- the triangulation data structure can be thought of as a container for
faces and vertices
- implements adjacency and incidence relations
Top level - the triangulation class implements
user interface with the triangulation.
- offers high level functionalities such as insertion & removal of
vertices,traversal of faces, etc.
- responsible for geometric embedding of triangulation
- Construction
Given a triangulation tr, a point pt can be inserted with tr.insert(pt).
If point pt coincides with an already
existing vertex, the triangulation is not changed. If it lies on an edge
two adjacent faces are split into two new
faces. If it lies inside a face, the face is split into three new faces.
And if it lies outside the crt triangulation,
point is connected to the visible faces of the CH in order to form new
faces.
Also, a whole range of points can be inserted using iterators in the following
fashion:
tr.insert(first, last), where first and last are input iterators.
Triangulation of 4 points
Extra interior point
Extra exterior point
All finite vertices can be accessed through a vertex iterator, defined
within the triangulation class:
Triangulation_2::Vertex_iterator. The value type of a vertex iterator is
a vertex. Method
vertices_begin() gives and iterator reffering to the first vertex in the
range, and vertices_end() is
the past-the-end iterator.
-Faces
A face is an object type that is defined locally within the
triangulation class: Triangulation_2::Face.
created automatically when a point is inserted. A face has 3 vertices:
f.vertex(0), f.vertex(1), f.vertex(2).
These methods return a pointer to the vertex, Vertex_handle. Conversely,
if v is a vertex then
f.index(v) returns the vertex index of v in f.
The vertices 0, 1, 2 are ordered in counterclockwise. In order to reach
the next vertex, faces have member functions ccw(i)
which returns i+1 (mod3) and cw(i) which returns i+2 (mod3).
Each face has three neighbors: f.neighbor(0), f.neighbor(1), f.neighbor(2).
These methods run a Face_handle that is the
pointer.
The neighbor with index i is always opposite the vertex with index i.
Relation between indices, vertices and neighbors
To test if a handle v refers to an infinite vertex, there is a method is_infinite(v).
There is also a
method for testing if a face has an infinite vertex which is is_infinite(f).
Similar to the vertex iterator there is also a face iterator: Triangulation_2::Face_iterator.
-Edges
Edges are not stored explicitly in the class. An edge is
defined by a pair of a face handle and an index, where the
index denotes
the edge between the face and the neighbor of that index. However, the
triangulation provides an iterator for edges. Given
an
object edge of type Edge, the face handle is accessed with edge.first,
and the index value with edge.second.
Relation between edge e, face_handle f, and index i.
Top
MY CONTRIBUTION
The following are the links to some of the available reports on
the web.
std::cout << tr << ; //tr being the varible of type Triangulation.
The output was in the following form:
5 6 2
-5 0 -1 1 3 4 0 0
0 1 3
1 2 3
4 2 1
2 4 3
4 0 3
0 4 1
1 4 5
3 0 2
1 5 3
4 1 2
0 3 5
2 0 4
** enter output here **
And nowhere in the reference manuals was a description of what this was. Furthermore, I couldn't get a chance to look at the code for the class "Triangulation", because the library comes with compiled code of all classes.
After reading through all the material about triangulations and just thinking about the output and with some insight from Ileana, I figured out what the output meant.
This is the
code that I wrote using face iterators, and vertex iterators, and handles
and dereferencing.
Using the output of my program, I could see which vertices were given
what indeces, and how they were defined.
So this is how it goes:
The first three integers outputted in the first line are the following
according to my insight and program.
leftmost # : total number of vertices including the dummy one at infinity.
middle #: total numer of faces after triangulation
rightmost # : is the dimension of the outputted data. (If there is only
one point it is 0D, if there are two it is 1D, and if there are
3(you can form the first triangle) it is 2D)
The second line gives the list of points according to their indeces. I
still don't know what order it is. It's not cw or ccw.
After that the first half of the list that follows is the list of faces,
given in the form of surrounding vertices. The numbers are the
indeces of the vertices in the order given in the second line.
The second half gives the list of the same faces this time in the form
of neighboring faces. The indeces of the neighboring faces are given by
the first half of the list. It will be better understood when I give an
example.
Let P be our point set = {(0, 0), (-1, 1), (3, 4), (-5, 0)}
Let's place them on the coordinate system:
So the following is our output:
5 6 2
// 4+1 = 5 vertices, 6 faces as can be seen on picture, and it is
2D
-5 0 -1 1 3 4 0 0
// list of vertices. P(-5, 0) has index 1, P(-1, 1) has index 2, and so
on. Dummy vertex
// at infinity has index 0.
0 1 3
// give this face index 0.
1 2 3
//face w/ index 1
4 2 1
//and so on...
2 4 3
4 0 3
0 4 1
// the last one has index 5.
1 4 5
//look at the face that is surrounded with faces 1,4 and 5. It is the same
one with index 0.
3 0 2
//face with index 1
1 5 3
//and so on...
4 1 2
0 3 5
2 0 4
I had to use the classes I've mentioned above to be able to write such
code, although I've never written code using such concepts. I had to learn
all about them, and I had to go through a lot of examples related to them.
I had to read different chapters on
the manuals on the uses of iterators, handles and dereferencing.
It was a challenge to figure it out but it was a lot of fun!- especially when I figured out what was happening. So I can say that my topic was NOT that boring after all :))