Você está na página 1de 53

sid.inpe.br/mtc-m21b/2015/06.02.18.

30-MAN

DESCRIPTION OF A C++ IMPLEMENTATION OF


THE INCREMENTAL ALGORITHM TO GENERATE
THE DELAUNAY TRIANGULATION

Henrique Rennó de Azeredo Freitas

URL do documento original:


<http://urlib.net/8JMKD3MGP3W34P/3JJUR2L>

INPE
São José dos Campos
2015
PUBLICADO POR:

Instituto Nacional de Pesquisas Espaciais - INPE


Gabinete do Diretor (GB)
Serviço de Informação e Documentação (SID)
Caixa Postal 515 - CEP 12.245-970
São José dos Campos - SP - Brasil
Tel.:(012) 3208-6923/6921
Fax: (012) 3208-6919
E-mail: pubtc@sid.inpe.br

COMISSÃO DO CONSELHO DE EDITORAÇÃO E PRESERVAÇÃO


DA PRODUÇÃO INTELECTUAL DO INPE (DE/DIR-544):
Presidente:
Marciana Leite Ribeiro - Serviço de Informação e Documentação (SID)
Membros:
Dr. Gerald Jean Francis Banon - Coordenação Observação da Terra (OBT)
Dr. Amauri Silva Montes - Coordenação Engenharia e Tecnologia Espaciais (ETE)
Dr. André de Castro Milone - Coordenação Ciências Espaciais e Atmosféricas
(CEA)
Dr. Joaquim José Barroso de Castro - Centro de Tecnologias Espaciais (CTE)
Dr. Manoel Alonso Gan - Centro de Previsão de Tempo e Estudos Climáticos
(CPT)
Dra Maria do Carmo de Andrade Nono - Conselho de Pós-Graduação
Dr. Plínio Carlos Alvalá - Centro de Ciência do Sistema Terrestre (CST)
BIBLIOTECA DIGITAL:
Dr. Gerald Jean Francis Banon - Coordenação de Observação da Terra (OBT)
Clayton Martins Pereira - Serviço de Informação e Documentação (SID)
REVISÃO E NORMALIZAÇÃO DOCUMENTÁRIA:
Simone Angélica Del Ducca Barbedo - Serviço de Informação e Documentação
(SID)
Yolanda Ribeiro da Silva Souza - Serviço de Informação e Documentação (SID)
EDITORAÇÃO ELETRÔNICA:
Marcelo de Castro Pazos - Serviço de Informação e Documentação (SID)
André Luis Dias Fernandes - Serviço de Informação e Documentação (SID)
sid.inpe.br/mtc-m21b/2015/06.02.18.30-MAN

DESCRIPTION OF A C++ IMPLEMENTATION OF


THE INCREMENTAL ALGORITHM TO GENERATE
THE DELAUNAY TRIANGULATION

Henrique Rennó de Azeredo Freitas

URL do documento original:


<http://urlib.net/8JMKD3MGP3W34P/3JJUR2L>

INPE
São José dos Campos
2015
Esta obra foi licenciada sob uma Licença Creative Commons Atribuição-NãoComercial 3.0 Não
Adaptada.

This work is licensed under a Creative Commons Attribution-NonCommercial 3.0 Unported Li-
cense.

ii
ABSTRACT

This work describes the data structures and procedures developed as a C++
implementation of the Incremental algorithm to calculate a triangulation called
Delaunay triangulation, which is often used in several scientific applications as, for
example, in the modeling of terrain surfaces. The implementation includes functions
that perform computational geometry tasks on a set of points used as input and
then generates a set of triangles as output.

iii
DESCRIÇÃO DE UMA IMPLEMENTAÇÃO EM C++ DO
ALGORITMO INCREMENTAL PARA GERAR A TRIANGULAÇÃO
DE DELAUNAY

RESUMO

Este trabalho descreve as estruturas de dados e os procedimentos desenvolvidos


como uma implementação em C++ do algoritmo Incremental para calcular uma
triangulação chamada triangulação de Delaunay, a qual é muito utilizada em diversas
aplicações científicas como, por exemplo, na modelagem de superfícies de terreno. A
implementação inclui funções que executam tarefas de geometria computacional em
um conjunto de pontos utilizados como entrada e gera um conjunto de triângulos
como saída.

v
LIST OF FIGURES

Page

2.1 Delaunay triangulation criteria . . . . . . . . . . . . . . . . . . . . . . . 3

3.1 Enclosing triangle of the set of points . . . . . . . . . . . . . . . . . . . . 5


3.2 Illegal edge . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
3.3 Rotating an edge maximizes interior angles of triangles . . . . . . . . . . 7
3.4 Tree structure reflects triangles divisions . . . . . . . . . . . . . . . . . . 7

vii
CONTENTS

Page

1 INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . . . . . 1

2 DELAUNAY TRIANGULATION . . . . . . . . . . . . . . . . . . 3

3 INCREMENTAL ALGORITHM . . . . . . . . . . . . . . . . . . . 5

4 CONCLUSIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

REFERENCES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

ANNEX A - DATA STRUCTURES . . . . . . . . . . . . . . . . . . . 13

ANNEX B - GLOBAL VARIABLES . . . . . . . . . . . . . . . . . . . 15

ANNEX C - ENCLOSING TRIANGLE . . . . . . . . . . . . . . . . . 17

ANNEX D - DELAUNAY TRIANGULATION . . . . . . . . . . . . . 19

ANNEX E - GEOMETRIC FUNCTIONS . . . . . . . . . . . . . . . . 31

ANNEX F - UTILITY FUNCTIONS . . . . . . . . . . . . . . . . . . . 39

ix
1 INTRODUCTION

Triangulations are structures generally comprised of several adjacent triangles of


different sizes and shapes which are usually generated from a set of points distributed
over space, where each point can be defined by a triple (x, y, z) with x and y as
the coordinates on the horizontal plane and z as a particular value associated to the
point (x, y).

These structures have relevant and useful applications in many areas of natural
sciences since digital elevation models are efficiently represented by triangulations
(PETRIE; KENNIE, 1987; JONES et al., 1990; BERG et al., 2008) where the density
of information can vary from region to region, thus avoiding data redundancy and
producing a model that better adapts to the irregularities of the terrain.

The present work describes all the data structures and procedures developed as
a C++ implementation of the Incremental algorithm to generate a particular
triangulation called Delaunay triangulation.

1
2 DELAUNAY TRIANGULATION

A triangulation calculated from a set of points in the plane is defined as a subdivision


of the plane such that any three points of the set are connected by edges to form the
vertices of a triangle and all the edges of the triangulation do not intersect each other
at points different from the vertices. Many distinct triangulations can be calculated
from the same set of points and one particular triangulation is called the Delaunay
triangulation (BERG et al., 2008), which avoids the generation of skinny triangles.

The main property of the Delaunay triangulation is that each triangle defines a
circle through its three vertices that does not contain any other point of the set
in its interior, so that this property is considered as a criteria for calculating
the triangulation (TSAI, 1993). As a consequence of this property, the Delaunay
triangulation presents more equiangular triangles and the minimum angle among
all the triangles is maximized. Figure 2.1 shows a Delaunay triangulation together
with the Delaunay criteria for a circle defined by the three vertices of a triangle.

Figure 2.1 - Delaunay triangulation criteria


SOURCE: adapted from Jones et al. (1990)

The Delaunay triangulation can be generated by several different algorithms found


in the literature, each one with a specific approach. Some of these algorithms are:
Bowyer-Watson (BOWYER, 1981; WATSON, 1981), Incremental (GUIBAS et al., 1992;
BERG et al., 2008), Divide-and-Conquer (CIGNONI et al., 1998), Fortune (FORTUNE,
1987) and Brute Force (O’ROURKE, 1998). This work describes the Incremental
algorithm, which presents a time complexity of O(n log n) (BERG et al., 2008) as an
upper bound for the running time of the algorithm with an input dataset of size n.
A C++ implementation of the algorithm is also given, with the data structures for
points and triangles listed in annex A and all the global variables listed in annex B.

3
3 INCREMENTAL ALGORITHM

The first step of the Incremental algorithm is to define a triangle that contains the
whole set of points to be triangulated located in its interior. In addition, each one
of its vertices cannot be inside the circle that passes through any three points of the
set, thus respecting the Delaunay criteria.

The coordinates of the vertices of this initial triangle are defined by a constant
value K calculated from a point P that defines the width and height of an enclosing
rectangle of the set of points as presented by Vomacka (2008) apud Zalik and
Kolingerova (2003), where these authors consider the value of K as ten times greater
than the larger rectangle dimension, either width or height.

This work considers the value of K calculated from a straight line with a slope equals
to −1, where this line is translated up and to the right in relation to the point P,
so that the intersections between the line and both the x and y axes determine the
points (K, 0) and (0, K), respectively. The initial enclosing triangle is then defined
by the vertices (K, 0), (0, K) and (−K, −K) as illustrated in figure 3.1, where the
black rectangle represents the enclosing rectangle of the set of points. The source
code that defines the enclosing triangle is in annex C.

Figure 3.1 - Enclosing triangle of the set of points


SOURCE: adapted from Vomacka (2008)

After defining the enclosing triangle, each point of the set is inserted one at a time
into the current triangulation, then new edges are created and connected to the
inserted point. These new edges are either connected to each one of the three vertices
of the triangle that contains the point, if the point is located inside the triangle, or to

5
the vertices opposite to an edge shared by two triangles, if the point is exactly on an
edge. The new edges of the triangles created are then considered as Delaunay edges,
i.e., these edges respect the Delaunay criteria since the circle that passes through
them does not include any other point in its interior.

However, the edges of each divided triangle need to be checked whether they are
still Delaunay edges as a circle passing through both the points of one of the edges
and also through the inserted point may include another point of the set inside it.
In this case, the edge will be considered illegal. Figure 3.2 exhibits an example of
illegal edge, where the circle that passes through the points of the edge pi pj and also
through the point pk includes the point pl in its interior.

Figure 3.2 - Edge pi pj is illegal


SOURCE: Berg et al. (2008)

Furthermore, when a triangle edge is considered illegal, it is modified by a rotation


operation and its new points are the points opposite to the edge before the rotation,
so that both the triangles that shared the edge before it is rotated are also changed
into two new triangles. The rotated edge becomes a Delaunay edge since the interior
angles of the new triangles is maximized as shown in figure 3.3, where two skinny
triangles are changed after the rotation of the edge pi pj to pk pl .

An edge rotation can make the other two edges of the triangles that existed before the
rotation become illegal. These edges also need to be checked if they are still Delaunay
edges, otherwise they are rotated as well. This procedure of checking and rotating
recursively repeats until no more edges are illegal. Therefore the triangulation is
locally changed and triangles are modified around the inserted point.

6
Figure 3.3 - Rotating an edge maximizes interior angles of triangles
SOURCE: adapted from Berg et al. (2008)

In the programming level, for the previously mentioned modifications to be correctly


applied to the triangulation, the triangle structure holds the information of each
adjacent triangle as a pointer reference and these references change with each edge
rotation in order to ensure that the adjacency relationships are maintained.

The Incremental algorithm uses a tree structure for the storage of the triangles as
its nodes, where divided triangles and new triangles created are then connected in
the tree by hierarchical links that indicate the triangles divisions. The new triangles
are stored as children of the divided triangles, so that each triangle has three or two
children depending on whether the inserted point is located inside a triangle or on
an edge, respectively. At the end, Delaunay triangles are leaf nodes of the tree and
the enclosing triangle, together with all its incident edges, is discarded. An example
of how the triangles and the tree structure are modified after a point is inserted
can be visualized in figure 3.4. The source code of the Incremental algorithm that
calculates the Delaunay triangulation is in annex D with specific geometric and
utility functions in annexes E and F, respectively.

Figure 3.4 - Tree structure reflects triangles divisions


SOURCE: adapted from Berg et al. (2008)

7
4 CONCLUSIONS

The implementation in a programming language of the Incremental algorithm


to generate the Delaunay triangulation is not a trivial problem. Despite being
comprised of simple recursive procedures, there are many details related to the
information that is stored in the data structures and also to particular tasks of
computational geometry that must be solved for the algorithm to work properly.

This work presented the source code of the Incremental algorithm written in the
C++ programming language with data structures and procedures developed as a
set of several functions that can be used in a computational geometry library as an
alternative implementation to generate the Delaunay triangulation.

9
REFERENCES

BERG, M. de; CHEONG, O.; KREVELD, M. v.; OVERMARS, M.


Computational geometry: algorithms and applications. 3. ed. Santa Clara, CA,
USA: Springer-Verlag, 2008. 191-205 p. ISBN 978-3-540-77973-5. 1, 3, 6, 7

BOWYER, A. Computing Dirichlet tessellations. The Computer Journal, v. 24,


n. 2, p. 162–166, 1981. 3

CIGNONI, P.; MONTANI, C.; SCOPIGNO, R. DeWall: A fast divide and conquer
Delaunay triangulation algorithm in Ed. Computer-Aided Design, v. 30, n. 5,
p. 333–341, Apr 1998. 3

FORTUNE, S. A sweepline algorithm for Voronoi diagrams. Algorithmica, v. 2,


p. 153–174, 1987. 3

GUIBAS, L. J.; KNUTH, D. E.; SHARIR, M. Randomized incremental


construction of Delaunay and Voronoi diagrams. Algorithmica, v. 7, n. 1-6, p.
381–413, Jun 1992. 3

JONES, N. L.; WRIGHT, S. G.; MAIDMENT, D. R. Watershed delineation with


triangle-based terrain models. Journal of Hydraulic Engineering - ASCE,
v. 116, n. 10, p. 1232–1251, Oct 1990. 1, 3

O’ROURKE, J. Computational geometry in C. 2. ed. New York, NY, USA:


Cambridge University Press, 1998. ISBN 0521640105. Available from:
<http://cs.smith.edu/~orourke/books/compgeom.html>. 3

PETRIE, G.; KENNIE, T. J. M. Terrain modelling in surveying and civil


engineering. Computer-Aided Design, Butterworth-Heinemann, Newton, MA,
USA, v. 19, n. 4, p. 171–187, May 1987. ISSN 0010-4485. 1

TSAI, V. J. D. Delaunay triangulations in TIN creation: an overview and a


linear-time algorithm. International Journal of Geographical Information
Systems, v. 7, n. 6, p. 501–524, 1993. 3

VOMACKA, T. Delaunay triangulation of moving points in a plane. 2008.


University of West Bohemia, Pilsen. 5

WATSON, D. F. Computing the n-dimensional Delaunay tessellation with


application to Voronoi polytopes. The Computer Journal, v. 24, n. 2, p.
167–172, 1981. 3

11
ZALIK, B.; KOLINGEROVA, I. An incremental construction algorithm for
Delaunay triangulation using the nearest-point paradigm. International Journal
of Geographical Information Science, v. 17, n. 2, p. 119–138, 2003. 5

12
ANNEX A - DATA STRUCTURES
s t r u c t POINT
{
// p o i n t c o o r d i n a t e s
double x , y , z ;
// p o i n t memory a d d r e s s
s t r u c t POINT ∗ a d d r e s s ;
// p o i n t i n d e x i n v e c t o r
int point_index ;
// f l a g s
bool p r o c e s s e d , v i s i t e d ;
};

s t r u c t TRIANGLE
{
// p o i n t s o f t h e t r i a n g l e
s t r u c t POINT p_i , p_j , p_k ;
// number o f c h i l d r e n and p a r e n t s o f t h e t r i a n g l e
i n t n u m b e r _ o f _ c h i l d r e n , number_of_parents ;
// r e f e r e n c e s t o t h e c h i l d r e n , a d j a c e n t and p a r e n t s o f
// t h e t r i a n g l e
s t r u c t TRIANGLE ∗∗ c h i l d r e n , ∗ a d j a c e n t [ 3 ] , ∗ p a r e n t s [ 2 ] ;
// t r i a n g l e i n d e x i n v e c t o r
int triangle_index ;
// c i r c u m c e n t e r c o o r d i n a t e s o f t h e c i r c u n f e r e n c e d e f i n e d
// f r o m t h e 3 p o i n t s o f t h e t r i a n g l e
double xc , yc ;
// c i r c u n f e r e n c e r a d i u s
double r ;
// f l a g s
bool p r o c e s s e d , v i s i t e d ;
};

13
ANNEX B - GLOBAL VARIABLES
// p o i n t s v e c t o r
v e c t o r <s t r u c t POINT> p o i n t s ;
// 3 p o i n t s o f e n c l o s i n g t r i a n g l e
s t r u c t POINT p_0 , p_1 , p_2 ;
// r o o t n o d e o f t r i a n g l e s t r e e
s t r u c t TRIANGLE ∗ t r i a n g l e s _ t r e e ;
// f l a g s t o i n d i c a t e i f p o i n t i s on an e d g e
bool s a m e _ s l o p e _ i j , same_slope_jk , s a m e _ s l o p e _ k i ;
// D e l a u n a y t r i a n g l e s v e c t o r
v e c t o r <s t r u c t TRIANGLE ∗> d e l a u n a y _ t r i a n g l e s ;
// e r r o r v a l u e f o r v e r t i c e s
const double e p s V e r t e x = 1 . e −5;
// e r r o r v a l u e f o r e d g e s
const double epsEdge = 1 . e −6;
// c o n s t a n t u n d e f i n e d v a l u e
const double UNDEF = − 9 9 9 9 . ;
// b a s e c o o r d i n a t e X, minimum v a l u e o f x
const double BASE_X = 0 . ;
// b a s e c o o r d i n a t e Y, minimum v a l u e o f y
const double BASE_Y = 0 . ;

15
ANNEX C - ENCLOSING TRIANGLE
// d e f i n e t h e c o o r d i n a t e s o f t h e p o i n t s p0 , p1 , p2 o f t h e
// e n c l o s i n g t r i a n g l e o f a s e t o f p o i n t s p i n t h e p l a n e
//
// t h e c o o r d i n a t e s a r e c a l c u l a t e d r e l a t i v e t o an
// e n c l o s i n g r e c t a n g l e
//
// w i t h t h e maximum p o i n t ( max_x+INC , max_y+INC ) o f t h e
// r e c t a n g l e d e f i n e d , t h e p o i n t s ( 0 ,K) and (K, 0 ) o f t h e
// t r i a n g l e a r e c a l c u l a t e d f r o m t h e i n t e r s e c t i o n o f t h e
// l i n e w i t h s l o p e = −1 (−45 o ) t h a t p a s s e s t h r o u g h t h e
// maximum p o i n t and i n t e r s e c t s t h e x and y a x e s .
// t h e l a s t p o i n t i s d e f i n e d w i t h c o o r d i n a t e s (−K,−K)
void d e f i n e _ e n c l o s i n g _ t r i a n g l e ( v e c t o r <s t r u c t POINT> &p )
{
int i ;
double max_x , max_y , K, INC ;
s t r u c t TRIANGLE t ;

// d e f i n e t h e increment in coordinates
INC = 1 0 . ;

// d e f i n e maximum c o o r d i n a t e s i n x and y
max_x = − 1 . ;
max_y = − 1 . ;
f o r ( i = 0 ; i < p . s i z e ( ) ; i ++)
{
i f ( p [ i ] . x > max_x )
max_x = p [ i ] . x ;
i f ( p [ i ] . y > max_y )
max_y = p [ i ] . y ;
}

// d e f i n e maximum c o o r d i n a t e s o f t h e e n c l o s i n g
// r e c t a n g l e i n c r e m e n t e d b y INC s h i f t i n g up and right
max_x += INC ;
max_y += INC ;

// d e f i n e c o o r d i n a t e s o f p o i n t s p0 , p1 , p2 w i t h
// K = max_x + max_y g i v e n b y t h e e q u a t i o n
// (K − max_y ) / ( 0 − max_x ) = −1 o f t h e l i n e t h a t p a s s e s
// t h r o u g h t h e p o i n t s ( 0 ,K) and ( max_x , max_y ) w i t h
// s l o p e = −1
K = max_x + max_y ;
// m u l t i p l y K b y a c o n s t a n t
K ∗= INC ;

// c o o r d i n a t e s of p o i n t s p0 , p1 , p2
p_0 . x = −K;
p_0 . y = −K;
p_1 . x = 0 . ;
p_1 . y = K;
p_2 . x = K;
p_2 . y = 0 . ;

// d e f i n e r e f e r e n c e s of the enclosing triangle points


p_0 . a d d r e s s = &p_0 ;
p_1 . a d d r e s s = &p_1 ;
p_2 . a d d r e s s = &p_2 ;

// d e f i n e e n c l o s i n g t r i a n g l e p0 , p1 , p2
t . p_i = p_0 ;
t . p_j = p_1 ;
t . p_k = p_2 ;
t . number_of_children = 0 ;
t . c h i l d r e n = NULL ;
t . number_of_parents = 0 ;
f o r ( i = 0 ; i < 2 ; i ++)
t . p a r e n t s [ i ] = NULL ;
f o r ( i = 0 ; i < 3 ; i ++)
t . a d j a c e n t [ i ] = NULL ;
t . t r i a n g l e _ i n d e x = −1;
t . processed = false ;
t . visited = false ;

// a l l o c a t e memory t o reference a tree of triangles

17
t r i a n g l e s _ t r e e = ( s t r u c t TRIANGLE ∗ ) m a l l o c ( s i z e o f ( s t r u c t TRIANGLE) ) ;
// d e f i n e t r i a n g l e p0 , p1 , p2 a s c h i l d o f f i r s t t r e e n o d e
t r i a n g l e s _ t r e e −>c h i l d r e n = ( s t r u c t TRIANGLE ∗ ∗ ) m a l l o c ( s i z e o f ( s t r u c t TRIANGLE ∗ ) ) ;
t r i a n g l e s _ t r e e −>c h i l d r e n [ 0 ] = ( s t r u c t TRIANGLE ∗ ) m a l l o c ( s i z e o f ( s t r u c t TRIANGLE) ) ;
∗ ( t r i a n g l e s _ t r e e −>c h i l d r e n [ 0 ] ) = t ;
t r i a n g l e s _ t r e e −>n u m b e r _ o f _ c h i l d r e n = 1 ;
t r i a n g l e s _ t r e e −>p r o c e s s e d = f a l s e ;
t r i a n g l e s _ t r e e −>v i s i t e d = f a l s e ;

return ;
}

18
ANNEX D - DELAUNAY TRIANGULATION
// r e t u r n s f l a g i n d i c a t i n g i f t r i a n g l e h a s p0 , p1 o r p2 a s vertex
bool v a l i d _ d e l a u n a y _ t r i a n g l e ( s t r u c t TRIANGLE ∗ t )
{
i f ( t == NULL)
return ( f a l s e ) ;

i f ( ( p o i n t s _ a r e _ e q u a l ( t−>p_i , p_0 ) == true ) ||


( p o i n t s _ a r e _ e q u a l ( t−>p_i , p_1 ) == true ) ||
( p o i n t s _ a r e _ e q u a l ( t−>p_i , p_2 ) == true ) ||
( p o i n t s _ a r e _ e q u a l ( t−>p_j , p_0 ) == true ) ||
( p o i n t s _ a r e _ e q u a l ( t−>p_j , p_1 ) == true ) ||
( p o i n t s _ a r e _ e q u a l ( t−>p_j , p_2 ) == true ) ||
( p o i n t s _ a r e _ e q u a l ( t−>p_k , p_0 ) == true ) ||
( p o i n t s _ a r e _ e q u a l ( t−>p_k , p_1 ) == true ) ||
( p o i n t s _ a r e _ e q u a l ( t−>p_k , p_2 ) == true ) )
return ( f a l s e ) ;

return ( true ) ;
}

// p e r f o r m a d e p t h − f i r s t s e a r c h t o s e l e c t t h e D e l a u n a y t r i a n g l e s f r o m t h e l e a f n o d e s o f t h e
triangles tree
void d e f i n e _ d e l a u n a y _ t r i a n g l e s _ f r o m _ t r e e ( s t r u c t TRIANGLE ∗ t , v e c t o r <s t r u c t TRIANGLE ∗> &
triangles )
{
int i ;

// i f t r i a n g l e i s n o t v i s i t e d
i f ( t−>v i s i t e d == f a l s e )
{
// s e t s t r i a n g l e a s v i s i t e d
t−>v i s i t e d = true ;

// i f t r i a n g l e h a s c h i l d r e n i s n o t l e a f , s e a r c h c o n t i n u e s
i f ( t−>n u m b e r _ o f _ c h i l d r e n > 0 )
{
f o r ( i = 0 ; i < t−>n u m b e r _ o f _ c h i l d r e n ; i ++)
d e f i n e _ d e l a u n a y _ t r i a n g l e s _ f r o m _ t r e e ( t−>c h i l d r e n [ i ] , t r i a n g l e s ) ;
}
// i f t r i a n g l e h a s no c h i l d r e n , t h e n i t i s a D e l a u n a y t r i a n g l e
else
{
// v e r i f i e s i f t r i a n g l e d o e s n o t i n c l u d e p o i n t s p0 , p1 , p2 f r o m e n c l o s i n g triangle
i f ( v a l i d _ d e l a u n a y _ t r i a n g l e ( t ) == true )
{
// i n s e r t s t r i a n g l e i n t h e D e l a u n a y t r i a n g l e s v e c t o r
t r i a n g l e s . push_back ( t ) ;
}
}
}

return ;
}

// an e d g e p1 , p2 i s l e g a l i z e d b y c a l c u l a t i n g t h e c e n t e r and r a d i u s o f t h e c i r c u n f e r e n c e f r o m
p o i n t s p , p1 , p2 and b y v e r i f i n g i f t h e p o i n t o f t h e a d j a c e n t t r i a n g l e o p p o s i t e t o t h e e d g e i s
i n s i d e t h e c i r c u n f e r e n c e , s o t h e e d g e i s i l l e g a l and i t i s r o t a t e d c r e a t i n g 2 new t r i a n g l e s
void l e g a l i z e _ e d g e ( s t r u c t POINT p , s t r u c t POINT p1 , s t r u c t POINT p2 , s t r u c t TRIANGLE ∗t_o ,
s t r u c t TRIANGLE ∗t_p )
{
double xc , yc , r , d i s t ;
s t r u c t POINT o p p o s i t e _ p o i n t , c e n t e r , u s e l e s s _ p o i n t _ s e q [ 3 ] ;
int i ;

// c a s e s w h e r e some p o i n t s s h o u l d b e e x c l u d e d f r o m t h e s e t
//
// i f p o i n t p i s e q u a l t o e d g e p o i n t
i f ( p o i n t s _ a r e _ e q u a l ( p , p1 ) == true )
{
c o u t << " p o i n t ␣p␣ e q u a l s ␣ t o ␣ p1 " << e n d l ;
c o u t << " p . i n d e x ␣=␣ " << p . p o i n t _ i n d e x << e n d l ;
c o u t << " p1 . i n d e x ␣=␣ " << p1 . p o i n t _ i n d e x << e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p . x ␣=␣ " << p . x + BASE_X << " ␣ | ␣p . y ␣=␣ " << p . y + BASE_Y << "
␣ | ␣p . z ␣=␣ " << p . z << e n d l ;

19
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p1 . x ␣=␣ " << p1 . x + BASE_X << " ␣ | ␣ p1 . y ␣=␣ " << p1 . y + BASE_Y
<< " ␣ | ␣ p1 . z ␣=␣ " << p1 . z << e n d l ;
system ( " pause " ) ;
exit (0) ;
return ;
}
// i f p o i n t p i s e q u a l t o e d g e p o i n t
i f ( p o i n t s _ a r e _ e q u a l ( p , p2 ) == true )
{
c o u t << " p o i n t ␣p␣ e q u a l s ␣ t o ␣ p2 " << e n d l ;
c o u t << " p . i n d e x ␣=␣ " << p . p o i n t _ i n d e x << e n d l ;
c o u t << " p2 . i n d e x ␣=␣ " << p2 . p o i n t _ i n d e x << e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p . x ␣=␣ " << p . x + BASE_X << " ␣ | ␣p . y ␣=␣ " << p . y + BASE_Y << "
␣ | ␣p . z ␣=␣ " << p . z << e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p2 . x ␣=␣ " << p2 . x + BASE_X << " ␣ | ␣ p2 . y ␣=␣ " << p2 . y + BASE_Y
<< " ␣ | ␣ p2 . z ␣=␣ " << p2 . z << e n d l ;
system ( " pause " ) ;
exit (0) ;
return ;
}
// i f p o i n t s p1 and p2 a r e e q u a l
i f ( p o i n t s _ a r e _ e q u a l ( p1 , p2 ) == true )
{
c o u t << " p o i n t ␣ p1 ␣ e q u a l s ␣ t o ␣ p2 " << e n d l ;
c o u t << " p1 . i n d e x ␣=␣ " << p1 . p o i n t _ i n d e x << e n d l ;
c o u t << " p2 . i n d e x ␣=␣ " << p2 . p o i n t _ i n d e x << e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p1 . x ␣=␣ " << p1 . x + BASE_X << " ␣ | ␣ p1 . y ␣=␣ " << p1 . y + BASE_Y
<< " ␣ | ␣ p1 . z ␣=␣ " << p1 . z << e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p2 . x ␣=␣ " << p2 . x + BASE_X << " ␣ | ␣ p2 . y ␣=␣ " << p2 . y + BASE_Y
<< " ␣ | ␣ p2 . z ␣=␣ " << p2 . z << e n d l ;
system ( " pause " ) ;
exit (0) ;
return ;
}
// i f p , p1 , p2 a r e c o l i n e a r i n x t h e c i r c u n f e r e n c e d o e s n o t e x i s t
i f ( a b s ( p . x − p1 . x ) < e p s V e r t e x && a b s ( p1 . x − p2 . x ) < e p s V e r t e x )
{
c o u t << " 3 ␣ c o l i n e a r ␣ p o i n t s , ␣ v e r t i c a l ␣ l i n e " << e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p . x ␣=␣ ␣ " << p . p o i n t _ i n d e x << " ␣ " << p . x + BASE_X << " ␣ | ␣p .
y ␣=␣ " << p . y + BASE_Y << e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p1 . x ␣=␣ " << p1 . p o i n t _ i n d e x << " ␣ " << p1 . x + BASE_X << " ␣ | ␣
p1 . y ␣=␣ " << p1 . y + BASE_Y << e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p2 . x ␣=␣ " << p2 . p o i n t _ i n d e x << " ␣ " << p2 . x + BASE_X << " ␣ | ␣
p2 . y ␣=␣ " << p2 . y + BASE_Y << e n d l ;
system ( " pause " ) ;
exit (0) ;
}
// i f p , p1 , p2 a r e c o l i n e a r i n y t h e c i r c u n f e r e n c e d o e s n o t e x i s t
i f ( a b s ( p . y − p1 . y ) < e p s V e r t e x && a b s ( p1 . y − p2 . y ) < e p s V e r t e x )
{
c o u t << " 3 ␣ c o l i n e a r ␣ p o i n t s , ␣ h o r i z o n t a l ␣ l i n e " << e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p . x ␣=␣ ␣ " << p . p o i n t _ i n d e x << " ␣ " << p . x + BASE_X << " ␣ | ␣p .
y ␣=␣ " << p . y + BASE_Y << e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p1 . x ␣=␣ " << p1 . p o i n t _ i n d e x << " ␣ " << p1 . x + BASE_X << " ␣ | ␣
p1 . y ␣=␣ " << p1 . y + BASE_Y << e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p2 . x ␣=␣ " << p2 . p o i n t _ i n d e x << " ␣ " << p2 . x + BASE_X << " ␣ | ␣
p2 . y ␣=␣ " << p2 . y + BASE_Y << e n d l ;
system ( " pause " ) ;
exit (0) ;
}
// i f p , p1 , p2 a r e c o l i n e a r w i t h same s l o p e t h e c i r c u n f e r e n c e d o e s n o t e x i s t
i f ( s a m e _ s l o p e ( p , p1 , p2 ) == true )
{
c o u t << " 3 ␣ c o l i n e a r ␣ p o i n t s , ␣ same ␣ s l o p e " << e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p . x ␣=␣ ␣ " << p . x + BASE_X << " ␣ | ␣p . y ␣=␣ " << p . y + BASE_Y <<
endl ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p1 . x ␣=␣ " << p1 . x + BASE_X << " ␣ | ␣ p1 . y ␣=␣ " << p1 . y + BASE_Y
<< e n d l ;
c o u t << s e t p r e c i s i o n ( 1 5 ) << " p2 . x ␣=␣ " << p2 . x + BASE_X << " ␣ | ␣ p2 . y ␣=␣ " << p2 . y + BASE_Y
<< e n d l ;
system ( " pause " ) ;
exit (0) ;
}

// d e f i n e p o i n t o p p o s i t e t o t h e e d g e p1 , p2 f r o m a d j a c e n t triangle
o p p o s i t e _ p o i n t = o p p o s i t e _ p o i n t _ b y _ e d g e ( p1 , p2 , t_o ) ;
// i f p o i n t i s n o t d e f i n e d

20
i f ( p o i n t _ n o t _ u n d e f ( o p p o s i t e _ p o i n t ) == f a l s e )
return ;

// c a l c u l a t e s c e n t e r and r a d i u s o f c i r c u n f e r e n c e passing through p o i n t s p , p1 , p2


c i r c l e _ b y _ 3 _ p o i n t s ( p , p1 , p2 , &xc , &yc , &r ) ;

// v e r i f i e s i f p o i n t o p p o s i t e t o t h e e d g e p1 , p2 i s i n s i d e t h e c i r c u n f e r e n c e
//
// c a l c u l a t e s d i s t a n c e f r o m c i r c u n f e r e n c e c e n t e r t o t h e o p p o s i t e p o i n t
c e n t e r . x = xc ;
c e n t e r . y = yc ;
d i s t = distance_between ( center , opposite_point ) ;

// v e r i f i e s i f d i s t a n c e i s l e s s t h a n r a d i u s , s o t h e e d g e i s n o t v a l i d
if ( dist < r )
{
// d i v i d e c u r r e n t t r i a n g l e s a d d i n g new t r i a n g l e s p , p1 , o p p o s i t e and p , p2 , o p p o s i t e as
children
//
// t r i a n g l e w i t h p o i n t p
t_p−>c h i l d r e n = ( s t r u c t TRIANGLE ∗ ∗ ) m a l l o c ( 2 ∗ s i z e o f ( s t r u c t TRIANGLE ∗ ) ) ;
t_p−>n u m b e r _ o f _ c h i l d r e n = 2 ;
f o r ( i = 0 ; i < t_p−>n u m b e r _ o f _ c h i l d r e n ; i ++)
t_p−>c h i l d r e n [ i ] = ( s t r u c t TRIANGLE ∗ ) m a l l o c ( s i z e o f ( s t r u c t TRIANGLE) ) ;

// t r i a n g l e p , p1 , o p p o s i t e
t_p−>c h i l d r e n [0] − > p_i = p ;
t_p−>c h i l d r e n [0] − > p_j = p1 ;
t_p−>c h i l d r e n [0] − >p_k = o p p o s i t e _ p o i n t ;
t_p−>c h i l d r e n [0] − > c h i l d r e n = NULL ;
t_p−>c h i l d r e n [0] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t_p−>c h i l d r e n [0] − > p a r e n t s [ 0 ] = t_p ;
t_p−>c h i l d r e n [0] − > p a r e n t s [ 1 ] = t_o ;
t_p−>c h i l d r e n [0] − > number_of_parents = 2 ;
t_p−>c h i l d r e n [0] − > p r o c e s s e d = f a l s e ;
t_p−>c h i l d r e n [0] − > v i s i t e d = f a l s e ;
// t r i a n g l e p , p2 , o p p o s i t e
t_p−>c h i l d r e n [1] − > p_i = p ;
t_p−>c h i l d r e n [1] − > p_j = p2 ;
t_p−>c h i l d r e n [1] − >p_k = o p p o s i t e _ p o i n t ;
t_p−>c h i l d r e n [1] − > c h i l d r e n = NULL ;
t_p−>c h i l d r e n [1] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t_p−>c h i l d r e n [1] − > p a r e n t s [ 0 ] = t_p ;
t_p−>c h i l d r e n [1] − > p a r e n t s [ 1 ] = t_o ;
t_p−>c h i l d r e n [1] − > number_of_parents = 2 ;
t_p−>c h i l d r e n [1] − > p r o c e s s e d = f a l s e ;
t_p−>c h i l d r e n [1] − > v i s i t e d = f a l s e ;

// d e f i n e a d j a c e n c y b e t w e e n new t r i a n g l e s
//
// t r i a n g l e p , p1 , o p p o s i t e
// a d j a c e n t b y p a r e n t p1 , p2 , p
t_p−>c h i l d r e n [0] − > a d j a c e n t [ 0 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_p , t_p−>c h i l d r e n [ 0 ] ,
p1 , p , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t b y p a r e n t p1 , p2 , o p p o s i t e
t_p−>c h i l d r e n [0] − > a d j a c e n t [ 1 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_o , t_p−>c h i l d r e n [ 0 ] ,
p1 , o p p o s i t e _ p o i n t , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t p , p2 , o p p o s i t e
t_p−>c h i l d r e n [0] − > a d j a c e n t [ 2 ] = t_p−>c h i l d r e n [ 1 ] ;
//
// t r i a n g l e p , p2 , o p p o s i t e
// a d j a c e n t e p e l o t r i â n g u l o p a i p1 , p2 , p
t_p−>c h i l d r e n [1] − > a d j a c e n t [ 0 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_p , t_p−>c h i l d r e n [ 1 ] ,
p2 , p , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t b y p a r e n t p1 , p2 , o p p o s i t e
t_p−>c h i l d r e n [1] − > a d j a c e n t [ 1 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_o , t_p−>c h i l d r e n [ 1 ] ,
p2 , o p p o s i t e _ p o i n t , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t p , p1 , o p p o s i t e
t_p−>c h i l d r e n [1] − > a d j a c e n t [ 2 ] = t_p−>c h i l d r e n [ 0 ] ;

// t r i a n g l e w i t h o p p o s i t e p o i n t , c h i l d r e n a r e t h e same o f t r i a n g l e w i t h p o i n t p
t_o−>c h i l d r e n = ( s t r u c t TRIANGLE ∗ ∗ ) m a l l o c ( 2 ∗ s i z e o f ( s t r u c t TRIANGLE ∗ ) ) ;
t_o−>n u m b e r _ o f _ c h i l d r e n = 2 ;

// t r i a n g l e p , p1 , o p p o s i t e
t_o−>c h i l d r e n [ 0 ] = t_p−>c h i l d r e n [ 0 ] ;
// t r i a n g l e p , p2 , o p p o s i t e

21
t_o−>c h i l d r e n [ 1 ] = t_p−>c h i l d r e n [ 1 ] ;

// r e c u r s i v e l y l e g a l i z e e d g e s p1 , o p p o s i t e e o p p o s i t e , p2
//
// a d j a c e n t t r i a n g l e s o f new t r i a n g l e s
// a d j a c e n t b y e d g e p1 , o p p o s i t e
l e g a l i z e _ e d g e ( p , p1 , o p p o s i t e _ p o i n t , t_o−>c h i l d r e n [0] − > a d j a c e n t [ 1 ] , t_o−>c h i l d r e n
[0]) ;
// a d j a c e n t b y e d g e p2 , o p p o s i t e
l e g a l i z e _ e d g e ( p , o p p o s i t e _ p o i n t , p2 , t_o−>c h i l d r e n [1] − > a d j a c e n t [ 1 ] , t_o−>c h i l d r e n
[1]) ;
}

return ;
}

// c a l c u l a t e s t h e D e l a u n a y t r i a n g u l a t i o n f r o m a s e t o f p o i n t s w i t h t h e i n c r e m e n t a l algorithm
//
// t h e p o i n t s a r e i n s e r t e d one a t a t i m e and t h e t r i a n g u l a t i o n i s l o c a l l y m o d i f i e d with the
i n s e r t i o n of each p o i n t
v e c t o r <s t r u c t TRIANGLE ∗> d e l a u n a y _ t r i a n g u l a t i o n ( v e c t o r <s t r u c t POINT> &p )
{
v e c t o r <s t r u c t TRIANGLE ∗> t r i a n g l e s ;
queue <s t r u c t TRIANGLE ∗> t q ;
s t r u c t TRIANGLE ∗ t_node , ∗ t _ a d j a c e n t ;
s t r u c t POINT p o i n t _ s e q [ 3 ] , u s e l e s s _ p o i n t _ s e q [ 3 ] ;
i n t p o i n t _ i n _ t r i a n g l e _ r e s u l t , p_index , t _ i n d e x ;
int i ;

// i n s e r t s a p o i n t and v e r i f i e s t h e t r i a n g l e t h a t c o n t a i n s t h e p o i n t
f o r ( p_index = 0 ; p_index < p . s i z e ( ) ; p_index++)
{
// s e a r c h t h e t r i a n g l e t h a t c o n t a i n s t h e p o i n t t r a v e r s i n g t h e t r e e
//
// s e t s t h e e n c l o s i n g t r i a n g l e a s n o t p r o c e s s e d and i n s e r t s i t i n t o the queue
t r i a n g l e s _ t r e e −>c h i l d r e n [0] − > p r o c e s s e d = f a l s e ;
t q . push ( t r i a n g l e s _ t r e e −>c h i l d r e n [ 0 ] ) ;

// w h i l e t h e q u e u e i s n o t empty , t r i a n g l e s are still verified


while ( t q . empty ( ) == f a l s e )
{
// r e m o v e t r i a n g l e f r o m q u e u e
t_node = t q . f r o n t ( ) ;
t q . pop ( ) ;

// v e r i f i e s i f triangle is already processed , w h i c h can o c c u r when t h e point is


l o c a t e d e x a c t l y on an e d g e
//
// i f t r i a n g l e i s a l r e a d y p r o c e s s e d , continue , otherwise sets it as processed
i f ( t_node−>p r o c e s s e d == true )
continue ;
else
t_node−>p r o c e s s e d = true ;

// g e t l o c a t i o n o f p o i n t i n t h e t r i a n g l e
p o i n t _ i n _ t r i a n g l e _ r e s u l t = p o i n t _ i n _ t r i a n g l e ( p [ p_index ] , ∗ t_node ) ;

// if t h e t r i a n g l e h a s c h i l d r e n , add t h e c h i l d r e n i n t o t h e q u e u e i f t h e p o i n t is on
the t r i a n g l e
i f ( t_node−>n u m b e r _ o f _ c h i l d r e n > 0 )
{
// i f p o i n t i s i n s i d e o r on an e d g e o f t h e t r i a n g l e
i f ( point_in_triangle_result > 0)
{
// no n e e d t o v e r i f y o t h e r t r i a n g l e s i n t h e q u e u e , empty t h e q u e u e
t q = queue<s t r u c t TRIANGLE ∗ >() ;

// add c h i l d r e n i n t h e q u e u e
f o r ( t _ i n d e x = 0 ; t _ i n d e x < t_node−>n u m b e r _ o f _ c h i l d r e n ; t _ i n d e x++)
{
// s e t s t r i a n g l e a s n o t p r o c e s s e d
t_node−>c h i l d r e n [ t _ i n d e x]−> p r o c e s s e d = f a l s e ;
t q . push ( t_node−>c h i l d r e n [ t _ i n d e x ] ) ;
}
}
}
// if triangle is leaf node , divide triangle according to location of point in

22
triangle
else
{
// i f p o i n t i s i n s i d e t r i a n g l e
i f ( p o i n t _ i n _ t r i a n g l e _ r e s u l t == 2 )
{
// add e d g e s f r o m t h e p o i n t t o t h e v e r t i c e s o f t h e t r i a n g l e d i v i d i n g i t i n t o
3 new t r i a n g l e s
t_node−>c h i l d r e n = ( s t r u c t TRIANGLE ∗ ∗ ) m a l l o c ( 3 ∗ s i z e o f ( s t r u c t TRIANGLE ∗ ) ) ;
t_node−>n u m b e r _ o f _ c h i l d r e n = 3 ;
f o r ( i = 0 ; i < t_node−>n u m b e r _ o f _ c h i l d r e n ; i ++)
t_node−>c h i l d r e n [ i ] = ( s t r u c t TRIANGLE ∗ ) m a l l o c ( s i z e o f ( s t r u c t TRIANGLE)
);

// t r i a n g l e i , j , p
t_node−>c h i l d r e n [0] − > p_i = t_node−>p_i ;
t_node−>c h i l d r e n [0] − > p_j = t_node−>p_j ;
t_node−>c h i l d r e n [0] − >p_k = p [ p_index ] ;
t_node−>c h i l d r e n [0] − > c h i l d r e n = NULL ;
t_node−>c h i l d r e n [0] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t_node−>c h i l d r e n [0] − > p a r e n t s [ 0 ] = t_node ;
t_node−>c h i l d r e n [0] − > number_of_parents = 1 ;
t_node−>c h i l d r e n [0] − > p r o c e s s e d = f a l s e ;
t_node−>c h i l d r e n [0] − > v i s i t e d = f a l s e ;
// t r i a n g l e j , k , p
t_node−>c h i l d r e n [1] − > p_i = t_node−>p_j ;
t_node−>c h i l d r e n [1] − > p_j = t_node−>p_k ;
t_node−>c h i l d r e n [1] − >p_k = p [ p_index ] ;
t_node−>c h i l d r e n [1] − > c h i l d r e n = NULL ;
t_node−>c h i l d r e n [1] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t_node−>c h i l d r e n [1] − > p a r e n t s [ 0 ] = t_node ;
t_node−>c h i l d r e n [1] − > number_of_parents = 1 ;
t_node−>c h i l d r e n [1] − > p r o c e s s e d = f a l s e ;
t_node−>c h i l d r e n [1] − > v i s i t e d = f a l s e ;
// t r i a n g l e i , k , p
t_node−>c h i l d r e n [2] − > p_i = t_node−>p_i ;
t_node−>c h i l d r e n [2] − > p_j = t_node−>p_k ;
t_node−>c h i l d r e n [2] − >p_k = p [ p_index ] ;
t_node−>c h i l d r e n [2] − > c h i l d r e n = NULL ;
t_node−>c h i l d r e n [2] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t_node−>c h i l d r e n [2] − > p a r e n t s [ 0 ] = t_node ;
t_node−>c h i l d r e n [2] − > number_of_parents = 1 ;
t_node−>c h i l d r e n [2] − > p r o c e s s e d = f a l s e ;
t_node−>c h i l d r e n [2] − > v i s i t e d = f a l s e ;

// d e f i n e a d j a c e n c y b e t w e e n new t r i a n g l e s
//
// t r i a n g l e i , j , p :
// a d j a c e n t b y p a r e n t
t_node−>c h i l d r e n [0] − > a d j a c e n t [ 0 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_node ,
t_node−>c h i l d r e n [ 0 ] , t_node−>p_i , t_node−>p_j , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t j , k , p
t_node−>c h i l d r e n [0] − > a d j a c e n t [ 1 ] = t_node−>c h i l d r e n [ 1 ] ;
// a d j a c e n t i , k , p
t_node−>c h i l d r e n [0] − > a d j a c e n t [ 2 ] = t_node−>c h i l d r e n [ 2 ] ;
//
// t r i a n g l e j , k , p :
// a d j a c e n t b y p a r e n t
t_node−>c h i l d r e n [1] − > a d j a c e n t [ 0 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_node ,
t_node−>c h i l d r e n [ 1 ] , t_node−>p_j , t_node−>p_k , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t i , k , p
t_node−>c h i l d r e n [1] − > a d j a c e n t [ 1 ] = t_node−>c h i l d r e n [ 2 ] ;
// a d j a c e n t i , j , p
t_node−>c h i l d r e n [1] − > a d j a c e n t [ 2 ] = t_node−>c h i l d r e n [ 0 ] ;
//
// t r i a n g l e i , k , p :
// a d j a c e n t b y p a r e n t
t_node−>c h i l d r e n [2] − > a d j a c e n t [ 0 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_node ,
t_node−>c h i l d r e n [ 2 ] , t_node−>p_i , t_node−>p_k , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t j , k , p
t_node−>c h i l d r e n [2] − > a d j a c e n t [ 1 ] = t_node−>c h i l d r e n [ 1 ] ;
// a d j a c e n t i , j , p
t_node−>c h i l d r e n [2] − > a d j a c e n t [ 2 ] = t_node−>c h i l d r e n [ 0 ] ;

// l e g a l i z e t h e e d g e s o f t h e d i v i d e d t r i a n g l e
l e g a l i z e _ e d g e ( p [ p_index ] , t_node−>p_i , t_node−>p_j , t_node−>c h i l d r e n [0] − >
a d j a c e n t [ 0 ] , t_node−>c h i l d r e n [ 0 ] ) ;

23
l e g a l i z e _ e d g e ( p [ p_index ] , t_node−>p_j , t_node−>p_k , t_node−>c h i l d r e n [1] − >
a d j a c e n t [ 0 ] , t_node−>c h i l d r e n [ 1 ] ) ;
l e g a l i z e _ e d g e ( p [ p_index ] , t_node−>p_k , t_node−>p_i , t_node−>c h i l d r e n [2] − >
a d j a c e n t [ 0 ] , t_node−>c h i l d r e n [ 2 ] ) ;

// no n e e d t o v e r i f y o t h e r t r i a n g l e s in the queue , empty t h e queue


t q = queue<s t r u c t TRIANGLE ∗ >() ;
}
// i f t h e p o i n t i s on an e d g e
else
i f ( p o i n t _ i n _ t r i a n g l e _ r e s u l t == 1 )
{
// add an e d g e f r o m t h e p o i n t t o t h e p o i n t o f t h e t r i a n g l e o p p o s i t e t o t h e
e d g e d i v i d i n g i t i n t o 2 new t r i a n g l e s
t_node−>c h i l d r e n = ( s t r u c t TRIANGLE ∗ ∗ ) m a l l o c ( 2 ∗ s i z e o f ( s t r u c t TRIANGLE ∗ ) ) ;
t_node−>n u m b e r _ o f _ c h i l d r e n = 2 ;
f o r ( i = 0 ; i < t_node−>n u m b e r _ o f _ c h i l d r e n ; i ++)
t_node−>c h i l d r e n [ i ] = ( s t r u c t TRIANGLE ∗ ) m a l l o c ( s i z e o f ( s t r u c t TRIANGLE)
);

// v e r i f i e s on w h a t e d g e t h e point is located and defines t h e new triangles


with the opposite point
//
// e d g e i , j
// a d j a c e n t t r i a n g l e : p o i n t l <−> p o i n t k
i f ( s a m e _ s l o p e _ i j == true )
{
// t r i a n g l e i , k , p
t_node−>c h i l d r e n [0] − > p_i = t_node−>p_i ;
t_node−>c h i l d r e n [0] − > p_j = t_node−>p_k ;
t_node−>c h i l d r e n [0] − >p_k = p [ p_index ] ;
t_node−>c h i l d r e n [0] − > c h i l d r e n = NULL ;
t_node−>c h i l d r e n [0] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t_node−>c h i l d r e n [0] − > p a r e n t s [ 0 ] = t_node ;
t_node−>c h i l d r e n [0] − > number_of_parents = 1 ;
t_node−>c h i l d r e n [0] − > p r o c e s s e d = f a l s e ;
t_node−>c h i l d r e n [0] − > v i s i t e d = f a l s e ;
// t r i a n g l e j , k , p
t_node−>c h i l d r e n [1] − > p_i = t_node−>p_j ;
t_node−>c h i l d r e n [1] − > p_j = t_node−>p_k ;
t_node−>c h i l d r e n [1] − >p_k = p [ p_index ] ;
t_node−>c h i l d r e n [1] − > c h i l d r e n = NULL ;
t_node−>c h i l d r e n [1] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t_node−>c h i l d r e n [1] − > p a r e n t s [ 0 ] = t_node ;
t_node−>c h i l d r e n [1] − > number_of_parents = 1 ;
t_node−>c h i l d r e n [1] − > p r o c e s s e d = f a l s e ;
t_node−>c h i l d r e n [1] − > v i s i t e d = f a l s e ;

// d e f i n e 2 new t r i a n g l e s f r o m t h e a d j a c e n t t r i a n g l e b y t h e e d g e
t _ a d j a c e n t = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_node , t_node , t_node−>p_i ,
t_node−>p_j , p o i n t _ s e q ) ;

i f ( t _ a d j a c e n t != NULL)
{
t _ a d j a c e n t −>c h i l d r e n = ( s t r u c t TRIANGLE ∗ ∗ ) m a l l o c ( 2 ∗ s i z e o f ( s t r u c t
TRIANGLE ∗ ) ) ;
t _ a d j a c e n t −>n u m b e r _ o f _ c h i l d r e n = 2 ;
f o r ( i = 0 ; i < t _ a d j a c e n t −>n u m b e r _ o f _ c h i l d r e n ; i ++)
t _ a d j a c e n t −>c h i l d r e n [ i ] = ( s t r u c t TRIANGLE ∗ ) m a l l o c ( s i z e o f (
s t r u c t TRIANGLE) ) ;

// s e t s a d j a c e n t t r i a n g l e a s p r o c e s s e d
t _ a d j a c e n t −>p r o c e s s e d = true ;

// t r i a n g l e i , l , p
t _ a d j a c e n t −>c h i l d r e n [0] − > p_i = p o i n t _ s e q [ 1 ] ;
t _ a d j a c e n t −>c h i l d r e n [0] − > p_j = p o i n t _ s e q [ 0 ] ;
t _ a d j a c e n t −>c h i l d r e n [0] − >p_k = p [ p_index ] ;
t _ a d j a c e n t −>c h i l d r e n [0] − > c h i l d r e n = NULL ;
t _ a d j a c e n t −>c h i l d r e n [0] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t _ a d j a c e n t −>c h i l d r e n [0] − > p a r e n t s [ 0 ] = t _ a d j a c e n t ;
t _ a d j a c e n t −>c h i l d r e n [0] − > number_of_parents = 1 ;
t _ a d j a c e n t −>c h i l d r e n [0] − > p r o c e s s e d = f a l s e ;
t _ a d j a c e n t −>c h i l d r e n [0] − > v i s i t e d = f a l s e ;
// t r i a n g l e j , l , p
t _ a d j a c e n t −>c h i l d r e n [1] − > p_i = p o i n t _ s e q [ 2 ] ;
t _ a d j a c e n t −>c h i l d r e n [1] − > p_j = p o i n t _ s e q [ 0 ] ;

24
t _ a d j a c e n t −>c h i l d r e n [1] − >p_k = p [ p_index ] ;
t _ a d j a c e n t −>c h i l d r e n [1] − > c h i l d r e n = NULL ;
t _ a d j a c e n t −>c h i l d r e n [1] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t _ a d j a c e n t −>c h i l d r e n [1] − > p a r e n t s [ 0 ] = t _ a d j a c e n t ;
t _ a d j a c e n t −>c h i l d r e n [1] − > number_of_parents = 1 ;
t _ a d j a c e n t −>c h i l d r e n [1] − > p r o c e s s e d = f a l s e ;
t _ a d j a c e n t −>c h i l d r e n [1] − > v i s i t e d = f a l s e ;
}

// d e f i n e a d j a c e n c y b e t w e e n new t r i a n g l e s
//
// t r i a n g l e i , k , p :
// a d j a c e n t b y p a r e n t
t_node−>c h i l d r e n [0] − > a d j a c e n t [ 0 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_node ,
t_node−>c h i l d r e n [ 0 ] , t_node−>p_i , t_node−>p_k , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t j , k , p
t_node−>c h i l d r e n [0] − > a d j a c e n t [ 1 ] = t_node−>c h i l d r e n [ 1 ] ;
// a d j a c e n t i , l , p
i f ( t _ a d j a c e n t != NULL)
t_node−>c h i l d r e n [0] − > a d j a c e n t [ 2 ] = t _ a d j a c e n t −>c h i l d r e n [ 0 ] ;

// t r i a n g l e j , k , p :
// a d j a c e n t b y p a r e n t
t_node−>c h i l d r e n [1] − > a d j a c e n t [ 0 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_node ,
t_node−>c h i l d r e n [ 1 ] , t_node−>p_j , t_node−>p_k , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t i , k , p
t_node−>c h i l d r e n [1] − > a d j a c e n t [ 1 ] = t_node−>c h i l d r e n [ 0 ] ;
// a d j a c e n t j , l , p
i f ( t _ a d j a c e n t != NULL)
t_node−>c h i l d r e n [1] − > a d j a c e n t [ 2 ] = t _ a d j a c e n t −>c h i l d r e n [ 1 ] ;

i f ( t _ a d j a c e n t != NULL)
{
// t r i a n g l e i , l , p :
// a d j a c e n t e p e l o t r i â n g u l o p a i
t _ a d j a c e n t −>c h i l d r e n [0] − > a d j a c e n t [ 0 ] = adjacent_triangle_by_parent (
t _ a d j a c e n t , t _ a d j a c e n t −>c h i l d r e n [ 0 ] , point_seq [ 1 ] , point_seq [ 0 ] ,
useless_point_seq ) ;
// a d j a c e n t j , l , p
t _ a d j a c e n t −>c h i l d r e n [0] − > a d j a c e n t [ 1 ] = t _ a d j a c e n t −>c h i l d r e n [ 1 ] ;
// a d j a c e n t i , k , p
t _ a d j a c e n t −>c h i l d r e n [0] − > a d j a c e n t [ 2 ] = t_node−>c h i l d r e n [ 0 ] ;
//
// t r i a n g l e j , l , p :
// a d j a c e n t e p e l o t r i â n g u l o p a i
t _ a d j a c e n t −>c h i l d r e n [1] − > a d j a c e n t [ 0 ] = adjacent_triangle_by_parent (
t _ a d j a c e n t , t _ a d j a c e n t −>c h i l d r e n [ 1 ] , point_seq [ 2 ] , point_seq [ 0 ] ,
useless_point_seq ) ;
// a d j a c e n t i , l , p
t _ a d j a c e n t −>c h i l d r e n [1] − > a d j a c e n t [ 1 ] = t _ a d j a c e n t −>c h i l d r e n [ 0 ] ;
// a d j a c e n t j , k , p
t _ a d j a c e n t −>c h i l d r e n [1] − > a d j a c e n t [ 2 ] = t_node−>c h i l d r e n [ 1 ] ;
}

// l e g a l i z e t h e e d g e s o f t h e d i v i d e d t r i a n g l e
l e g a l i z e _ e d g e ( p [ p_index ] , t_node−>p_i , p o i n t _ s e q [ 0 ] , t _ a d j a c e n t −>
c h i l d r e n [0] − > a d j a c e n t [ 0 ] , t _ a d j a c e n t −>c h i l d r e n [ 0 ] ) ;
l e g a l i z e _ e d g e ( p [ p_index ] , p o i n t _ s e q [ 0 ] , t_node−>p_j , t _ a d j a c e n t −>
c h i l d r e n [1] − > a d j a c e n t [ 0 ] , t _ a d j a c e n t −>c h i l d r e n [ 1 ] ) ;
l e g a l i z e _ e d g e ( p [ p_index ] , t_node−>p_j , t_node−>p_k , t_node−>c h i l d r e n
[1] − > a d j a c e n t [ 0 ] , t_node−>c h i l d r e n [ 1 ] ) ;
l e g a l i z e _ e d g e ( p [ p_index ] , t_node−>p_k , t_node−>p_i , t_node−>c h i l d r e n
[0] − > a d j a c e n t [ 0 ] , t_node−>c h i l d r e n [ 0 ] ) ;
}
else
// e d g e j , k
// a d j a c e n t t r i a n g l e : p o i n t l <−> p o i n t i
i f ( same_slope_jk == true )
{
// t r i a n g l e j , i , p
t_node−>c h i l d r e n [0] − > p_i = t_node−>p_j ;
t_node−>c h i l d r e n [0] − > p_j = t_node−>p_i ;
t_node−>c h i l d r e n [0] − >p_k = p [ p_index ] ;
t_node−>c h i l d r e n [0] − > c h i l d r e n = NULL ;
t_node−>c h i l d r e n [0] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t_node−>c h i l d r e n [0] − > p a r e n t s [ 0 ] = t_node ;
t_node−>c h i l d r e n [0] − > number_of_parents = 1 ;

25
t_node−>c h i l d r e n [0] − > p r o c e s s e d = f a l s e ;
t_node−>c h i l d r e n [0] − > v i s i t e d = f a l s e ;
// t r i a n g l e k , i , p
t_node−>c h i l d r e n [1] − > p_i = t_node−>p_k ;
t_node−>c h i l d r e n [1] − > p_j = t_node−>p_i ;
t_node−>c h i l d r e n [1] − >p_k = p [ p_index ] ;
t_node−>c h i l d r e n [1] − > c h i l d r e n = NULL ;
t_node−>c h i l d r e n [1] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t_node−>c h i l d r e n [1] − > p a r e n t s [ 0 ] = t_node ;
t_node−>c h i l d r e n [1] − > number_of_parents = 1 ;
t_node−>c h i l d r e n [1] − > p r o c e s s e d = f a l s e ;
t_node−>c h i l d r e n [1] − > v i s i t e d = f a l s e ;

// d e f i n e 2 new t r i a n g l e s f r o m t h e a d j a c e n t t r i a n g l e b y t h e e d g e
t _ a d j a c e n t = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_node , t_node , t_node−>p_j ,
t_node−>p_k , p o i n t _ s e q ) ;

i f ( t _ a d j a c e n t != NULL)
{
t _ a d j a c e n t −>c h i l d r e n = ( s t r u c t TRIANGLE ∗ ∗ ) m a l l o c ( 2 ∗ s i z e o f ( s t r u c t
TRIANGLE ∗ ) ) ;
t _ a d j a c e n t −>n u m b e r _ o f _ c h i l d r e n = 2 ;
f o r ( i = 0 ; i < t _ a d j a c e n t −>n u m b e r _ o f _ c h i l d r e n ; i ++)
t _ a d j a c e n t −>c h i l d r e n [ i ] = ( s t r u c t TRIANGLE ∗ ) m a l l o c ( s i z e o f (
s t r u c t TRIANGLE) ) ;

// s e t s a d j a c e n t t r i a n g l e a s p r o c e s s e d
t _ a d j a c e n t −>p r o c e s s e d = true ;

// t r i a n g l e j , l , p
t _ a d j a c e n t −>c h i l d r e n [0] − > p_i = p o i n t _ s e q [ 1 ] ;
t _ a d j a c e n t −>c h i l d r e n [0] − > p_j = p o i n t _ s e q [ 0 ] ;
t _ a d j a c e n t −>c h i l d r e n [0] − >p_k = p [ p_index ] ;
t _ a d j a c e n t −>c h i l d r e n [0] − > c h i l d r e n = NULL ;
t _ a d j a c e n t −>c h i l d r e n [0] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t _ a d j a c e n t −>c h i l d r e n [0] − > p a r e n t s [ 0 ] = t _ a d j a c e n t ;
t _ a d j a c e n t −>c h i l d r e n [0] − > number_of_parents = 1 ;
t _ a d j a c e n t −>c h i l d r e n [0] − > p r o c e s s e d = f a l s e ;
t _ a d j a c e n t −>c h i l d r e n [0] − > v i s i t e d = f a l s e ;
// t r i a n g l e k , l , p
t _ a d j a c e n t −>c h i l d r e n [1] − > p_i = p o i n t _ s e q [ 2 ] ;
t _ a d j a c e n t −>c h i l d r e n [1] − > p_j = p o i n t _ s e q [ 0 ] ;
t _ a d j a c e n t −>c h i l d r e n [1] − >p_k = p [ p_index ] ;
t _ a d j a c e n t −>c h i l d r e n [1] − > c h i l d r e n = NULL ;
t _ a d j a c e n t −>c h i l d r e n [1] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t _ a d j a c e n t −>c h i l d r e n [1] − > p a r e n t s [ 0 ] = t _ a d j a c e n t ;
t _ a d j a c e n t −>c h i l d r e n [1] − > number_of_parents = 1 ;
t _ a d j a c e n t −>c h i l d r e n [1] − > p r o c e s s e d = f a l s e ;
t _ a d j a c e n t −>c h i l d r e n [1] − > v i s i t e d = f a l s e ;
}

// d e f i n e a d j a c e n c y b e t w e e n new t r i a n g l e s
//
// t r i a n g l e j , i , p :
// a d j a c e n t b y p a r e n t
t_node−>c h i l d r e n [0] − > a d j a c e n t [ 0 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_node ,
t_node−>c h i l d r e n [ 0 ] , t_node−>p_j , t_node−>p_i , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t k , i , p
t_node−>c h i l d r e n [0] − > a d j a c e n t [ 1 ] = t_node−>c h i l d r e n [ 1 ] ;
// a d j a c e n t j , l , p
i f ( t _ a d j a c e n t != NULL)
t_node−>c h i l d r e n [0] − > a d j a c e n t [ 2 ] = t _ a d j a c e n t −>c h i l d r e n [ 0 ] ;

// t r i â n g u l o k , i , p :
// a d j a c e n t b y p a r e n t
t_node−>c h i l d r e n [1] − > a d j a c e n t [ 0 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_node ,
t_node−>c h i l d r e n [ 1 ] , t_node−>p_k , t_node−>p_i , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t j , i , p
t_node−>c h i l d r e n [1] − > a d j a c e n t [ 1 ] = t_node−>c h i l d r e n [ 0 ] ;
// a d j a c e n t k , l , p
i f ( t _ a d j a c e n t != NULL)
t_node−>c h i l d r e n [1] − > a d j a c e n t [ 2 ] = t _ a d j a c e n t −>c h i l d r e n [ 1 ] ;

i f ( t _ a d j a c e n t != NULL)
{
// t r i a n g l e j , l , p :
// a d j a c e n t b y p a r e n t

26
t _ a d j a c e n t −>c h i l d r e n [0] − > a d j a c e n t [ 0 ] = adjacent_triangle_by_parent (
t _ a d j a c e n t , t _ a d j a c e n t −>c h i l d r e n [ 0 ] , point_seq [ 1 ] , point_seq [ 0 ] ,
useless_point_seq ) ;
// a d j a c e n t k , l , p
t _ a d j a c e n t −>c h i l d r e n [0] − > a d j a c e n t [ 1 ] = t _ a d j a c e n t −>c h i l d r e n [ 1 ] ;
// a d j a c e n t j , i , p
t _ a d j a c e n t −>c h i l d r e n [0] − > a d j a c e n t [ 2 ] = t_node−>c h i l d r e n [ 0 ] ;
//
// t r i a n g l e k , l , p :
// a d j a c e n t e p e l o t r i â n g u l o p a i
t _ a d j a c e n t −>c h i l d r e n [1] − > a d j a c e n t [ 0 ] = adjacent_triangle_by_parent (
t _ a d j a c e n t , t _ a d j a c e n t −>c h i l d r e n [ 1 ] , point_seq [ 2 ] , point_seq [ 0 ] ,
useless_point_seq ) ;
// a d j a c e n t j , l , p
t _ a d j a c e n t −>c h i l d r e n [1] − > a d j a c e n t [ 1 ] = t _ a d j a c e n t −>c h i l d r e n [ 0 ] ;
// a d j a c e n t k , i , p
t _ a d j a c e n t −>c h i l d r e n [1] − > a d j a c e n t [ 2 ] = t_node−>c h i l d r e n [ 1 ] ;
}

// l e g a l i z e t h e e d g e s o f t h e d i v i d e d t r i a n g l e
l e g a l i z e _ e d g e ( p [ p_index ] , t_node−>p_j , p o i n t _ s e q [ 0 ] , t _ a d j a c e n t −>
c h i l d r e n [0] − > a d j a c e n t [ 0 ] , t _ a d j a c e n t −>c h i l d r e n [ 0 ] ) ;
l e g a l i z e _ e d g e ( p [ p_index ] , p o i n t _ s e q [ 0 ] , t_node−>p_k , t _ a d j a c e n t −>
c h i l d r e n [1] − > a d j a c e n t [ 0 ] , t _ a d j a c e n t −>c h i l d r e n [ 1 ] ) ;
l e g a l i z e _ e d g e ( p [ p_index ] , t_node−>p_k , t_node−>p_i , t_node−>c h i l d r e n
[1] − > a d j a c e n t [ 0 ] , t_node−>c h i l d r e n [ 1 ] ) ;
l e g a l i z e _ e d g e ( p [ p_index ] , t_node−>p_i , t_node−>p_j , t_node−>c h i l d r e n
[0] − > a d j a c e n t [ 0 ] , t_node−>c h i l d r e n [ 0 ] ) ;
}
else
// e d g e k , i
// a d j a c e n t t r i a n g l e : p o i n t l <−> p o i n t j
i f ( s a m e _ s l o p e _ k i == true )
{
// t r i a n g l e k , j , p
t_node−>c h i l d r e n [0] − > p_i = t_node−>p_k ;
t_node−>c h i l d r e n [0] − > p_j = t_node−>p_j ;
t_node−>c h i l d r e n [0] − >p_k = p [ p_index ] ;
t_node−>c h i l d r e n [0] − > c h i l d r e n = NULL ;
t_node−>c h i l d r e n [0] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t_node−>c h i l d r e n [0] − > p a r e n t s [ 0 ] = t_node ;
t_node−>c h i l d r e n [0] − > number_of_parents = 1 ;
t_node−>c h i l d r e n [0] − > p r o c e s s e d = f a l s e ;
t_node−>c h i l d r e n [0] − > v i s i t e d = f a l s e ;
// t r i a n g l e i , j , p
t_node−>c h i l d r e n [1] − > p_i = t_node−>p_i ;
t_node−>c h i l d r e n [1] − > p_j = t_node−>p_j ;
t_node−>c h i l d r e n [1] − >p_k = p [ p_index ] ;
t_node−>c h i l d r e n [1] − > c h i l d r e n = NULL ;
t_node−>c h i l d r e n [1] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t_node−>c h i l d r e n [1] − > p a r e n t s [ 0 ] = t_node ;
t_node−>c h i l d r e n [1] − > number_of_parents = 1 ;
t_node−>c h i l d r e n [1] − > p r o c e s s e d = f a l s e ;
t_node−>c h i l d r e n [1] − > v i s i t e d = f a l s e ;

// d e f i n e 2 new t r i a n g l e s f r o m t h e a d j a c e n t t r i a n g l e b y t h e e d g e
t _ a d j a c e n t = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_node , t_node , t_node−>p_k ,
t_node−>p_i , p o i n t _ s e q ) ;

i f ( t _ a d j a c e n t != NULL)
{
t _ a d j a c e n t −>c h i l d r e n = ( s t r u c t TRIANGLE ∗ ∗ ) m a l l o c ( 2 ∗ s i z e o f ( s t r u c t
TRIANGLE ∗ ) ) ;
t _ a d j a c e n t −>n u m b e r _ o f _ c h i l d r e n = 2 ;
f o r ( i = 0 ; i < t _ a d j a c e n t −>n u m b e r _ o f _ c h i l d r e n ; i ++)
t _ a d j a c e n t −>c h i l d r e n [ i ] = ( s t r u c t TRIANGLE ∗ ) m a l l o c ( s i z e o f (
s t r u c t TRIANGLE) ) ;

// s e t s a d j a c e n t t r i a n g l e a s p r o c e s s e d
t _ a d j a c e n t −>p r o c e s s e d = true ;

// t r i a n g l e k , l , p
t _ a d j a c e n t −>c h i l d r e n [0] − > p_i = p o i n t _ s e q [ 1 ] ;
t _ a d j a c e n t −>c h i l d r e n [0] − > p_j = p o i n t _ s e q [ 0 ] ;
t _ a d j a c e n t −>c h i l d r e n [0] − >p_k = p [ p_index ] ;
t _ a d j a c e n t −>c h i l d r e n [0] − > c h i l d r e n = NULL ;
t _ a d j a c e n t −>c h i l d r e n [0] − > n u m b e r _ o f _ c h i l d r e n = 0 ;

27
t _ a d j a c e n t −>c h i l d r e n [0] − > p a r e n t s [ 0 ] = t _ a d j a c e n t ;
t _ a d j a c e n t −>c h i l d r e n [0] − > number_of_parents = 1 ;
t _ a d j a c e n t −>c h i l d r e n [0] − > p r o c e s s e d = f a l s e ;
t _ a d j a c e n t −>c h i l d r e n [0] − > v i s i t e d = f a l s e ;
// t r i a n g l e i , l , p
t _ a d j a c e n t −>c h i l d r e n [1] − > p_i = p o i n t _ s e q [ 2 ] ;
t _ a d j a c e n t −>c h i l d r e n [1] − > p_j = p o i n t _ s e q [ 0 ] ;
t _ a d j a c e n t −>c h i l d r e n [1] − >p_k = p [ p_index ] ;
t _ a d j a c e n t −>c h i l d r e n [1] − > c h i l d r e n = NULL ;
t _ a d j a c e n t −>c h i l d r e n [1] − > n u m b e r _ o f _ c h i l d r e n = 0 ;
t _ a d j a c e n t −>c h i l d r e n [1] − > p a r e n t s [ 0 ] = t _ a d j a c e n t ;
t _ a d j a c e n t −>c h i l d r e n [1] − > number_of_parents = 1 ;
t _ a d j a c e n t −>c h i l d r e n [1] − > p r o c e s s e d = f a l s e ;
t _ a d j a c e n t −>c h i l d r e n [1] − > v i s i t e d = f a l s e ;
}

// d e f i n e a d j a c e n c y b e t w e e n new t r i a n g l e s
//
// t r i a n g l e k , j , p :
// a d j a c e n t b y p a r e n t
t_node−>c h i l d r e n [0] − > a d j a c e n t [ 0 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_node ,
t_node−>c h i l d r e n [ 0 ] , t_node−>p_k , t_node−>p_j , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t i , j , p
t_node−>c h i l d r e n [0] − > a d j a c e n t [ 1 ] = t_node−>c h i l d r e n [ 1 ] ;
// a d j a c e n t k , l , p
i f ( t _ a d j a c e n t != NULL)
t_node−>c h i l d r e n [0] − > a d j a c e n t [ 2 ] = t _ a d j a c e n t −>c h i l d r e n [ 0 ] ;

// t r i a n g l e i , j , p :
// a d j a c e n t b y p a r e n t
t_node−>c h i l d r e n [1] − > a d j a c e n t [ 0 ] = a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( t_node ,
t_node−>c h i l d r e n [ 1 ] , t_node−>p_i , t_node−>p_j , u s e l e s s _ p o i n t _ s e q ) ;
// a d j a c e n t k , j , p
t_node−>c h i l d r e n [1] − > a d j a c e n t [ 1 ] = t_node−>c h i l d r e n [ 0 ] ;
// a d j a c e n t i , l , p
i f ( t _ a d j a c e n t != NULL)
t_node−>c h i l d r e n [1] − > a d j a c e n t [ 2 ] = t _ a d j a c e n t −>c h i l d r e n [ 1 ] ;

i f ( t _ a d j a c e n t != NULL)
{
// t r i a n g l e k , l , p :
// a d j a c e n t b y p a r e n t
t _ a d j a c e n t −>c h i l d r e n [0] − > a d j a c e n t [ 0 ] = adjacent_triangle_by_parent (
t _ a d j a c e n t , t _ a d j a c e n t −>c h i l d r e n [ 0 ] , point_seq [ 1 ] , point_seq [ 0 ] ,
useless_point_seq ) ;
// a d j a c e n t i , l , p
t _ a d j a c e n t −>c h i l d r e n [0] − > a d j a c e n t [ 1 ] = t _ a d j a c e n t −>c h i l d r e n [ 1 ] ;
// a d j a c e n t k , j , p
t _ a d j a c e n t −>c h i l d r e n [0] − > a d j a c e n t [ 2 ] = t_node−>c h i l d r e n [ 0 ] ;
//
// t r i a n g l e i , l , p :
// a d j a c e n t b y p a r e n t
t _ a d j a c e n t −>c h i l d r e n [1] − > a d j a c e n t [ 0 ] = adjacent_triangle_by_parent (
t _ a d j a c e n t , t _ a d j a c e n t −>c h i l d r e n [ 1 ] , point_seq [ 2 ] , point_seq [ 0 ] ,
useless_point_seq ) ;
// a d j a c e n t k , l , p
t _ a d j a c e n t −>c h i l d r e n [1] − > a d j a c e n t [ 1 ] = t _ a d j a c e n t −>c h i l d r e n [ 0 ] ;
// a d j a c e n t i , j , p
t _ a d j a c e n t −>c h i l d r e n [1] − > a d j a c e n t [ 2 ] = t_node−>c h i l d r e n [ 1 ] ;
}

// l e g a l i z e t h e e d g e s o f t h e d i v i d e d t r i a n g l e
l e g a l i z e _ e d g e ( p [ p_index ] , t_node−>p_k , p o i n t _ s e q [ 0 ] , t _ a d j a c e n t −>
c h i l d r e n [0] − > a d j a c e n t [ 0 ] , t _ a d j a c e n t −>c h i l d r e n [ 0 ] ) ;
l e g a l i z e _ e d g e ( p [ p_index ] , p o i n t _ s e q [ 0 ] , t_node−>p_i , t _ a d j a c e n t −>
c h i l d r e n [1] − > a d j a c e n t [ 0 ] , t _ a d j a c e n t −>c h i l d r e n [ 1 ] ) ;
l e g a l i z e _ e d g e ( p [ p_index ] , t_node−>p_i , t_node−>p_j , t_node−>c h i l d r e n
[1] − > a d j a c e n t [ 0 ] , t_node−>c h i l d r e n [ 1 ] ) ;
l e g a l i z e _ e d g e ( p [ p_index ] , t_node−>p_j , t_node−>p_k , t_node−>c h i l d r e n
[0] − > a d j a c e n t [ 0 ] , t_node−>c h i l d r e n [ 0 ] ) ;
}

// no n e e d t o v e r i f y o t h e r t r i a n g l e s in the queue , empty t h e queue


t q = queue<s t r u c t TRIANGLE ∗ >() ;
}
}
}

28
}

// p e r f o r m a DFS on t h e t r e e t o s e a r c h l e a f n o d e s w h i c h a r e D e l a u n a y triangles
define_delaunay_triangles_from_tree ( triangles_tree , t r i a n g l e s ) ;

return ( t r i a n g l e s ) ;
}

29
ANNEX E - GEOMETRIC FUNCTIONS
// c a l c u l a t e s e u c l i d i a n d i s t a n c e b e t w e e n 2 p o i n t s i n t h e plane
double d i s t a n c e _ b e t w e e n ( s t r u c t POINT p , s t r u c t POINT q )
{
double d i s t , dx , dy ;

dx = p . x − q . x ;
dy = p . y − q . y ;
d i s t = s q r t ( dx∗dx+dy∗dy ) ;

return ( d i s t ) ;
}

// c a l c u l a t e s d i s t a n c e b e t w e e n p o i n t p and l i n e Ax+By+C w i t h c o e f f i c i e n t s A, B , C a s | A∗ x+B∗ y+C | /


SQRT(A^2+B^ 2 )
double p o i n t _ l i n e _ d i s t a n c e ( double A, double B , double C, s t r u c t POINT p )
{
double d i s t a n c e ;

d i s t a n c e = a b s (A∗ ( p . x ) + B∗ ( p . y ) + C) / s q r t (A∗A + B∗B) ;

return ( d i s t a n c e ) ;
}

// v e r i f i e s i f p o i n t p i s on t h e l i n e t h a t p a s s e s t h r o u g h p o i n t s p1 , p2
//
// u s e s p o i n t −l i n e d i s t a n c e f o r m u l a b y c a l c u l a t i n g t h e c o e f f i c i e n t s A, B , C o f the l i n e Ax+By+C=0
f r o m p o i n t s p1 , p2
bool s a m e _ s l o p e ( s t r u c t POINT p , s t r u c t POINT p1 , s t r u c t POINT p2 )
{
double A, B , C, d i s t a n c e ;

// c o e f f i c i e n t s o f l i n e p1 , p2
A = p1 . y − p2 . y ;
B = p2 . x − p1 . x ;
C = ( p1 . x − p2 . x ) ∗ p1 . y + ( p2 . y − p1 . y ) ∗ p1 . x ;

// d i s t a n c e b e t w e e n p o i n t p and l i n e p1 , p2
d i s t a n c e = p o i n t _ l i n e _ d i s t a n c e (A, B , C, p ) ;

// i f d i s t a n c e i s l e s s t h a n an e r r o r , then point is on t h e line


i f ( d i s t a n c e < epsEdge )
return ( true ) ;
else
return ( f a l s e ) ;
}

// c a l c u l a t e s i n t e r s e c t i o n p o i n t b e t w e e n 2 s e g m e n t s p1 , p2 and p3 , p4
//
// c a s e s o f v e r t i c a l / h o r i z o n t a l l i n e s a r e t r e a t e d s e p a r a t e l y
//
// c o o r d i n a t e s o f i n t e r s e c t i o n p o i n t a r e t h e s o l u t i o n o f s y s t e m o f 2 e q u a t i o n s
s t r u c t POINT s e g m e n t _ i n t e r s e c t i o n ( s t r u c t POINT p1 , s t r u c t POINT p2 , s t r u c t POINT p3 , struct
POINT p4 )
{
s t r u c t POINT p ;
double x i , y i , m12 , m34 ;

// p a r a l l e l l i n e s
i f ( s a m e _ s l o p e ( p1 , p3 , p4 ) == true && s a m e _ s l o p e ( p2 , p3 , p4 ) == true )
{
p . x = UNDEF;
p . y = UNDEF;

return ( p ) ;
}

// s e g m e n t p1 , p2 i s v e r t i c a l
i f ( a b s ( p1 . x − p2 . x ) < e p s V e r t e x )
{
// s e g m e n t p3 , p4 i s v e r t i c a l , s o both are parallel , there is no intersection point
i f ( a b s ( p3 . x − p4 . x ) < e p s V e r t e x )
{
p . x = UNDEF;
p . y = UNDEF;

31
return ( p ) ;
}

// s e g m e n t p3 , p4 i s h o r i z o n t a l
i f ( a b s ( p3 . y − p4 . y ) < e p s V e r t e x )
{
p . x = p1 . x ;
p . y = p3 . y ;

i f ((( − e p s V e r t e x + p3 . x <= p . x && p . x <= p4 . x + e p s V e r t e x ) | | (− e p s V e r t e x + p4 . x <= p


. x && p . x <= p3 . x + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p1 . y <= p . y && p . y <= p2 . y + e p s V e r t e x ) | | (− e p s V e r t e x + p2 . y <= p
. y && p . y <= p1 . y + e p s V e r t e x ) ) )
return ( p ) ;

p . x = UNDEF;
p . y = UNDEF;

return ( p ) ;
}

// s e g m e n t p3 , p4 i s n o t v e r t i c a l / h o r i z o n t a l
x i = p1 . x ;
m34 = ( p4 . y − p3 . y ) / ( p4 . x − p3 . x ) ;
y i = p3 . y + m34 ∗ ( x i − p3 . x ) ;

p . x = xi ;
p . y = yi ;

i f ((( − e p s V e r t e x + p3 . x <= p . x && p . x <= p4 . x + e p s V e r t e x ) | | (− e p s V e r t e x + p4 . x <= p . x


&& p . x <= p3 . x + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p3 . y <= p . y && p . y <= p4 . y + e p s V e r t e x ) | | (− e p s V e r t e x + p4 . y <= p . y
&& p . y <= p3 . y + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p1 . y <= p . y && p . y <= p2 . y + e p s V e r t e x ) | | (− e p s V e r t e x + p2 . y <= p . y
&& p . y <= p1 . y + e p s V e r t e x ) ) )
return ( p ) ;

p . x = UNDEF;
p . y = UNDEF;

return ( p ) ;
}

// s e g m e n t p1 , p2 i s h o r i z o n t a l
i f ( a b s ( p1 . y − p2 . y ) < e p s V e r t e x )
{
// s e g m e n t p3 , p4 i s h o r i z o n t a l , s o both are parallel , there is no intersection point
i f ( a b s ( p3 . y − p4 . y ) < e p s V e r t e x )
{
p . x = UNDEF;
p . y = UNDEF;

return ( p ) ;
}

// s e g m e n t p3 , p4 i s v e r t i c a l
i f ( a b s ( p3 . x − p4 . x ) < e p s V e r t e x )
{
p . x = p3 . x ;
p . y = p1 . y ;

i f ((( − e p s V e r t e x + p1 . x <= p . x && p . x <= p2 . x + e p s V e r t e x ) | | (− e p s V e r t e x + p2 . x <= p


. x && p . x <= p1 . x + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p3 . y <= p . y && p . y <= p4 . y + e p s V e r t e x ) | | (− e p s V e r t e x + p4 . y <= p
. y && p . y <= p3 . y + e p s V e r t e x ) ) )
return ( p ) ;

p . x = UNDEF;
p . y = UNDEF;

return ( p ) ;
}

// s e g m e n t p3 , p4 i s n o t v e r t i c a l / h o r i z o n t a l
y i = p1 . y ;
m34 = ( p4 . y − p3 . y ) / ( p4 . x − p3 . x ) ;
x i = ( y i − p3 . y ) /m34 + p3 . x ;

32
p . x = xi ;
p . y = yi ;

i f ((( − e p s V e r t e x + p3 . x <= p . x && p . x <= p4 . x + e p s V e r t e x ) | | (− e p s V e r t e x + p4 . x <= p . x


&& p . x <= p3 . x + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p3 . y <= p . y && p . y <= p4 . y + e p s V e r t e x ) | | (− e p s V e r t e x + p4 . y <= p . y
&& p . y <= p3 . y + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p1 . x <= p . x && p . x <= p2 . x + e p s V e r t e x ) | | (− e p s V e r t e x + p2 . x <= p . x
&& p . x <= p1 . x + e p s V e r t e x ) ) )
return ( p ) ;

p . x = UNDEF;
p . y = UNDEF;

return ( p ) ;
}

// s e g m e n t p1 , p2 i s n o t v e r t i c a l / h o r i z o n t a l
//
// s e g m e n t p3 , p4 i s v e r t i c a l
i f ( a b s ( p3 . x − p4 . x ) < e p s V e r t e x )
{
x i = p3 . x ;
m12 = ( p2 . y − p1 . y ) / ( p2 . x − p1 . x ) ;
y i = p1 . y + m12 ∗ ( x i − p1 . x ) ;

p . x = xi ;
p . y = yi ;

i f ((( − e p s V e r t e x + p1 . x <= p . x && p . x <= p2 . x + e p s V e r t e x ) | | (− e p s V e r t e x + p2 . x <= p . x


&& p . x <= p1 . x + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p1 . y <= p . y && p . y <= p2 . y + e p s V e r t e x ) | | (− e p s V e r t e x + p2 . y <= p . y
&& p . y <= p1 . y + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p3 . y <= p . y && p . y <= p4 . y + e p s V e r t e x ) | | (− e p s V e r t e x + p4 . y <= p . y
&& p . y <= p3 . y + e p s V e r t e x ) ) )
return ( p ) ;

p . x = UNDEF;
p . y = UNDEF;

return ( p ) ;
}
// s e g m e n t p3 , p4 i s h o r i z o n t a l
i f ( a b s ( p3 . y − p4 . y ) < e p s V e r t e x )
{
y i = p3 . y ;
m12 = ( p2 . y − p1 . y ) / ( p2 . x − p1 . x ) ;
x i = ( y i − p1 . y ) /m12 + p1 . x ;

p . x = xi ;
p . y = yi ;

i f ((( − e p s V e r t e x + p1 . x <= p . x && p . x <= p2 . x + e p s V e r t e x ) | | (− e p s V e r t e x + p2 . x <= p . x


&& p . x <= p1 . x + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p1 . y <= p . y && p . y <= p2 . y + e p s V e r t e x ) | | (− e p s V e r t e x + p2 . y <= p . y
&& p . y <= p1 . y + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p3 . x <= p . x && p . x <= p4 . x + e p s V e r t e x ) | | (− e p s V e r t e x + p4 . x <= p . x
&& p . x <= p3 . x + e p s V e r t e x ) ) )
return ( p ) ;

p . x = UNDEF;
p . y = UNDEF;

return ( p ) ;
}

// b o t h s e g m e n t s a r e n o t h o r i z o n t a l / v e r t i c a l
m12 = ( p2 . y − p1 . y ) / ( p2 . x − p1 . x ) ;
m34 = ( p4 . y − p3 . y ) / ( p4 . x − p3 . x ) ;
x i = ( p3 . y − p1 . y − m34∗ p3 . x + m12∗ p1 . x ) / ( m12 − m34 ) ;
y i = p1 . y + m12 ∗ ( x i − p1 . x ) ;

p . x = xi ;
p . y = yi ;

i f ((( − e p s V e r t e x + p1 . x <= p . x && p . x <= p2 . x + e p s V e r t e x ) | | (− e p s V e r t e x + p2 . x <= p . x && p .

33
x <= p1 . x + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p1 . y <= p . y && p . y <= p2 . y + e p s V e r t e x ) | | (− e p s V e r t e x + p2 . y <= p . y && p .
y <= p1 . y + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p3 . x <= p . x && p . x <= p4 . x + e p s V e r t e x ) | | (− e p s V e r t e x + p4 . x <= p . x && p .
x <= p3 . x + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + p3 . y <= p . y && p . y <= p4 . y + e p s V e r t e x ) | | (− e p s V e r t e x + p4 . y <= p . y && p .
y <= p3 . y + e p s V e r t e x ) ) )
return ( p ) ;

p . x = UNDEF;
p . y = UNDEF;

return ( p ) ;
}

// verifies if point is inside t r i a n g l e , on an e d g e o r outside triangle


//
// c o n s i d e r s a h o r i z o n t a l l i n e from t h e p o i n t going to the right and c h e c k s how many and w h a t
kind of i n t e r s e c t i o n s with edges occur
//
// r e t u r n v a l u e s
// 0 − p o i n t i s o u t s i d e t r i a n g l e
// 1 − p o i n t i s on an e d g e
// 2 − p o i n t i s i n s i d e t r i a n g l e
i n t p o i n t _ i n _ t r i a n g l e ( s t r u c t POINT p , s t r u c t TRIANGLE t )
{
s t r u c t POINT pmax , i n t e r s e c t i o n _ p o i n t ;
double max_x ;
int e d g e _ i n t e r s e c t i o n s ;
bool up , down ;

// i f p o i n t i s on t h e e d g e i , j
i f ( s a m e _ s l o p e ( p , t . p_i , t . p_j ) == true )
{
s a m e _ s l o p e _ i j = true ;
same_slope_jk = s a m e _ s l o p e _ k i = f a l s e ;

// i f c o o r d i n a t e s o f t h e p o i n t a r e i n t h e r a n g e o f t h e c o o r d i n a t e s o f t h e e d g e p o i n t s
i f ((( − e p s V e r t e x + t . p_i . x <= p . x && p . x <= t . p_j . x + e p s V e r t e x ) | | (− e p s V e r t e x + t . p_j . x
<= p . x && p . x <= t . p_i . x + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + t . p_i . y <= p . y && p . y <= t . p_j . y + e p s V e r t e x ) | | (− e p s V e r t e x + t . p_j . y
<= p . y && p . y <= t . p_i . y + e p s V e r t e x ) ) )
return ( 1 ) ;
else
return ( 0 ) ;
}

// i f p o i n t i s on t h e e d g e j , k
i f ( s a m e _ s l o p e ( p , t . p_j , t . p_k ) == true )
{
same_slope_jk = true ;
same_slope_ki = same_slope_ij = f a l s e ;

// i f c o o r d i n a t e s o f t h e p o i n t a r e i n t h e r a n g e o f t h e c o o r d i n a t e s o f t h e e d g e p o i n t s
i f ((( − e p s V e r t e x + t . p_j . x <= p . x && p . x <= t . p_k . x + e p s V e r t e x ) | | (− e p s V e r t e x + t . p_k . x
<= p . x && p . x <= t . p_j . x + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + t . p_j . y <= p . y && p . y <= t . p_k . y + e p s V e r t e x ) | | (− e p s V e r t e x + t . p_k . y
<= p . y && p . y <= t . p_j . y + e p s V e r t e x ) ) )
return ( 1 ) ;
else
return ( 0 ) ;
}

// i f p o i n t i s on t h e e d g e k , i
i f ( s a m e _ s l o p e ( p , t . p_k , t . p_i ) == true )
{
s a m e _ s l o p e _ k i = true ;
s a m e _ s l o p e _ i j = same_slope_jk = f a l s e ;

// i f c o o r d i n a t e s o f t h e p o i n t a r e i n t h e r a n g e o f t h e c o o r d i n a t e s o f t h e e d g e p o i n t s
i f ((( − e p s V e r t e x + t . p_k . x <= p . x && p . x <= t . p_i . x + e p s V e r t e x ) | | (− e p s V e r t e x + t . p_i . x
<= p . x && p . x <= t . p_k . x + e p s V e r t e x ) ) &&
(( − e p s V e r t e x + t . p_k . y <= p . y && p . y <= t . p_i . y + e p s V e r t e x ) | | (− e p s V e r t e x + t . p_i . y
<= p . y && p . y <= t . p_k . y + e p s V e r t e x ) ) )
return ( 1 ) ;
else
return ( 0 ) ;

34
}

// d e f i n e s maximum x coordinate from points i , j , k of the triangle


max_x = − 1 . ;
i f ( t . p_i . x > max_x )
max_x = t . p_i . x ;
i f ( t . p_j . x > max_x )
max_x = t . p_j . x ;
i f ( t . p_k . x > max_x )
max_x = t . p_k . x ;

// c o o r d i n a t e s o f t h e outside p o i n t pmax
pmax . x = max_x + INC ;
pmax . y = p . y ;

// v e r i f i e s i f point is inside triangle by the intersection between horizontal line from


point p with the t r i a n g l e edges
//
// i n i t i a l i z e number o f i n t e r s e c t i o n s and d i r e c t i o n o f e d g e p o i n t s
edge_intersections = 0;
up = down = f a l s e ;
// i n t e r s e c t i o n b e t w e e n s e g m e n t s p , pmax and i , j
i n t e r s e c t i o n _ p o i n t = s e g m e n t _ i n t e r s e c t i o n ( p , pmax , t . p_i , t . p_j ) ;
// i f i n t e r s e c t i o n e x i s t s
i f ( p o i n t _ n o t _ u n d e f ( i n t e r s e c t i o n _ p o i n t ) == true )
{
// i n c r e m e n t number o f i n t e r s e c t i o n s
e d g e _ i n t e r s e c t i o n s ++;

// i f i n t e r s e c t i o n i s a v e r t e x
i f ( p o i n t s _ a r e _ e q u a l ( t . p_i , i n t e r s e c t i o n _ p o i n t ) == true )
{
// i f i n t e r s e c t e d v e r t e x i s up o r down on t h e edge
i f ( t . p_i . y < t . p_j . y )
down = true ;
else
up = true ;
}
else
// i f i n t e r s e c t i o n i s a v e r t e x
i f ( p o i n t s _ a r e _ e q u a l ( t . p_j , i n t e r s e c t i o n _ p o i n t ) == true )
{
// i f i n t e r s e c t e d v e r t e x i s up o r down on t h e edge
i f ( t . p_j . y < t . p_i . y )
down = true ;
else
up = true ;
}
}

// i n t e r s e c t i o n b e t w e e n s e g m e n t s p , pmax and j , k
i n t e r s e c t i o n _ p o i n t = s e g m e n t _ i n t e r s e c t i o n ( p , pmax , t . p_j , t . p_k ) ;
// i f i n t e r s e c t i o n e x i s t s
i f ( p o i n t _ n o t _ u n d e f ( i n t e r s e c t i o n _ p o i n t ) == true )
{
// i n c r e m e n t number o f i n t e r s e c t i o n s
e d g e _ i n t e r s e c t i o n s ++;

// i f i n t e r s e c t i o n i s a v e r t e x
i f ( p o i n t s _ a r e _ e q u a l ( t . p_j , i n t e r s e c t i o n _ p o i n t ) == true )
{
// i f i n t e r s e c t e d v e r t e x i s up o r down on t h e edge
i f ( t . p_j . y < t . p_k . y )
down = true ;
else
up = true ;
}
else
// i f i n t e r s e c t i o n i s a v e r t e x
i f ( p o i n t s _ a r e _ e q u a l ( t . p_k , i n t e r s e c t i o n _ p o i n t ) == true )
{
// i f i n t e r s e c t e d v e r t e x i s up o r down on t h e edge
i f ( t . p_k . y < t . p_j . y )
down = true ;
else
up = true ;
}

35
}

// i n t e r s e c t i o n b e t w e e n s e g m e n t s p , pmax and k , i
i n t e r s e c t i o n _ p o i n t = s e g m e n t _ i n t e r s e c t i o n ( p , pmax , t . p_k , t . p_i ) ;
// i f i n t e r s e c t i o n e x i s t s
i f ( p o i n t _ n o t _ u n d e f ( i n t e r s e c t i o n _ p o i n t ) == true )
{
// i n c r e m e n t number o f i n t e r s e c t i o n s
e d g e _ i n t e r s e c t i o n s ++;

// i f i n t e r s e c t i o n i s a v e r t e x
i f ( p o i n t s _ a r e _ e q u a l ( t . p_k , i n t e r s e c t i o n _ p o i n t ) == true )
{
// i f i n t e r s e c t e d v e r t e x i s up o r down on t h e edge
i f ( t . p_k . y < t . p_i . y )
down = true ;
else
up = true ;
}
else
// i f i n t e r s e c t i o n i s a v e r t e x
i f ( p o i n t s _ a r e _ e q u a l ( t . p_i , i n t e r s e c t i o n _ p o i n t ) == true )
{
// i f i n t e r s e c t e d v e r t e x i s up o r down on t h e edge
i f ( t . p_i . y < t . p_k . y )
down = true ;
else
up = true ;
}
}

// if number o f i n t e r s e c t i o n s w i t h e d g e s i s e i t h e r 1 o r 2 and i t h a p p e n e d w i t h a v e r t e x
forming a r i g h t " beak " , then point i s i n s i d e t r i a n g l e
i f ( ( e d g e _ i n t e r s e c t i o n s == 1 ) | | ( e d g e _ i n t e r s e c t i o n s == 2 && down == true && up == true ) )
return ( 2 ) ;

return ( 0 ) ;
}

// c a l c u l a t e s t h e c e n t e r and r a d i u s o f a c i r c u n f e r e n c e p a s s i n g t h r o u g h p o i n t s p , p1 , p2
void c i r c l e _ b y _ 3 _ p o i n t s ( s t r u c t POINT p , s t r u c t POINT p1 , s t r u c t POINT p2 , double ∗ xc , double ∗ yc
, double ∗ r )
{
double dx , dy ;
double m1 , m2 , xm1 , ym1 , xm2 , ym2 ;

// v e r i f i e s i f l i n e p1 , p2 i s v e r t i c a l and p2 , p i s h o r i z o n t a l , t h e n c i r c u m c e n t e r i s d e f i n e d
b y mean p o i n t
i f ( a b s ( p1 . x − p2 . x ) < e p s V e r t e x && a b s ( p2 . y − p . y ) < e p s V e r t e x )
{
// c a l c u l a t e s c i r c u m c e n t e r c o o r d i n a t e s
∗ xc = ( p2 . x + p . x ) / 2 ;
∗ yc = ( p1 . y + p2 . y ) / 2 ;
}
else
// v e r i f i e s i f l i n e p2 , p i s v e r t i c a l and p , p1 i s h o r i z o n t a l , t h e n c i r c u m c e n t e r i s d e f i n e d b y
mean p o i n t
i f ( a b s ( p2 . x − p . x ) < e p s V e r t e x && a b s ( p . y − p1 . y ) < e p s V e r t e x )
{
// c a l c u l a t e s c i r c u m c e n t e r c o o r d i n a t e s
∗ xc = ( p . x + p1 . x ) / 2 ;
∗ yc = ( p2 . y + p . y ) / 2 ;
}
else
// v e r i f i e s i f l i n e p , p1 i s v e r t i c a l and p1 , p2 i s h o r i z o n t a l , t h e n c i r c u m c e n t e r i s d e f i n e d
b y mean p o i n t
i f ( a b s ( p . x − p1 . x ) < e p s V e r t e x && a b s ( p1 . y − p2 . y ) < e p s V e r t e x )
{
// c a l c u l a t e s c i r c u m c e n t e r c o o r d i n a t e s
∗ xc = ( p1 . x + p2 . x ) / 2 ;
∗ yc = ( p . y + p1 . y ) / 2 ;
}
else
// v e r i f i e s i f l i n e p1 , p2 i s h o r i z o n t a l and p2 , p i s v e r t i c a l , t h e n c i r c u m c e n t e r i s d e f i n e d
b y mean p o i n t
i f ( a b s ( p1 . y − p2 . y ) < e p s V e r t e x && a b s ( p2 . x − p . x ) < e p s V e r t e x )
{

36
// c a l c u l a t e s c i r c u m c e n t e r coordinates
∗ xc = ( p1 . x + p2 . x ) / 2 ;
∗ yc = ( p2 . y + p . y ) / 2 ;
}
else
// v e r i f i e s i f l i n e p2 , p i s h o r i z o n t a l and p , p1 i s v e r t i c a l , t h e n c i r c u m c e n t e r i s d e f i n e d b y
mean p o i n t
i f ( a b s ( p2 . y − p . y ) < e p s V e r t e x && a b s ( p . x − p1 . x ) < e p s V e r t e x )
{
// c a l c u l a t e s c i r c u m c e n t e r c o o r d i n a t e s
∗ xc = ( p2 . x + p . x ) / 2 ;
∗ yc = ( p . y + p1 . y ) / 2 ;
}
else
// v e r i f i e s i f l i n e p , p1 i s h o r i z o n t a l and p1 , p2 i s v e r t i c a l , t h e n c i r c u m c e n t e r i s d e f i n e d
b y mean p o i n t
i f ( a b s ( p . y − p1 . y ) < e p s V e r t e x && a b s ( p1 . x − p2 . x ) < e p s V e r t e x )
{
// c a l c u l a t e s c i r c u m c e n t e r c o o r d i n a t e s
∗ xc = ( p . x + p1 . x ) / 2 ;
∗ yc = ( p1 . y + p2 . y ) / 2 ;
}
else
// v e r i f i e s i f l i n e p1 , p2 i s v e r t i c a l , t h e n c i r c u m c e n t e r i s d e f i n e d b y c o n s t a n t l i n e
i f ( a b s ( p1 . x − p2 . x ) < e p s V e r t e x )
{
// c a l c u l a t e s c i r c u m c e n t e r c o o r d i n a t e s
// v e r t i c a l l i n e , c a l c u l a t e s mean y and x b y i n t e r s e c t i o n
∗ yc = ( p1 . y + p2 . y ) / 2 ;
xm2 = ( p2 . x + p . x ) / 2 ;
ym2 = ( p2 . y + p . y ) / 2 ;
m2 = ( p . y − p2 . y ) / ( p . x − p2 . x ) ;
∗ xc = −(∗ yc − ym2 ) ∗m2 + xm2 ;
}
else
// v e r i f i e s i f l i n e p2 , p i s v e r t i c a l , t h e n c i r c u m c e n t e r i s d e f i n e d b y c o n s t a n t l i n e
i f ( a b s ( p2 . x − p . x ) < e p s V e r t e x )
{
// c a l c u l a t e s c i r c u m c e n t e r c o o r d i n a t e s
// v e r t i c a l l i n e , c a l c u l a t e s mean y and x b y i n t e r s e c t i o n
∗ yc = ( p2 . y + p . y ) / 2 ;
xm1 = ( p1 . x + p2 . x ) / 2 ;
ym1 = ( p1 . y + p2 . y ) / 2 ;
m1 = ( p2 . y − p1 . y ) / ( p2 . x − p1 . x ) ;
∗ xc = −(∗ yc − ym1 ) ∗m1 + xm1 ;
}
else
// v e r i f i e s i f l i n e p , p1 i s v e r t i c a l , t h e n c i r c u m c e n t e r i s d e f i n e d b y c o n s t a n t l i n e
i f ( a b s ( p . x − p1 . x ) < e p s V e r t e x )
{
// c a l c u l a t e s c i r c u m c e n t e r c o o r d i n a t e s
// v e r t i c a l l i n e , c a l c u l a t e s mean y and x b y i n t e r s e c t i o n
∗ yc = ( p . y + p1 . y ) / 2 ;
xm1 = ( p1 . x + p2 . x ) / 2 ;
ym1 = ( p1 . y + p2 . y ) / 2 ;
m1 = ( p2 . y − p1 . y ) / ( p2 . x − p1 . x ) ;
∗ xc = −(∗ yc − ym1 ) ∗m1 + xm1 ;
}
else
// v e r i f i e s i f l i n e p1 , p2 i s h o r i z o n t a l , t h e n c i r c u m c e n t e r i s d e f i n e d b y c o n s t a n t l i n e
i f ( a b s ( p1 . y − p2 . y ) < e p s V e r t e x )
{
// c a l c u l a t e s c i r c u m c e n t e r c o o r d i n a t e s
// v e r t i c a l l i n e , c a l c u l a t e s mean x and y b y i n t e r s e c t i o n
∗ xc = ( p1 . x + p2 . x ) / 2 ;
xm2 = ( p2 . x + p . x ) / 2 ;
ym2 = ( p2 . y + p . y ) / 2 ;
m2 = ( p . y − p2 . y ) / ( p . x − p2 . x ) ;
∗ yc = −(∗ xc − xm2 ) /m2 + ym2 ;
}
else
// v e r i f i e s i f l i n e p2 , p i s h o r i z o n t a l , t h e n c i r c u m c e n t e r i s d e f i n e d b y c o n s t a n t l i n e
i f ( a b s ( p2 . y − p . y ) < e p s V e r t e x )
{
// c a l c u l a t e s c i r c u m c e n t e r c o o r d i n a t e s
// v e r t i c a l l i n e , c a l c u l a t e s mean x and y b y i n t e r s e c t i o n
∗ xc = ( p2 . x + p . x ) / 2 ;

37
xm1 = ( p1 . x + p2 . x ) / 2 ;
ym1 = ( p1 . y + p2 . y ) / 2 ;
m1 = ( p2 . y − p1 . y ) / ( p2 . x − p1 . x ) ;
∗ yc = −(∗ xc − xm1 ) /m1 + ym1 ;
}
else
// v e r i f i e s i f l i n e p , p1 i s h o r i z o n t a l , t h e n c i r c u m c e n t e r i s d e f i n e d by constant line
i f ( a b s ( p . y − p1 . y ) < e p s V e r t e x )
{
// c a l c u l a t e s c i r c u m c e n t e r c o o r d i n a t e s
// v e r t i c a l l i n e , c a l c u l a t e s mean x and y b y i n t e r s e c t i o n
∗ xc = ( p . x + p1 . x ) / 2 ;
xm1 = ( p1 . x + p2 . x ) / 2 ;
ym1 = ( p1 . y + p2 . y ) / 2 ;
m1 = ( p2 . y − p1 . y ) / ( p2 . x − p1 . x ) ;
∗ yc = −(∗ xc − xm1 ) /m1 + ym1 ;
}
else
{
// i f b o t h l i n e s a r e n o t h o r i z o n t a l / v e r t i c a l
xm1 = ( p1 . x + p2 . x ) / 2 ;
ym1 = ( p1 . y + p2 . y ) / 2 ;
xm2 = ( p2 . x + p . x ) / 2 ;
ym2 = ( p2 . y + p . y ) / 2 ;
m1 = ( p2 . y − p1 . y ) / ( p2 . x − p1 . x ) ;
m2 = ( p . y − p2 . y ) / ( p . x − p2 . x ) ;
∗ xc = ( xm2/m2 + ym2 − xm1/m1 − ym1 ) / ( 1 /m2 − 1/m1) ;
∗ yc = −(∗ xc − xm1 ) /m1 + ym1 ;
}

// calculates radius
dx = p . x − ∗ xc ;
dy = p . y − ∗ yc ;
∗r = s q r t ( dx∗dx + dy∗dy ) ;

return ;
}

38
ANNEX F - UTILITY FUNCTIONS
// v e r i f i e s i f p o i n t c o o r d i n a t e s a r e defined
bool p o i n t _ n o t _ u n d e f ( s t r u c t POINT p )
{
i f ( p . x != UNDEF && p . y != UNDEF)
return ( true ) ;
else
return ( f a l s e ) ;
}

// r e t u r n s i f 2 p o i n t s h a v e t h e same c o o r d i n a t e s
bool p o i n t s _ a r e _ e q u a l ( s t r u c t POINT p1 , s t r u c t POINT p2 )
{
return ( a b s ( p1 . x − p2 . x ) < e p s V e r t e x && a b s ( p1 . y − p2 . y ) < e p s V e r t e x ) ;
}

// r e t u r n i f 2 e d g e s h a v e t h e same p o i n t s
bool e d g e s _ a r e _ e q u a l ( s t r u c t POINT p1 , s t r u c t POINT p2 , s t r u c t POINT p3 , s t r u c t POINT p4 )
{
return ( ( p o i n t s _ a r e _ e q u a l ( p1 , p3 ) == true && p o i n t s _ a r e _ e q u a l ( p2 , p4 ) == true ) | |
( p o i n t s _ a r e _ e q u a l ( p1 , p4 ) == true && p o i n t s _ a r e _ e q u a l ( p2 , p3 ) == true ) ) ;
}

// v e r i f i e s i f p o i n t s p1 , p2 a r e an e d g e o f a t r i a n g l e adjacent to the parent triangle and


returns the pointer to the adjacent t r i a n g l e
//
// i n a d d i t i o n , s t o r e s as p o i n t e r s in a v e c t o r t he c o o r d i n a t e s o f t he point opposite to the edge
and t h e p o i n t s o f t h e e d g e , i n t h i s o r d e r
s t r u c t TRIANGLE ∗ a d j a c e n t _ t r i a n g l e _ b y _ p a r e n t ( s t r u c t TRIANGLE ∗ p a r e n t , s t r u c t TRIANGLE ∗ c h i l d ,
s t r u c t POINT p1 , s t r u c t POINT p2 , s t r u c t POINT ∗ p o i n t _ s e q )
{
s t r u c t TRIANGLE ∗ t ;
int i , j ;

// p r o c e s s e d g e s
f o r ( i = 0 ; i < 3 ; i ++)
{
// a d j a c e n t t r i a n g l e b y e d g e
t = p a r e n t −>a d j a c e n t [ i ] ;

// i f a d j a c e n t t r i a n g l e e x i s t s
i f ( t != NULL)
{
// i f p o i n t s f o r m an e d g e
i f ( p o i n t s _ a r e _ e q u a l ( p1 , t−>p_i ) == true && p o i n t s _ a r e _ e q u a l ( p2 , t−>p_j ) == true )
{
// s t o r e p o i n t s : o p p o s i t e and f r o m t h e e d g e
p o i n t _ s e q [ 0 ] = t−>p_k ;
p o i n t _ s e q [ 1 ] = t−>p_i ;
p o i n t _ s e q [ 2 ] = t−>p_j ;

// i f n e c e s s a r y t o c h a n g e a d j a c e n c y
i f ( p a r e n t != c h i l d )
// d e f i n e a d j a c e n t t o a d j a c e n t t r i a n g l e a s c h i l d t r i a n g l e
f o r ( j = 0 ; j < 3 ; j ++)
i f ( p a r e n t −>a d j a c e n t [ i ]−> a d j a c e n t [ j ] == p a r e n t )
p a r e n t −>a d j a c e n t [ i ]−> a d j a c e n t [ j ] = c h i l d ;

return ( t ) ;
}
else
// i f p o i n t s f o r m an e d g e
i f ( p o i n t s _ a r e _ e q u a l ( p1 , t−>p_j ) == true && p o i n t s _ a r e _ e q u a l ( p2 , t−>p_i ) == true )
{
// s t o r e p o i n t s : o p p o s i t e and f r o m t h e e d g e
p o i n t _ s e q [ 0 ] = t−>p_k ;
p o i n t _ s e q [ 1 ] = t−>p_j ;
p o i n t _ s e q [ 2 ] = t−>p_i ;

// i f n e c e s s a r y t o c h a n g e a d j a c e n c y
i f ( p a r e n t != c h i l d )
// d e f i n e a d j a c e n t t o a d j a c e n t t r i a n g l e a s c h i l d t r i a n g l e
f o r ( j = 0 ; j < 3 ; j ++)
i f ( p a r e n t −>a d j a c e n t [ i ]−> a d j a c e n t [ j ] == p a r e n t )
p a r e n t −>a d j a c e n t [ i ]−> a d j a c e n t [ j ] = c h i l d ;

39
return ( t ) ;
}
else
// i f p o i n t s f o r m an e d g e
i f ( p o i n t s _ a r e _ e q u a l ( p1 , t−>p_j ) == true && p o i n t s _ a r e _ e q u a l ( p2 , t−>p_k ) == true )
{
// s t o r e p o i n t s : o p p o s i t e and f r o m t h e e d g e
p o i n t _ s e q [ 0 ] = t−>p_i ;
p o i n t _ s e q [ 1 ] = t−>p_j ;
p o i n t _ s e q [ 2 ] = t−>p_k ;

// i f n e c e s s a r y t o c h a n g e a d j a c e n c y
i f ( p a r e n t != c h i l d )
// d e f i n e a d j a c e n t t o a d j a c e n t t r i a n g l e a s c h i l d t r i a n g l e
f o r ( j = 0 ; j < 3 ; j ++)
i f ( p a r e n t −>a d j a c e n t [ i ]−> a d j a c e n t [ j ] == p a r e n t )
p a r e n t −>a d j a c e n t [ i ]−> a d j a c e n t [ j ] = c h i l d ;

return ( t ) ;
}
else
// i f p o i n t s f o r m an e d g e
i f ( p o i n t s _ a r e _ e q u a l ( p1 , t−>p_k ) == true && p o i n t s _ a r e _ e q u a l ( p2 , t−>p_j ) == true )
{
// s t o r e p o i n t s : o p p o s i t e and f r o m t h e e d g e
p o i n t _ s e q [ 0 ] = t−>p_i ;
p o i n t _ s e q [ 1 ] = t−>p_k ;
p o i n t _ s e q [ 2 ] = t−>p_j ;

// i f n e c e s s a r y t o c h a n g e a d j a c e n c y
i f ( p a r e n t != c h i l d )
// d e f i n e a d j a c e n t t o a d j a c e n t t r i a n g l e a s c h i l d t r i a n g l e
f o r ( j = 0 ; j < 3 ; j ++)
i f ( p a r e n t −>a d j a c e n t [ i ]−> a d j a c e n t [ j ] == p a r e n t )
p a r e n t −>a d j a c e n t [ i ]−> a d j a c e n t [ j ] = c h i l d ;

return ( t ) ;
}
else
// i f p o i n t s f o r m an e d g e
i f ( p o i n t s _ a r e _ e q u a l ( p1 , t−>p_k ) == true && p o i n t s _ a r e _ e q u a l ( p2 , t−>p_i ) == true )
{
// s t o r e p o i n t s : o p p o s i t e and f r o m t h e e d g e
p o i n t _ s e q [ 0 ] = t−>p_j ;
p o i n t _ s e q [ 1 ] = t−>p_k ;
p o i n t _ s e q [ 2 ] = t−>p_i ;

// i f n e c e s s a r y t o c h a n g e a d j a c e n c y
i f ( p a r e n t != c h i l d )
// d e f i n e a d j a c e n t t o a d j a c e n t t r i a n g l e a s c h i l d t r i a n g l e
f o r ( j = 0 ; j < 3 ; j ++)
i f ( p a r e n t −>a d j a c e n t [ i ]−> a d j a c e n t [ j ] == p a r e n t )
p a r e n t −>a d j a c e n t [ i ]−> a d j a c e n t [ j ] = c h i l d ;

return ( t ) ;
}
else
// i f p o i n t s f o r m an e d g e
i f ( p o i n t s _ a r e _ e q u a l ( p1 , t−>p_i ) == true && p o i n t s _ a r e _ e q u a l ( p2 , t−>p_k ) == true )
{
// s t o r e p o i n t s : o p p o s i t e and f r o m t h e e d g e
p o i n t _ s e q [ 0 ] = t−>p_j ;
p o i n t _ s e q [ 1 ] = t−>p_i ;
p o i n t _ s e q [ 2 ] = t−>p_k ;

// i f n e c e s s a r y t o c h a n g e a d j a c e n c y
i f ( p a r e n t != c h i l d )
// d e f i n e a d j a c e n t t o a d j a c e n t t r i a n g l e a s c h i l d t r i a n g l e
f o r ( j = 0 ; j < 3 ; j ++)
i f ( p a r e n t −>a d j a c e n t [ i ]−> a d j a c e n t [ j ] == p a r e n t )
p a r e n t −>a d j a c e n t [ i ]−> a d j a c e n t [ j ] = c h i l d ;

return ( t ) ;
}
}
}

40
// no a d j a c e n t triangle by the given edge
t = NULL ;

return ( t ) ;
}

// v e r i f i e s i f p o i n t s p1 , p2 f o r m an e d g e o f t r i a n g l e t and r e t u r n t h e opposite point


s t r u c t POINT o p p o s i t e _ p o i n t _ b y _ e d g e ( s t r u c t POINT p1 , s t r u c t POINT p2 , s t r u c t TRIANGLE ∗ t )
{
s t r u c t POINT o p p o s i t e _ p o i n t ;

// i f t r i a n g l e e x i s t s
i f ( t != NULL)
{
// v e r i f i e s e d g e i , j
i f ( e d g e s _ a r e _ e q u a l ( p1 , p2 , t−>p_i , t−>p_j ) == true )
{
o p p o s i t e _ p o i n t = t−>p_k ;

return ( o p p o s i t e _ p o i n t ) ;
}
// v e r i f i e s e d g e j , k
i f ( e d g e s _ a r e _ e q u a l ( p1 , p2 , t−>p_j , t−>p_k ) == true )
{
o p p o s i t e _ p o i n t = t−>p_i ;

return ( o p p o s i t e _ p o i n t ) ;
}
// v e r i f i e s e d g e i , k
i f ( e d g e s _ a r e _ e q u a l ( p1 , p2 , t−>p_i , t−>p_k ) == true )
{
o p p o s i t e _ p o i n t = t−>p_j ;

return ( o p p o s i t e _ p o i n t ) ;
}
}

// set opposite point with undefined coordinates as p o i n t s p1 , p2 a r e n o t an e d g e of triangle


t
o p p o s i t e _ p o i n t . x = UNDEF;
o p p o s i t e _ p o i n t . y = UNDEF;
o p p o s i t e _ p o i n t . z = UNDEF;
o p p o s i t e _ p o i n t . a d d r e s s = NULL ;

return ( o p p o s i t e _ p o i n t ) ;
}

41

Você também pode gostar