Elif Tosun
274b-ab
Spring 2000
CS274 Computational Geometry

Back to 274b-ab homepage
 


CSC 274
FINAL PROJECT:

Triangulations in




                                                                                 
 
 


INTRODUCTION ON CGAL... ON TRIANGULATION...                             - Design
                            - Construction
                            - Access
                                    -Vertices
                                    -Faces
                                    -Edges

MY CONTRIBUTION



 
 
 


INTRODUCTION

          Geometric Algorithms are used in many application domains such as computer
          graphics, robotics, geographic information systems, computer vision, etc.

                                                

                                                        

          It is not easy to implement these algorithms.

         It is a well-designed Computational Geometry Algorithms Library used with the
         programming language C++.             It is created by a group of Computational geometrists from several institutions
          around the world:

          - 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...

        1.The Elementary Part: -the Kernel

              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.
 
 

              Since CGAL is desinged for the use of several different groups of people such as,  to fullfill the demand of these different users, CGAL is based on a number of design goals such as robustness, generality,
 efficiency and ease of use.
                1.ROBUSTNESS
                   In CGAL the following rule is used:

                  "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...

        A triangulation is a 2D simplicial complex which is purely connected and is without singularities. Basically it is a collection of triangular faces, such
        that two faces either have no intersetion or they share an edge or a vertex. Each edge belongs to at most two triangles.

                                    
 

                            - Design
                                CGAL uses a proper internal representation of triangulations based on faces and vertices, rather than edges. This saves storage place  and results in faster algorithms .So, the basic elements of a triangulation is its faces and vertices.  Using each triangle the user can access the three incident vertices and the adjacent faces. Each vertexgives access to one of its incident faces. Triangulations in CGAL are represented by a three-level structure:

                                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
 
 
 
 

                            - Access
                                    -Vertices
                                A triangulation is stored as a collection of vertices and faces. A vertex is an object type that is defined locally
                                    within the triangulation class: Triangulation_2::Vertex. Vertices are created automatically when a point is
                                    inserted. The point associated with the vertex can be accessed through v.point().- of type Point_2.
                                    Each triangulation has a special vertex at infinity.
                                                                    
                                                                                                            Vertex at infinity

                                      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

             I have downloaded and installed CGAL from their webpage. Since it was for research purposes it was for free.
               I have installed the library as local files in a Linux operating system. The download and installation process wasn't very hard with the help of the
                installation manual, available for download with the library on the site.
               I also had to figure out how to compile and run programs since we also installed a new compiler g ++ GNU 2.95, since this was the only
                compatible compiler with the newest version of CGAL.              There aren't very many papers on CGAL. The most helpful search results were the technical reports, project
                workpackages, and the reference manuals. I mostly used the "Getting_Started" manual that comes with the download of the library. It gives a
                crash introduction on several aspects of the library, with example programs.

             The following are the links to some of the available reports on the web.
 
 

             Since I was working on the triangulation library of CGAL, I followed the Triangulations Chapter in the Getting Started
                manual. However, in the first example program ** enter link here **, the output was impossible to identify.
                The program just prints out the triangulation using the following instruction:

                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.

                So, my contribution to the project was to figure out what this list of numbers actually meant by exploring the uses of faces, vertices, and some other aspects of the library such as the "is_infinite()" method.

                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  :))

Top