• No se han encontrado resultados

MATERIAL Y MÉTODO

In document UNIVERSIDAD NACIONAL DE TRUJILLO (página 37-47)

As the Arrangement_with_history_2 class template extends the Arrangement_2 class template, it inherits the fundamental modification operations, such as assign() and clear(), from it. The vertex-manipulation functions are also inherited and supported; see Sections 2.2.2 and 3.4.1 for the details. However, there are some fundamental differences between the interfaces of the two classes, which we highlight next.

The most significant difference between the arrangement-with-history class and the basic ar-rangement class is the way they handle their input curves. Arar-rangement_with_history_2 always stores the Curve_2 objects that induce it. Thus, it is impossible to insert x-monotone curves into an arrangement with history. The free insert_non_intersecting_curve() and the version of insert()that accepts an x-monotone curve, as well as their aggregate versions, are therefore not available for arrangement-with-history instances. Only the free overloaded functions insert() that accept general curves, namely, the incremental insertion function and the aggregate insertion function, are supported; see Section 3.4.1 for a review of these functions. Notice, however, that while the incremental insertion function insert(arr, c) for an Arrangement_2 object arr does not have a return value, the corresponding arrangement-with-history function returns a Curve_

handleobject that points to the inserted curve.

As we are able to keep track of all edges induced by an input curve, we also provide a free function that removes a curve from an arrangement. By calling remove(arr,ch), where ch is a valid curve handle, the given curve is deleted from the curve container, and all edges induced solely by this curve (i.e., excluding overlapping edges) are removed from the arrangement. The function returns the number of edges that have been removed.

In some cases, you may need to operate directly on the arrangement edges. We first mention that the specialized insertion-functions (see Section 2.2.2) are not supported, as they accept x-monotone curves. Insertion can only be performed via the free insertion-functions. The other edge-manipulation functions (see Section 2.2.2) are, however, available, but have a different interface that does not use x-monotone curves.

1. Invoking split_edge(e,p) splits the edge e at a given point p that lies in its interior.

2. Invoking merge_edge(e1,e2) merges the two given edges. There is a precondition that e1

and e2 share a common end vertex of degree2 prior to the merge, and that the x-monotone subcurves associated with these edges are mergeable.

3. It is possible to remove an edge by simply invoking remove_edge(e).

In all cases, the maintenance of cross-pointers for the appropriate input curves is done automati-cally.

q1

q2

q3

s2

s1 s3

Note that it is possible to attach observers to an arrangement-with-history instance in order to get detailed notifications of the changes the arrangement undergoes; see Section6.1for the details.

Example: The example below constructs a simple arrangement of six line segments, as illustrated in the figure to the right, while maintaining the curve history. Note that the input segments s1and s3 overlap over two edges. The example demonstrates the usage of the special traversal functions. It also shows how to issue point-location queries on the resulting arrangement (the query points q1, q2, and q3 are drawn as crosses), using the function locate_

point()listed on Page 44.

// F i l e : ex_curve_history . cpp

#include <CGAL/ b a s i c . h>

#include <CGAL/Arrangement_with_history_2. h>

#include <CGAL/Arr_trapezoid_ric_point_location . h>

#include "arr_exact_construction_segments . h"

#include " point_locatio n_utils . h"

typedef CGAL: : Arrangement_with_history_2<Traits> Arr_with_hist ;

typedef Arr_with_hist : : Curve_handle Curve_handle ;

typedef CGAL: : Arr_trapezoid_ric_point_location<Arr_with_hist> Point_location ; int main ( )

{

// I n s e r t s1 , s2 , and s3 incrementally . Arr_with_hist a r r ;

Curve_handle s1 = i n s e r t ( arr , Segment( Point ( 0 , 3 ) , Point ( 4 , 3 ) ) ) ; Curve_handle s2 = i n s e r t ( arr , Segment( Point ( 3 , 2 ) , Point ( 3 , 5 ) ) ) ; Curve_handle s3 = i n s e r t ( arr , Segment( Point ( 2 , 3 ) , Point ( 5 , 3 ) ) ) ; // I n s e r t t hree a d d i t i o n a l segments a g g r e g a t e l y .

Segment seg s [ ] = {Segment( Point ( 2 , 6 ) , Point ( 7 , 1 ) ) , Segment( Point ( 0 , 0 ) , Point ( 2 , 6 ) ) , Segment( Point ( 3 , 4 ) , Point ( 6 , 4 ) ) } ; i n s e r t ( arr , segs , seg s + sizeof ( seg s )/ sizeof ( Segment ) ) ;

// Print out the curves and the number o f edges each one induces . Arr_with_hist : : Curve_iterator c i t ;

std : : cout << "The␣arrangement␣ co nta ins␣"

<< a r r . number_of_curves ( ) << "␣ curves : " << std : : endl ; for ( c i t = a r r . curves_begin ( ) ; c i t != a r r . curves_end ( ) ; ++c i t )

std : : cout << "Curve␣ [ " << ∗ c i t << " ] ␣induces␣"

<< a r r . number_of_induced_edges ( c i t ) << "␣ edges . " << std : : endl ; // Print the arrangement edges along with the l i s t o f curves t h a t

// induce each edge .

Arr_with_hist : : Edge_iterator e i t ; Arr_with_hist : : Originating_curve_iterator o c i t ; std : : cout << "The␣arrangement␣ i s ␣comprised␣ o f ␣"

<< a r r . number_of_edges( ) << "␣edges : " << std : : endl ; for ( e i t = a r r . edges_begin ( ) ; e i t != a r r . edges_end ( ) ; ++e i t ) {

std : : cout << " [ " << e i t−>curve () << " ] . ␣Originating␣curves : ␣" ; for ( o c i t = a r r . originating_curves_begin( e i t ) ;

o c i t != a r r . originating_curves_end ( e i t ) ; ++o c i t ) std : : cout << "␣ [ " << ∗ ocit << " ] " << std : : flush ; std : : cout << std : : endl ;

}

// Perform some point−location queries . Point_location pl ( a r r ) ;

locate_point ( pl , Point ( 4 , 6 ) ) ; // q1 locate_point ( pl , Point ( 6 , 2 ) ) ; // q2 locate_point ( pl , Point ( 2 , 4 ) ) ; // q3 return 0 ;

}

q

C0

C1

C2

C3

C4

C5

C6

C7

C8

Example: The example below demonstrates the usage of the free remove_curve()function template. We construct an arrangement of nine circles, while keeping a handle to each inserted circle. We then remove the large circle C0, which induces 18 edges, as de-picted in the figure to the right (note the two vertices induced by splitting the circle into two x-monotone arcs). The example also shows how to use the split_edge() and merge_edge() member functions when operating on an arrangement-with-history object.

// F i l e : ex_edge_manipulation_curve_history . cpp

#include <CGAL/ b a s i c . h>

#include <CGAL/Arrangement_with_history_2. h>

#include <CGAL/Arr_walk_along_line_point_location . h>

#include " a r r _ c i r c ul a r . h"

#include " arr_print . h"

typedef CGAL: : Arrangement_with_history_2<Traits> Arr_with_hist ;

typedef Arr_with_hist : : Curve_handle Curve_handle ;

typedef CGAL: : Arr_walk_along_line_point_location<Arr_with_hist>Point_location ; int main ( )

{

// Construct an arrangement containing nine c i r c l e s : C[ 0 ] o f radiu s 2 and // C[ 1 ] , . . . , C[ 8 ] o f radiu s 1 .

const Number_type _7_halves = Number_type (7 ) / Number_type ( 2 ) ;

Curve C[ 9 ] ;

C[ 0 ] = C i r c l e ( Kernel : : Point_2 (_7_halves , _7_halves ) , 4 , CGAL: :CLOCKWISE) ; C[ 1 ] = C i r c l e ( Kernel : : Point_2 (_7_halves , 6 ) , 1 , CGAL: :CLOCKWISE) ;

C[ 2 ] = C i r c l e ( Kernel : : Point_2 ( 5 , 5 ) , 1 , CGAL: :CLOCKWISE) ;

C[ 3 ] = C i r c l e ( Kernel : : Point_2 ( 6 , _7_halves ) , 1 , CGAL: :CLOCKWISE) ; C[ 4 ] = C i r c l e ( Kernel : : Point_2 ( 5 , 2 ) , 1 , CGAL: :CLOCKWISE) ;

C[ 5 ] = C i r c l e ( Kernel : : Point_2 (_7_halves , 1 ) , 1 , CGAL: :CLOCKWISE) ; C[ 6 ] = C i r c l e ( Kernel : : Point_2 ( 2 , 2 ) , 1 , CGAL: :CLOCKWISE) ;

C[ 7 ] = C i r c l e ( Kernel : : Point_2 ( 1 , _7_halves ) , 1 , CGAL: :CLOCKWISE) ; C[ 8 ] = C i r c l e ( Kernel : : Point_2 ( 2 , 5 ) , 1 , CGAL: :CLOCKWISE) ;

Arr_with_hist a r r ;

Curve_handle handles [ 9 ] ;

for ( int k = 0 ; k < 9 ; k++) handles [ k ] = i n s e r t ( arr , C[ k ] ) ; std : : cout << "The␣ i n i t i a l ␣arrangement␣ s i z e : " << std : : endl ; print_arrangement_size ( a r r ) ;

// Remove the l a r g e c i r c l e C[ 0 ] .

std : : cout << "Removing␣C[ 0 ] ␣ : ␣" << remove_curve( arr , handles [ 0 ] )

<< "␣ edges␣have␣been␣removed . " << std : : endl ; print_arrangement_size ( a r r ) ;

// Locate the point q , which should be on an edge e .

Point_location pl ( a r r ) ;

const Point q = Point ( _7_halves , 7 ) ;

CGAL: : Object obj = pl . l o c a t e ( q ) ; Arr_with_hist : : Halfedge_const_handle e ;

bool s u c c e s s = CGAL: : a s s i g n ( e , obj ) ;

CGAL_assertion( s u c c e s s ) ;

// S p l i t the edge i n t o two edges e1 and e2 . Arr_with_hist : : Halfedge_handle e1 =

a r r . split_edge ( a r r . non_const_handle( e ) , q ) ; Arr_with_hist : : Halfedge_handle e2 = e1−>next ( ) ; std : : cout << " After ␣edge␣ s p l i t : ␣" << std : : endl ; print_arrangement_size ( a r r ) ;

a r r . merge_edge( e1 , e2 ) ; // merge back the two s p l i t edges std : : cout << " After ␣edge␣merge : ␣" << std : : endl ;

print_arrangement_size ( a r r ) ; return 0 ;

}

The program uses types defined in the header file arr_circular.h listed on Page 99.

In document UNIVERSIDAD NACIONAL DE TRUJILLO (página 37-47)

Documento similar