Escolar Documentos
Profissional Documentos
Cultura Documentos
30-MAN
INPE
São José dos Campos
2015
PUBLICADO POR:
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
v
LIST OF FIGURES
Page
vii
CONTENTS
Page
1 INTRODUCTION . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
2 DELAUNAY TRIANGULATION . . . . . . . . . . . . . . . . . . 3
3 INCREMENTAL ALGORITHM . . . . . . . . . . . . . . . . . . . 5
4 CONCLUSIONS . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
REFERENCES . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
ix
1 INTRODUCTION
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
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.
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.
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.
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)
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.
7
4 CONCLUSIONS
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
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
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 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 ;
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 ) ;
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 ;
// 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 ] ) ;
// 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 ] ) ;
// 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 ] ) ;
}
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 ) ;
}
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 ) ;
// 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 ;
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 ;
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 ;
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 ;
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 ;
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 ;
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 ;
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 ) ;
}
// 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
}
// 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 ;
// 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 ) ) ;
}
// 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 ) ;
}
// 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 ) ;
}
}
return ( o p p o s i t e _ p o i n t ) ;
}
41