mirror of https://github.com/CGAL/cgal
removing files
This commit is contained in:
parent
7a58b5bdda
commit
41a7ba11d1
|
|
@ -1,630 +0,0 @@
|
||||||
// Copyright (c) 2005 Tel-Aviv University (Israel).
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
|
||||||
// the terms of the Q Public License version 1.0.
|
|
||||||
// See the file LICENSE.QPL distributed with CGAL.
|
|
||||||
//
|
|
||||||
// Licensees holding a valid commercial license may use this file in
|
|
||||||
// accordance with the commercial license agreement provided with the software.
|
|
||||||
//
|
|
||||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il>
|
|
||||||
|
|
||||||
#ifndef CGAL_ENVELOPE_ARRANGEMENT_ZONE_2_H
|
|
||||||
#define CGAL_ENVELOPE_ARRANGEMENT_ZONE_2_H
|
|
||||||
|
|
||||||
/*! \file
|
|
||||||
* Defintion of the Envelope_arrangement_zone_2 class.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <CGAL/Arrangement_zone_2.h>
|
|
||||||
#include <CGAL/Arr_observer.h>
|
|
||||||
#include <list>
|
|
||||||
#include <map>
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
CGAL_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
/*! \class
|
|
||||||
* A class for computing the zone of a given $x$-monotone curve in a given
|
|
||||||
* arrangement.
|
|
||||||
* The arrangement parameter corresponds to the underlying arrangement, and
|
|
||||||
* the zone-visitor parameter corresponds to a visitor class which is capable
|
|
||||||
* of receiving notifications on the arrangment features the query curve
|
|
||||||
* traverses. The visitor has to support the following functions:
|
|
||||||
* - init(), for initializing the visitor with a given arrangement.
|
|
||||||
* - found_subcurve(), called when a non-intersecting x-monotone curve is
|
|
||||||
* computed and located in the arrangement.
|
|
||||||
* - found_overlap(), called when an x-monotone curve overlaps an existing
|
|
||||||
* halfedge in the arrangement.
|
|
||||||
* Both the second and the third functions return pair<Halfedge_handle, bool>,
|
|
||||||
* where the halfedge handle corresponds to the halfedge created or modified
|
|
||||||
* by the visitor (if valid), and the Boolean value indicates whether we
|
|
||||||
* should halt the zone-computation process.
|
|
||||||
*
|
|
||||||
* This class improves the complexity of the zone algorithm of
|
|
||||||
* Arrangement_zone_2 for the cases where we enter a face many times
|
|
||||||
*/
|
|
||||||
template <class Arrangement_, class ZoneVisitor_>
|
|
||||||
class Envelope_arrangement_zone_2 :
|
|
||||||
public Arrangement_zone_2< Arrangement_, ZoneVisitor_ >,
|
|
||||||
public Arr_observer< Arrangement_ >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef Arrangement_ Arrangement_2;
|
|
||||||
typedef typename Arrangement_2::Traits_2 Traits_2;
|
|
||||||
|
|
||||||
typedef ZoneVisitor_ Visitor;
|
|
||||||
|
|
||||||
typedef typename Arrangement_2::Vertex_handle Vertex_handle;
|
|
||||||
typedef typename Arrangement_2::Halfedge_handle Halfedge_handle;
|
|
||||||
typedef typename Arrangement_2::Face_handle Face_handle;
|
|
||||||
|
|
||||||
typedef std::pair<Halfedge_handle, bool> Visitor_result;
|
|
||||||
|
|
||||||
typedef typename Traits_2::Point_2 Point_2;
|
|
||||||
typedef typename Traits_2::X_monotone_curve_2 X_monotone_curve_2;
|
|
||||||
|
|
||||||
typedef Arrangement_zone_2< Arrangement_2, Visitor >
|
|
||||||
Base_zone_2;
|
|
||||||
typedef Arr_observer< Arrangement_2 > Base_observer;
|
|
||||||
protected:
|
|
||||||
|
|
||||||
typedef typename Arrangement_2::Ccb_halfedge_circulator
|
|
||||||
Ccb_halfedge_circulator;
|
|
||||||
typedef Arr_traits_adaptor_2<Traits_2> Traits_adaptor_2;
|
|
||||||
|
|
||||||
// Types used for caching intersection points:
|
|
||||||
typedef std::pair<Point_2, unsigned int> Intersect_point_2;
|
|
||||||
typedef std::list<CGAL::Object> Intersect_list;
|
|
||||||
typedef std::map<const X_monotone_curve_2*,
|
|
||||||
Intersect_list> Intersect_map;
|
|
||||||
typedef typename Intersect_map::iterator Intersect_map_iterator;
|
|
||||||
|
|
||||||
typedef std::set<const X_monotone_curve_2*> Curves_set;
|
|
||||||
typedef typename Curves_set::iterator Curves_set_iterator;
|
|
||||||
|
|
||||||
// Data member:
|
|
||||||
|
|
||||||
// Set of faces that we dealt with already
|
|
||||||
Unique_hash_map<Face_handle, bool> discovered_faces;
|
|
||||||
|
|
||||||
// map halfedges that were split to the right part of it
|
|
||||||
// (which is the only part that might be encountered later again.
|
|
||||||
class Less_halfedge
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool operator()(Halfedge_handle h1, Halfedge_handle h2)
|
|
||||||
{
|
|
||||||
return (&*h1 < &*h2);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::map<Halfedge_handle, Halfedge_handle,Less_halfedge> Halfedges_map;
|
|
||||||
typedef typename Halfedges_map::iterator Halfedges_map_iter;
|
|
||||||
Halfedges_map split_map;
|
|
||||||
|
|
||||||
// Set of features (halfedges and vertices) that intersect cv
|
|
||||||
// (the current portion of the query curve), ordered according to the
|
|
||||||
// intersection order on cv from left to right
|
|
||||||
|
|
||||||
class Less_inter_vertex
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Less_inter_vertex(Traits_adaptor_2* t) : traits(t)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool operator() (const Vertex_handle& v1,
|
|
||||||
const Vertex_handle& v2) const
|
|
||||||
{
|
|
||||||
return (traits->compare_xy_2_object()(v1->point(), v2->point())
|
|
||||||
== SMALLER);
|
|
||||||
}
|
|
||||||
protected:
|
|
||||||
Traits_adaptor_2 *traits;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Less_inter_edge
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Less_inter_edge(Traits_adaptor_2 *t, Intersect_map& imap) :
|
|
||||||
traits(t), zone_inter_map(imap)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool operator() (const Halfedge_handle& h1,
|
|
||||||
const Halfedge_handle& h2) const
|
|
||||||
{
|
|
||||||
// find the leftmost intersection with each curve
|
|
||||||
// (the curves must be in the inter_map)
|
|
||||||
const Intersect_point_2 *ip;
|
|
||||||
const X_monotone_curve_2 *icv;
|
|
||||||
Point_2 ip1, ip2;
|
|
||||||
bool no_inter1, no_inter2;
|
|
||||||
|
|
||||||
Intersect_map_iterator iter = zone_inter_map.find (&(h1->curve()));
|
|
||||||
CGAL_assertion(iter != zone_inter_map.end());
|
|
||||||
if (iter != zone_inter_map.end())
|
|
||||||
{
|
|
||||||
// Retrieve the intersections list from the map.
|
|
||||||
Intersect_list& inter_list = iter->second;
|
|
||||||
|
|
||||||
if (inter_list.empty())
|
|
||||||
no_inter1 = true;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
no_inter1 = false;
|
|
||||||
// Locate the first intersection
|
|
||||||
// Compare that current object with left_pt.
|
|
||||||
ip = object_cast<Intersect_point_2> (&(inter_list.front()));
|
|
||||||
|
|
||||||
if (ip != NULL)
|
|
||||||
ip1 = ip->first;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
icv = object_cast<X_monotone_curve_2> (&(inter_list.front()));
|
|
||||||
CGAL_assertion (icv != NULL);
|
|
||||||
|
|
||||||
ip1 = traits->construct_min_vertex_2_object()(*icv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iter = zone_inter_map.find (&(h2->curve()));
|
|
||||||
CGAL_assertion(iter != zone_inter_map.end());
|
|
||||||
if (iter != zone_inter_map.end())
|
|
||||||
{
|
|
||||||
// Retrieve the intersections list from the map.
|
|
||||||
Intersect_list& inter_list = iter->second;
|
|
||||||
|
|
||||||
if (inter_list.empty())
|
|
||||||
no_inter2 = true;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
no_inter2 = false;
|
|
||||||
// Locate the first intersection
|
|
||||||
// Compare that current object with left_pt.
|
|
||||||
ip = object_cast<Intersect_point_2> (&(inter_list.front()));
|
|
||||||
|
|
||||||
if (ip != NULL)
|
|
||||||
ip2 = ip->first;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
icv = object_cast<X_monotone_curve_2> (&(inter_list.front()));
|
|
||||||
CGAL_assertion (icv != NULL);
|
|
||||||
|
|
||||||
ip2 = traits->construct_min_vertex_2_object()(*icv);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if (no_inter1 && no_inter2)
|
|
||||||
// return (h1 < h2);
|
|
||||||
// else if (no_inter1)
|
|
||||||
// return false;
|
|
||||||
// else if (no_inter2)
|
|
||||||
// return true;
|
|
||||||
// else
|
|
||||||
CGAL_assertion(!no_inter1 && !no_inter2);
|
|
||||||
return (traits->compare_xy_2_object()(ip1, ip2) == SMALLER);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Traits_adaptor_2 *traits;
|
|
||||||
Intersect_map &zone_inter_map;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef std::set<Halfedge_handle, Less_inter_edge> Halfedge_sorted_set;
|
|
||||||
typedef typename Halfedge_sorted_set::iterator He_sorted_set_iter;
|
|
||||||
Halfedge_sorted_set intersect_he_sorted_set;
|
|
||||||
|
|
||||||
typedef std::set<Vertex_handle, Less_inter_vertex> Vertices_sorted_set;
|
|
||||||
typedef typename Vertices_sorted_set::iterator V_sorted_set_iter;
|
|
||||||
Vertices_sorted_set intersect_v_sorted_set;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Constructor. typename Arrangement_2::Ccb_halfedge_circulator
|
|
||||||
* \param _arr The arrangement for which we compute the zone.
|
|
||||||
* \param _visitor A pointer to a zone-visitor object.
|
|
||||||
*/
|
|
||||||
Envelope_arrangement_zone_2 (Arrangement_2& _arr,
|
|
||||||
Visitor *_visitor) :
|
|
||||||
Base_zone_2(_arr, _visitor),
|
|
||||||
Base_observer(_arr),
|
|
||||||
intersect_he_sorted_set(Less_inter_edge(traits, inter_map)),
|
|
||||||
intersect_v_sorted_set(Less_inter_vertex(traits))
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual ~Envelope_arrangement_zone_2(){}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Compute the zone of the given curve and issue the apporpriate
|
|
||||||
* notifications for the visitor.
|
|
||||||
*/
|
|
||||||
virtual void compute_zone ()
|
|
||||||
{
|
|
||||||
Base_zone_2::compute_zone();
|
|
||||||
intersect_v_sorted_set.clear();
|
|
||||||
intersect_he_sorted_set.clear();
|
|
||||||
discovered_faces.clear();
|
|
||||||
split_map.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Notification after an edge was split.
|
|
||||||
* \param e1 A handle to one of the twin halfedges forming the first edge.
|
|
||||||
* \param e2 A handle to one of the twin halfedges forming the second edge.
|
|
||||||
*/
|
|
||||||
virtual void after_split_edge (Halfedge_handle e1,
|
|
||||||
Halfedge_handle e2)
|
|
||||||
{
|
|
||||||
// we assume that e1 is the original edge that was split
|
|
||||||
// update split_map with the pair e1 and the rightmost
|
|
||||||
// halfedge part
|
|
||||||
if (e1->direction() == LARGER)
|
|
||||||
{
|
|
||||||
split_map[e1] = e2;
|
|
||||||
split_map[e1->twin()] = e2;
|
|
||||||
}
|
|
||||||
// in the other case, don't need the map
|
|
||||||
}
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Notification after a face was split.
|
|
||||||
* \param f A handle to the face we have just split.
|
|
||||||
* \param new_f A handle to the new face that has been created.
|
|
||||||
* \param is_hole Whether the new face forms a hole inside f.
|
|
||||||
*/
|
|
||||||
virtual void after_split_face (Face_handle f,
|
|
||||||
Face_handle new_f,
|
|
||||||
bool is_hole)
|
|
||||||
{
|
|
||||||
// update the set of discovered faces
|
|
||||||
if (discovered_faces.is_defined(f))
|
|
||||||
discovered_faces[new_f] = discovered_faces.default_value();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Compute the (lexicographically) leftmost intersection of the query
|
|
||||||
* curve with the boundary of a given face in the arrangement.
|
|
||||||
* The function computes sets intersect_p, intersect_he (or alternatively
|
|
||||||
* overlap_cv and intersect_he) and set the flags found_intersect and
|
|
||||||
* found_overlap accordingly.
|
|
||||||
* \param face A handle to the face.
|
|
||||||
* \param on_boundary Specifies whether the left endpoint of the curve lies
|
|
||||||
* on the face boundary.
|
|
||||||
*/
|
|
||||||
virtual void _leftmost_intersection_with_face_boundary (Face_handle face,
|
|
||||||
bool on_boundary)
|
|
||||||
{
|
|
||||||
found_intersect = false;
|
|
||||||
found_overlap = false;
|
|
||||||
found_iso_vert = false;
|
|
||||||
|
|
||||||
// Go over the outer boundary of the face (if one exists), and try to
|
|
||||||
// locate intersections of cv with the edges along the boundary.
|
|
||||||
typename Traits_adaptor_2::Compare_xy_2 compare_xy =
|
|
||||||
traits->compare_xy_2_object();
|
|
||||||
typename Traits_adaptor_2::Is_in_x_range_2 is_in_x_range =
|
|
||||||
traits->is_in_x_range_2_object();
|
|
||||||
typename Traits_adaptor_2::Construct_min_vertex_2 min_vertex =
|
|
||||||
traits->construct_min_vertex_2_object();
|
|
||||||
typename Traits_adaptor_2::Construct_max_vertex_2 max_vertex =
|
|
||||||
traits->construct_max_vertex_2_object();
|
|
||||||
typename Traits_adaptor_2::Compare_y_at_x_2 compare_y_at_x =
|
|
||||||
traits->compare_y_at_x_2_object();
|
|
||||||
|
|
||||||
//Base_zone_2::_leftmost_intersection_with_face_boundary(face, on_boundary);
|
|
||||||
if (!discovered_faces.is_defined(face))
|
|
||||||
{
|
|
||||||
// find all intersections with face boundary, and insert into the
|
|
||||||
// intersection sets
|
|
||||||
Ccb_halfedge_circulator he_first;
|
|
||||||
if (! face->is_unbounded())
|
|
||||||
{
|
|
||||||
// Get circulators for the outer boundary of the face.
|
|
||||||
he_first = face->outer_ccb();
|
|
||||||
_intersect_with_ccb(he_first, on_boundary);
|
|
||||||
}
|
|
||||||
|
|
||||||
typename Arrangement_2::Hole_iterator holes_it;
|
|
||||||
for (holes_it = face->holes_begin();
|
|
||||||
holes_it != face->holes_end(); ++holes_it)
|
|
||||||
{
|
|
||||||
// Get circulators for the boundary of the current hole.
|
|
||||||
he_first = *holes_it;
|
|
||||||
_intersect_with_ccb(he_first, on_boundary);
|
|
||||||
}
|
|
||||||
|
|
||||||
typename Arrangement_2::Isolated_vertex_iterator iso_verts_it;
|
|
||||||
for (iso_verts_it = face->isolated_vertices_begin();
|
|
||||||
iso_verts_it != face->isolated_vertices_end(); ++iso_verts_it)
|
|
||||||
{
|
|
||||||
// If the isolated vertex is not in the x-range of our curve, disregard it.
|
|
||||||
if (! is_in_x_range (cv, iso_verts_it->point()))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// In case the isolated vertex lies on the curve, add it to the
|
|
||||||
// intersection vertex set
|
|
||||||
if (compare_y_at_x (iso_verts_it->point(), cv) == EQUAL)
|
|
||||||
{
|
|
||||||
intersect_v_sorted_set.insert(iso_verts_it);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // End:: traversal of the isolated vertices inside the face.
|
|
||||||
|
|
||||||
// mark that we discovered the current face
|
|
||||||
discovered_faces[face] = discovered_faces.default_value();
|
|
||||||
}
|
|
||||||
// find the leftmost intersection (it should relate to the current face)
|
|
||||||
|
|
||||||
// should find the halfedge with the leftmost intersection
|
|
||||||
// and the isolated point with the leftmost intersection
|
|
||||||
// and compare them
|
|
||||||
bool he_exist, v_exist;
|
|
||||||
// the leftmost intersections
|
|
||||||
Point_2 vp, hep;
|
|
||||||
V_sorted_set_iter v_iter;
|
|
||||||
He_sorted_set_iter he_iter;
|
|
||||||
bool he_inter_is_point;
|
|
||||||
Halfedge_handle inter_he;
|
|
||||||
|
|
||||||
if (intersect_v_sorted_set.empty())
|
|
||||||
v_exist = false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
v_exist = true;
|
|
||||||
v_iter = intersect_v_sorted_set.begin();
|
|
||||||
vp = (*v_iter)->point();
|
|
||||||
}
|
|
||||||
|
|
||||||
CGAL::Object obj;
|
|
||||||
const Intersect_point_2 *int_p;
|
|
||||||
const X_monotone_curve_2 *icv;
|
|
||||||
Point_2 ip;
|
|
||||||
|
|
||||||
if (intersect_he_sorted_set.empty())
|
|
||||||
he_exist = false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
he_iter = intersect_he_sorted_set.begin();
|
|
||||||
// now find the next intersection with this halfedge
|
|
||||||
// todo: is the false ok?
|
|
||||||
Halfedges_map_iter split_iter = split_map.find(inter_he);
|
|
||||||
if (split_iter == split_map.end())
|
|
||||||
inter_he = *he_iter;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Halfedge_handle old = inter_he;
|
|
||||||
inter_he = split_iter->second;
|
|
||||||
split_map.erase(old);
|
|
||||||
}
|
|
||||||
|
|
||||||
obj = _compute_next_intersection (inter_he, false);
|
|
||||||
if (obj.is_empty())
|
|
||||||
intersect_he_sorted_set.erase(he_iter);
|
|
||||||
|
|
||||||
}
|
|
||||||
while(obj.is_empty() && !intersect_he_sorted_set.empty());
|
|
||||||
|
|
||||||
if (intersect_he_sorted_set.empty())
|
|
||||||
he_exist = false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
he_exist = true;
|
|
||||||
CGAL_assertion (! obj.is_empty());
|
|
||||||
|
|
||||||
// We have found an intersection (either a simple point or an
|
|
||||||
// overlapping x-monotone curve).
|
|
||||||
int_p = object_cast<Intersect_point_2> (&obj);
|
|
||||||
if (int_p != NULL)
|
|
||||||
{
|
|
||||||
hep = int_p->first;
|
|
||||||
he_inter_is_point = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We have located an overlapping curve. Assign ip as its left
|
|
||||||
// endpoint.
|
|
||||||
icv = object_cast<X_monotone_curve_2> (&obj);
|
|
||||||
CGAL_assertion (icv != NULL);
|
|
||||||
|
|
||||||
hep = min_vertex (*icv);
|
|
||||||
he_inter_is_point = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!v_exist && !he_exist)
|
|
||||||
return; // no intersection at all
|
|
||||||
|
|
||||||
if (v_exist && he_exist)
|
|
||||||
{
|
|
||||||
// compare the intersections of the vertex and the halfedge
|
|
||||||
// and return the leftmost between them
|
|
||||||
Comparison_result res = compare_xy(hep, vp);
|
|
||||||
CGAL_assertion(res != EQUAL); // imposible intersection between halfedge
|
|
||||||
// and isolated vertex
|
|
||||||
|
|
||||||
// change v_exist/he_exist in order for the below conditiona to work
|
|
||||||
if (res == SMALLER)
|
|
||||||
// halfedge wins
|
|
||||||
v_exist = false;
|
|
||||||
else
|
|
||||||
he_exist = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (v_exist && !he_exist)
|
|
||||||
{
|
|
||||||
// return the intersection with isolated vertex
|
|
||||||
intersect_v = *v_iter;
|
|
||||||
intersect_p = intersect_v->point();
|
|
||||||
ip_mult = 0;
|
|
||||||
found_intersect = true;
|
|
||||||
found_iso_vert = true;
|
|
||||||
|
|
||||||
// remove the vertex from the sorted set
|
|
||||||
intersect_v_sorted_set.erase(v_iter);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!v_exist && he_exist)
|
|
||||||
{
|
|
||||||
// return the intersection with a halfedge
|
|
||||||
if (he_inter_is_point)
|
|
||||||
{
|
|
||||||
intersect_p = hep;
|
|
||||||
ip_mult = int_p->second;
|
|
||||||
intersect_he = inter_he;
|
|
||||||
found_intersect = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// begin of overlapping curve
|
|
||||||
intersect_p = hep;
|
|
||||||
ip_mult = 0;
|
|
||||||
overlap_cv = *icv;
|
|
||||||
intersect_he = inter_he;
|
|
||||||
found_overlap = true;
|
|
||||||
found_intersect = true;
|
|
||||||
}
|
|
||||||
// remove the halfedge from the sorted intersection set
|
|
||||||
intersect_he_sorted_set.erase(he_iter);
|
|
||||||
// remove the found intersection from the list, and if the list is not
|
|
||||||
// empty, reenter the halfedge into the sorted set
|
|
||||||
_remove_next_intersection(intersect_he);
|
|
||||||
Intersect_map_iterator iter = inter_map.find(&(intersect_he->curve()));
|
|
||||||
Intersect_list& inter_list = iter->second;
|
|
||||||
if (!inter_list.empty())
|
|
||||||
intersect_he_sorted_set.insert(intersect_he);
|
|
||||||
|
|
||||||
// todo: should remove all halfedges that intersect in the same point from the set
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void _intersect_with_ccb(Ccb_halfedge_circulator he_first, bool on_boundary)
|
|
||||||
{
|
|
||||||
typename Traits_adaptor_2::Compare_xy_2 compare_xy =
|
|
||||||
traits->compare_xy_2_object();
|
|
||||||
typename Traits_adaptor_2::Is_in_x_range_2 is_in_x_range =
|
|
||||||
traits->is_in_x_range_2_object();
|
|
||||||
typename Traits_adaptor_2::Construct_min_vertex_2 min_vertex =
|
|
||||||
traits->construct_min_vertex_2_object();
|
|
||||||
typename Traits_adaptor_2::Construct_max_vertex_2 max_vertex =
|
|
||||||
traits->construct_max_vertex_2_object();
|
|
||||||
typename Traits_adaptor_2::Compare_y_at_x_2 compare_y_at_x =
|
|
||||||
traits->compare_y_at_x_2_object();
|
|
||||||
|
|
||||||
CGAL::Object obj;
|
|
||||||
Point_2 ip;
|
|
||||||
bool left_equals_curr_endpoint;
|
|
||||||
|
|
||||||
Ccb_halfedge_circulator he_curr = he_first;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
// If we have already found an intersection with the twin halfedge,
|
|
||||||
// we do not have to compute intersections with the current halfedge.
|
|
||||||
// This happens if we already discovered the twin's face
|
|
||||||
// todo: this doesn't work for antennas!
|
|
||||||
if (discovered_faces.is_defined(he_curr->twin()->face()) ||
|
|
||||||
inter_map.find(&(he_curr->curve())) != inter_map.end())
|
|
||||||
{
|
|
||||||
++he_curr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
left_equals_curr_endpoint = false;
|
|
||||||
if (on_boundary)
|
|
||||||
{
|
|
||||||
// Check if the left endpoint of the inserted curve (which is located
|
|
||||||
// on the boundary of our face) equals one of the endpoints of the
|
|
||||||
// current halfedge. If it equals the right endpoint of the current
|
|
||||||
// halfedge, we can skip this edge, as there is no true overlap in
|
|
||||||
// the x-range. Otherwise, we keep track of the fact that left_v is
|
|
||||||
// the left end-vertex of the current halfedge.
|
|
||||||
if (he_curr->target() == left_v)
|
|
||||||
{
|
|
||||||
left_equals_curr_endpoint = true;
|
|
||||||
|
|
||||||
if (he_curr->direction() == SMALLER)
|
|
||||||
{
|
|
||||||
++he_curr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (he_curr->source() == left_v)
|
|
||||||
{
|
|
||||||
left_equals_curr_endpoint = true;
|
|
||||||
|
|
||||||
if (he_curr->direction() == LARGER)
|
|
||||||
{
|
|
||||||
++he_curr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check whether the two curves overlap in their x-range (in order
|
|
||||||
// to avoid unnecessary intersection computations).
|
|
||||||
if (! left_equals_curr_endpoint &&
|
|
||||||
(compare_xy (max_vertex (he_curr->curve()), left_pt) != LARGER ||
|
|
||||||
! is_in_x_range (cv, he_curr->curve())))
|
|
||||||
{
|
|
||||||
// In case there is no overlap, the two x-monotone curves obviously
|
|
||||||
// do not intersect.
|
|
||||||
++he_curr;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The intersection of the halfedge with the curve have not been
|
|
||||||
// computed yet, so we have to compute them now.
|
|
||||||
// Note that the first curve we intersect is
|
|
||||||
// always the subcurve associated with the given halfegde and the second
|
|
||||||
// curve is the one we insert. Even though the order seems unimportant, we
|
|
||||||
// exploit this fact in some of the traits classes in order to optimize
|
|
||||||
// computations.
|
|
||||||
Intersect_list inter_list;
|
|
||||||
|
|
||||||
traits->intersect_2_object() (he_curr->curve(), cv,
|
|
||||||
std::back_inserter(inter_list));
|
|
||||||
|
|
||||||
// if there is intersection with the halfedge endpoint, we remove it
|
|
||||||
if (! inter_list.empty() && left_equals_curr_endpoint)
|
|
||||||
inter_list.pop_front();
|
|
||||||
|
|
||||||
// Insert the list of valid intersections into the map.
|
|
||||||
inter_map[&(he_curr->curve())] = inter_list;
|
|
||||||
|
|
||||||
if (! inter_list.empty())
|
|
||||||
{
|
|
||||||
// insert the intersection to the sorted est
|
|
||||||
intersect_he_sorted_set.insert(he_curr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move to the next edge along the ccb
|
|
||||||
++he_curr;
|
|
||||||
} while (he_curr != he_first);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
CGAL_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,60 +0,0 @@
|
||||||
// Copyright (c) 2005 Tel-Aviv University (Israel).
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
|
||||||
// the terms of the Q Public License version 1.0.
|
|
||||||
// See the file LICENSE.QPL distributed with CGAL.
|
|
||||||
//
|
|
||||||
// Licensees holding a valid commercial license may use this file in
|
|
||||||
// accordance with the commercial license agreement provided with the software.
|
|
||||||
//
|
|
||||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il>
|
|
||||||
|
|
||||||
#ifndef CGAL_NO_VERTICAL_DECOMPOSITION_2_H
|
|
||||||
#define CGAL_NO_VERTICAL_DECOMPOSITION_2_H
|
|
||||||
|
|
||||||
CGAL_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
// No_vertical_decomposition is a class with the interface needed for
|
|
||||||
// vertical decomposition, which doesn't do a decomposition at all
|
|
||||||
template <class ArrangementWithOverlayData>
|
|
||||||
class No_vertical_decomposition_2
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef ArrangementWithOverlayData Pmwx;
|
|
||||||
typedef typename Pmwx::Halfedge_iterator Halfedge_iterator;
|
|
||||||
typedef typename Pmwx::Halfedge_handle Halfedge_handle;
|
|
||||||
typedef typename Pmwx::Face_handle Face_handle;
|
|
||||||
typedef typename Pmwx::Face_iterator Face_iterator;
|
|
||||||
typedef typename Pmwx::Ccb_halfedge_circulator Ccb_halfedge_circulator;
|
|
||||||
typedef typename Pmwx::Hole_iterator Hole_iterator;
|
|
||||||
typedef typename Pmwx::Face_const_iterator Face_const_iterator;
|
|
||||||
typedef typename Pmwx::Vertex_iterator Vertex_iterator;
|
|
||||||
typedef typename Pmwx::Vertex_handle Vertex_handle;
|
|
||||||
|
|
||||||
typedef typename Pmwx::Traits_2 Traits;
|
|
||||||
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
|
|
||||||
typedef typename Traits::Curve_2 Curve_2;
|
|
||||||
typedef typename Traits::Point_2 Point_2;
|
|
||||||
|
|
||||||
typedef typename Pmwx::Dcel Pm_dcel;
|
|
||||||
typedef typename Pm_dcel::Face_data Pm_face_data;
|
|
||||||
|
|
||||||
void operator()(Pmwx& pm)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CGAL_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif // OVERLAY_2_H
|
|
||||||
|
|
@ -1,174 +0,0 @@
|
||||||
// Copyright (c) 2005 Tel-Aviv University (Israel).
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
|
||||||
// the terms of the Q Public License version 1.0.
|
|
||||||
// See the file LICENSE.QPL distributed with CGAL.
|
|
||||||
//
|
|
||||||
// Licensees holding a valid commercial license may use this file in
|
|
||||||
// accordance with the commercial license agreement provided with the software.
|
|
||||||
//
|
|
||||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il>
|
|
||||||
|
|
||||||
#ifndef CGAL_PARTIAL_VD_META_TRAITS_H
|
|
||||||
#define CGAL_PARTIAL_VD_META_TRAITS_H
|
|
||||||
|
|
||||||
|
|
||||||
CGAL_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
template <class Traits, class Arrangement_>
|
|
||||||
class Partial_vd_meta_traits : public Traits
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef Arrangement_ Arrangement;
|
|
||||||
typedef typename Arrangement::Halfedge_const_handle Halfedge_const_handle;
|
|
||||||
typedef typename Arrangement::Vertex_const_handle Vertex_const_handle;
|
|
||||||
|
|
||||||
typedef typename Traits::X_monotone_curve_2 Base_X_monotone_curve_2;
|
|
||||||
typedef typename Traits::Point_2 Base_Point_2;
|
|
||||||
typedef typename Traits::Construct_min_vertex_2 Base_construct_min_vertex_2;
|
|
||||||
typedef typename Traits::Construct_max_vertex_2 Base_construct_max_vertex_2;
|
|
||||||
|
|
||||||
// nested class My_X_monotone_curve_2
|
|
||||||
class My_X_monotone_curve_2 : public Base_X_monotone_curve_2
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef Base_X_monotone_curve_2 Base;
|
|
||||||
|
|
||||||
friend class Partial_vd_meta_traits<Traits,
|
|
||||||
Halfedge_const_handle>;
|
|
||||||
|
|
||||||
My_X_monotone_curve_2():Base(),
|
|
||||||
m_he_handle(NULL)
|
|
||||||
{}
|
|
||||||
|
|
||||||
My_X_monotone_curve_2(const Base& cv):Base(cv),
|
|
||||||
m_he_handle(NULL)
|
|
||||||
{}
|
|
||||||
|
|
||||||
My_X_monotone_curve_2(const Base&cv, Halfedge_const_handle he):Base(cv),
|
|
||||||
m_he_handle(he)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
Halfedge_const_handle get_halfedge_handle() const
|
|
||||||
{
|
|
||||||
return m_he_handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Halfedge_const_handle m_he_handle;
|
|
||||||
}; // nested class My_X_monotone_curve_2 - END
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class My_Point_2 : public Base_Point_2
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef Base_Point_2 Base;
|
|
||||||
|
|
||||||
friend class Partial_vd_meta_traits<Traits,
|
|
||||||
Halfedge_const_handle>;
|
|
||||||
|
|
||||||
My_Point_2(): Base(),
|
|
||||||
m_v(NULL)
|
|
||||||
{}
|
|
||||||
|
|
||||||
My_Point_2(const Base& pt): Base(pt),
|
|
||||||
m_v(NULL)
|
|
||||||
{}
|
|
||||||
|
|
||||||
My_Point_2(const Base& pt, Vertex_const_handle v): Base(pt), m_v(v)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
Vertex_const_handle get_vertex_handle() const
|
|
||||||
{
|
|
||||||
return m_v;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Vertex_const_handle m_v;
|
|
||||||
}; // nested class My_Point_2 - END
|
|
||||||
|
|
||||||
typedef My_X_monotone_curve_2 X_monotone_curve_2;
|
|
||||||
typedef My_Point_2 Point_2;
|
|
||||||
|
|
||||||
class Construct_min_vertex_2
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Base_construct_min_vertex_2 m_base_cons_min;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/*! Constructor. */
|
|
||||||
Construct_min_vertex_2 (const Base_construct_min_vertex_2& base) :
|
|
||||||
m_base_cons_min (base)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Point_2 operator() (const X_monotone_curve_2 & cv) const
|
|
||||||
{
|
|
||||||
const Base_Point_2& pt = m_base_cons_min(cv);
|
|
||||||
CGAL_assertion_code(Traits traits);
|
|
||||||
CGAL_assertion(traits.equal_2_object()(pt, cv.get_halfedge_handle()->source()->point()));
|
|
||||||
// the halfedge in cv should be directed from left to right
|
|
||||||
Point_2 p(pt, cv.get_halfedge_handle()->source());
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! Get a Construct_min_vertex_2 functor object. */
|
|
||||||
Construct_min_vertex_2 construct_min_vertex_2_object() const
|
|
||||||
{
|
|
||||||
return Construct_min_vertex_2(Traits::construct_min_vertex_2_object());
|
|
||||||
}
|
|
||||||
|
|
||||||
class Construct_max_vertex_2
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
Base_construct_max_vertex_2 m_base_cons_max;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/*! Constructor. */
|
|
||||||
Construct_max_vertex_2 (const Base_construct_max_vertex_2& base) :
|
|
||||||
m_base_cons_max (base)
|
|
||||||
{}
|
|
||||||
|
|
||||||
Point_2 operator() (const X_monotone_curve_2 & cv) const
|
|
||||||
{
|
|
||||||
const Base_Point_2& pt = m_base_cons_max(cv);
|
|
||||||
CGAL_assertion_code(Traits traits);
|
|
||||||
CGAL_assertion(traits.equal_2_object()(pt, cv.get_halfedge_handle()->target()->point()));
|
|
||||||
// the halfedge in cv should be directed from left to right
|
|
||||||
Point_2 p(pt, cv.get_halfedge_handle()->target());
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*! Get a Construct_max_vertex_2 functor object. */
|
|
||||||
Construct_max_vertex_2 construct_max_vertex_2_object () const
|
|
||||||
{
|
|
||||||
return Construct_max_vertex_2(Traits::construct_max_vertex_2_object());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
CGAL_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,320 +0,0 @@
|
||||||
// Copyright (c) 2005 Tel-Aviv University (Israel).
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
|
||||||
// the terms of the Q Public License version 1.0.
|
|
||||||
// See the file LICENSE.QPL distributed with CGAL.
|
|
||||||
//
|
|
||||||
// Licensees holding a valid commercial license may use this file in
|
|
||||||
// accordance with the commercial license agreement provided with the software.
|
|
||||||
//
|
|
||||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il>
|
|
||||||
|
|
||||||
#ifndef CGAL_PARTIAL_VD_VISITOR_H
|
|
||||||
#define CGAL_PARTIAL_VD_VISITOR_H
|
|
||||||
|
|
||||||
#include <CGAL/Sweep_line_2_empty_visitor.h>
|
|
||||||
#include <CGAL/Object.h>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
CGAL_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
template< class Traits_, class Arrangement_, class OutputIterator>
|
|
||||||
class Partial_vd_visitor : public Empty_visitor< Traits_ >
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef Partial_vd_visitor<Traits_,
|
|
||||||
Arrangement_,
|
|
||||||
OutputIterator> Self;
|
|
||||||
typedef Arrangement_ Arrangement;
|
|
||||||
typedef Traits_ Traits;
|
|
||||||
|
|
||||||
|
|
||||||
typedef Empty_visitor<Traits> Base;
|
|
||||||
typedef typename Base::Event Event;
|
|
||||||
typedef typename Base::Subcurve Subcurve;
|
|
||||||
typedef typename Base::SL_iterator SL_iterator;
|
|
||||||
typedef typename Base::SubCurveIter SubCurveIter;
|
|
||||||
typedef typename Base::SubCurveRevIter SubCurveRevIter;
|
|
||||||
|
|
||||||
|
|
||||||
typedef typename Traits::X_monotone_curve_2 X_monotone_curve_2;
|
|
||||||
typedef typename Traits::Point_2 Point_2;
|
|
||||||
typedef typename Traits::Base_Point_2 Base_Point_2;
|
|
||||||
typedef typename Arrangement::Halfedge_const_handle Halfedge_const_handle;
|
|
||||||
typedef typename Arrangement::Vertex_const_handle Vertex_const_handle;
|
|
||||||
typedef std::pair<Object, Object> Vd_Pair;
|
|
||||||
|
|
||||||
Partial_vd_visitor(const Arrangement& arr, OutputIterator o) :
|
|
||||||
m_arr(arr), m_out(o), m_last_event(NULL), m_last_above(NULL),
|
|
||||||
m_is_last_pair(false), m_last_should_shoot_down(false),
|
|
||||||
m_last_should_shoot_up(false)
|
|
||||||
{}
|
|
||||||
|
|
||||||
//after_handle_event
|
|
||||||
//(above_on_event is true iff 'above' subcurve is on the event
|
|
||||||
bool after_handle_event(Event* event, SL_iterator above, bool above_on_event)
|
|
||||||
{
|
|
||||||
// we should never have above_on_event = true since we sweep an existing
|
|
||||||
// arrangement
|
|
||||||
CGAL_assertion(!above_on_event);
|
|
||||||
|
|
||||||
Vertex_const_handle vh = event->get_point().get_vertex_handle();
|
|
||||||
CGAL_assertion(vh != Vertex_const_handle(NULL));
|
|
||||||
CGAL_assertion(m_arr.get_traits()->equal_2_object()(event->get_point(),
|
|
||||||
vh->point()));
|
|
||||||
|
|
||||||
// these booleans are needed for "LESANEN" vertical edges in a partial
|
|
||||||
// vertical decomposition
|
|
||||||
bool event_should_shoot_down = should_shoot_down(event);
|
|
||||||
bool event_should_shoot_up = should_shoot_up(event);
|
|
||||||
|
|
||||||
// this bool is used for solving 2 problems:
|
|
||||||
// 1. the redundant problem, where 2 vertices see each other, and we might
|
|
||||||
// discover this pair twice
|
|
||||||
// 2. a problem where when shooting down what we see is not exactly right
|
|
||||||
// below the current event, since there were events in the middle that
|
|
||||||
// were removed from the status line (with same x coordinate)
|
|
||||||
bool previous_event_see_current = false;
|
|
||||||
// if last event is set, we should check if we interrupt its above sight
|
|
||||||
if (m_is_last_pair)
|
|
||||||
{
|
|
||||||
CGAL_assertion(m_last_event != NULL);
|
|
||||||
// special cases can happen if we stay in the same x-coordinate sweepline
|
|
||||||
if(m_arr.get_traits()->compare_x_2_object()
|
|
||||||
(m_last_event->get_point(), event->get_point())
|
|
||||||
== EQUAL &&
|
|
||||||
((above == this->status_line_end() && m_last_above == NULL) ||
|
|
||||||
(above != this->status_line_end() && m_last_above == *above) ||
|
|
||||||
(event == m_last_above->get_right_event()) // last above ends in the current event
|
|
||||||
))
|
|
||||||
{
|
|
||||||
// should change the previous pair - is sees the current event point
|
|
||||||
// instead of the previous above curve
|
|
||||||
Vertex_const_handle pvh = m_last_event->get_point().get_vertex_handle();
|
|
||||||
if (event_should_shoot_down || m_last_should_shoot_up)
|
|
||||||
*m_out++ = std::make_pair(CGAL::make_object(pvh),
|
|
||||||
CGAL::make_object(vh));
|
|
||||||
|
|
||||||
previous_event_see_current = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// keep the previous pair, if existed
|
|
||||||
if (m_last_above != NULL)
|
|
||||||
{
|
|
||||||
Halfedge_const_handle phe = m_last_above->get_last_curve().get_halfedge_handle();
|
|
||||||
Vertex_const_handle pvh = m_last_event->get_point().get_vertex_handle();
|
|
||||||
CGAL_assertion(m_arr.get_traits()->equal_2_object()(m_last_event->get_point(),
|
|
||||||
pvh->point()));
|
|
||||||
if (m_last_should_shoot_up)
|
|
||||||
*m_out++ = std::make_pair(CGAL::make_object(pvh),
|
|
||||||
CGAL::make_object(phe));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// todo: check if we should shoot from this point
|
|
||||||
|
|
||||||
// if the event is an end of a vertical segment, we don't shoot down
|
|
||||||
bool vertical_end = false;
|
|
||||||
SubCurveIter lci = event->left_curves_begin();
|
|
||||||
for(; lci != event->left_curves_end(); ++lci)
|
|
||||||
{
|
|
||||||
if (m_arr.get_traits()->is_vertical_2_object()((*lci)->get_last_curve()))
|
|
||||||
{
|
|
||||||
vertical_end = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if (!vertical_end)
|
|
||||||
{
|
|
||||||
// shoot down
|
|
||||||
// if previous event sees the current event, then we don't have to shoot
|
|
||||||
// down, since this pair was already discovered
|
|
||||||
if (!previous_event_see_current)
|
|
||||||
{
|
|
||||||
// find who is right below the event point in the sweep line
|
|
||||||
int num_of_right_curves = event->get_num_right_curves();
|
|
||||||
SL_iterator below = above;
|
|
||||||
int i;
|
|
||||||
for(i=0; i<=num_of_right_curves && below != this->status_line_begin();
|
|
||||||
++i, --below);
|
|
||||||
|
|
||||||
if (i == (num_of_right_curves+1))
|
|
||||||
{
|
|
||||||
// we see something below us
|
|
||||||
// is it not an isolated point, since these were already removed from
|
|
||||||
// the status line
|
|
||||||
// it is also not an endpoint, since in this case, we would have
|
|
||||||
// previous_event_see_current = true
|
|
||||||
CGAL_assertion(m_arr.get_traits()->equal_2_object()(event->get_point(),
|
|
||||||
vh->point()));
|
|
||||||
|
|
||||||
// assert it is not an endpoint
|
|
||||||
CGAL_assertion_code(
|
|
||||||
Event* left_event = (*below)->get_left_event();
|
|
||||||
);
|
|
||||||
CGAL_assertion(m_arr.get_traits()->compare_x_2_object()
|
|
||||||
(left_event->get_point(), event->get_point()) != EQUAL);
|
|
||||||
|
|
||||||
Halfedge_const_handle he = (*below)->get_last_curve().get_halfedge_handle();
|
|
||||||
if (event_should_shoot_down)
|
|
||||||
*m_out++ = std::make_pair(CGAL::make_object(vh), CGAL::make_object(he));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the event is a start of a vertical segment, we don't shoot up
|
|
||||||
bool vertical_start = false;
|
|
||||||
lci = event->right_curves_begin();
|
|
||||||
for(; lci != event->right_curves_end(); ++lci)
|
|
||||||
{
|
|
||||||
if (m_arr.get_traits()->is_vertical_2_object()((*lci)->get_last_curve()))
|
|
||||||
{
|
|
||||||
vertical_start = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
m_last_event = event;
|
|
||||||
m_last_above = NULL;
|
|
||||||
m_last_should_shoot_down = event_should_shoot_down;
|
|
||||||
m_last_should_shoot_up = event_should_shoot_up;
|
|
||||||
|
|
||||||
m_is_last_pair = false;
|
|
||||||
if (!vertical_start)
|
|
||||||
{
|
|
||||||
m_is_last_pair = true;
|
|
||||||
// shoot up
|
|
||||||
if (above != this->status_line_end())
|
|
||||||
{
|
|
||||||
m_last_above = *above;
|
|
||||||
// we see something above us, and keep it to be dealt with in the next event
|
|
||||||
CGAL_assertion(m_arr.get_traits()->equal_2_object()(event->get_point(),
|
|
||||||
vh->point()));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_events.push_back(event);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void after_sweep()
|
|
||||||
{
|
|
||||||
typename std::list<Event*>::iterator it = m_events.begin();
|
|
||||||
for(;it != m_events.end(); ++it)
|
|
||||||
this->deallocate_event(*it);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// check if should shoot down/up from the evnet's point
|
|
||||||
// in partial vertical decomposition, we should check if the angle
|
|
||||||
// formed by the edges which we insert the vertical segment between
|
|
||||||
// is less than 180
|
|
||||||
bool should_shoot_down(Event* event)
|
|
||||||
{
|
|
||||||
// if no curve ends in this event we always get angel > 180 in the
|
|
||||||
// down direction
|
|
||||||
if (!event->has_left_curves())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// we have at least one curve that ends in this event, we take the lowest
|
|
||||||
// one
|
|
||||||
// if we have a vertical curve downwards, then it should be it (and we
|
|
||||||
// don't shoot down)
|
|
||||||
// (we can use get_last_curve() since we work on existing arrangement
|
|
||||||
// and don't split the curves)
|
|
||||||
SubCurveIter lci = event->left_curves_begin();
|
|
||||||
if (m_arr.get_traits()->is_vertical_2_object()((*lci)->get_last_curve()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// if we don't have any curves that begin in this event, the angel is
|
|
||||||
// always > 180 in the down direction
|
|
||||||
if (!event->has_right_curves())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// get the lowest right curve
|
|
||||||
SubCurveIter rci = event->right_curves_begin();
|
|
||||||
|
|
||||||
// TODO: be careful - this check is only true for segments -
|
|
||||||
// we should check the angle between curves and not between points
|
|
||||||
// should define it more carefully within the traits
|
|
||||||
|
|
||||||
Point_2 left = (*lci)->get_last_curve().source();
|
|
||||||
Point_2 right = (*rci)->get_last_curve().target();
|
|
||||||
// if (left, event->point(), right) is a left turn can shoot down
|
|
||||||
// return m_arr.get_traits()->leftturn_2_object()(left, event->get_point(), right);
|
|
||||||
return CGAL::left_turn(left, event->get_point(), right);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool should_shoot_up(Event* event)
|
|
||||||
{
|
|
||||||
// if no curve starts in this event we always get angel > 180 in the
|
|
||||||
// up direction
|
|
||||||
if (!event->has_right_curves())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// we have at least one curve that starts in this event, we take the
|
|
||||||
// highest one
|
|
||||||
// if we have a vertical curve upwards, then it should be it (and we
|
|
||||||
// don't shoot up)
|
|
||||||
// (we can use get_last_curve() since we work on existing arrangement
|
|
||||||
// and don't split the curves)
|
|
||||||
SubCurveRevIter rci = event->right_curves_rbegin();
|
|
||||||
if (m_arr.get_traits()->is_vertical_2_object()((*rci)->get_last_curve()))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// if we don't have any curves that end in this event, the angel is
|
|
||||||
// always > 180 in the up direction
|
|
||||||
if (!event->has_left_curves())
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// get the highest left curve
|
|
||||||
SubCurveRevIter lci = event->left_curves_rbegin();
|
|
||||||
|
|
||||||
// TODO: be careful - this check is only true for segments -
|
|
||||||
// we should check the angle between curves and not between points
|
|
||||||
// should define it more carefully within the traits
|
|
||||||
|
|
||||||
Point_2 left = (*lci)->get_last_curve().source();
|
|
||||||
Point_2 right = (*rci)->get_last_curve().target();
|
|
||||||
// if (left, event->point(), right) is a right turn can shoot up
|
|
||||||
// return m_arr.get_traits()->right_turn_2_object()(left, event->get_point(), right);
|
|
||||||
return CGAL::right_turn(left, event->get_point(), right);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const Arrangement& m_arr;
|
|
||||||
OutputIterator m_out;
|
|
||||||
|
|
||||||
// the last event that was completely handled
|
|
||||||
Event* m_last_event;
|
|
||||||
// the subcurve that was above the last event in the status line of that event
|
|
||||||
Subcurve* m_last_above;
|
|
||||||
// indicate if in the last event, when we shoot up, we might have a
|
|
||||||
// vertical pair
|
|
||||||
bool m_is_last_pair;
|
|
||||||
// last values of should_shoot_down/up
|
|
||||||
bool m_last_should_shoot_down, m_last_should_shoot_up;
|
|
||||||
|
|
||||||
// save all events here, and deallocate them in the end
|
|
||||||
std::list<Event*> m_events;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
CGAL_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,249 +0,0 @@
|
||||||
// Copyright (c) 2005 Tel-Aviv University (Israel).
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
|
||||||
// the terms of the Q Public License version 1.0.
|
|
||||||
// See the file LICENSE.QPL distributed with CGAL.
|
|
||||||
//
|
|
||||||
// Licensees holding a valid commercial license may use this file in
|
|
||||||
// accordance with the commercial license agreement provided with the software.
|
|
||||||
//
|
|
||||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il>
|
|
||||||
|
|
||||||
#ifndef CGAL_PARTIAL_VERTICAL_DECOMPOSITION_2_H
|
|
||||||
#define CGAL_PARTIAL_VERTICAL_DECOMPOSITION_2_H
|
|
||||||
|
|
||||||
#include <CGAL/Basic_sweep_line_2.h>
|
|
||||||
#include <CGAL/Sweep_line_2/Sweep_line_subcurve.h>
|
|
||||||
#include <CGAL/Sweep_line_2/Sweep_line_event.h>
|
|
||||||
#include <CGAL/Envelope_3/Partial_vd_visitor.h>
|
|
||||||
#include <CGAL/Envelope_3/Partial_vd_meta_traits.h>
|
|
||||||
#include <CGAL/Unique_hash_map.h>
|
|
||||||
#include <vector>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
CGAL_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
// To use this partial vertical decomposition, the arrangement's traits
|
|
||||||
// should supply 2 additional methods:
|
|
||||||
// 1. construct_vertical_2 - to construct a vertical X_monotone_curve_2
|
|
||||||
// from 2 points with same x coordinate
|
|
||||||
// 2. vertical_ray_shoot_2 - to get a point on a X_monotone_curve_2 with
|
|
||||||
// a given x coordinate (assuming it is in the curve's x-range)
|
|
||||||
|
|
||||||
|
|
||||||
template <class Arrangement_>
|
|
||||||
class Partial_vertical_decomposition_2
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
typedef Arrangement_ Arrangement;
|
|
||||||
// Arrangement types:
|
|
||||||
typedef typename Arrangement::Traits_2 Traits_2;
|
|
||||||
typedef typename Traits_2::X_monotone_curve_2 Base_X_monotone_curve_2;
|
|
||||||
typedef typename Traits_2::Point_2 Base_Point_2;
|
|
||||||
|
|
||||||
typedef typename Arrangement::Halfedge_const_handle Halfedge_const_handle;
|
|
||||||
typedef typename Arrangement::Vertex_const_handle Vertex_const_handle;
|
|
||||||
typedef typename Arrangement::Vertex_const_iterator Vertex_const_iterator;
|
|
||||||
typedef typename Arrangement::Edge_const_iterator Edge_const_iterator;
|
|
||||||
typedef typename Arrangement::Halfedge_const_iterator Halfedge_const_iterator;
|
|
||||||
typedef typename Arrangement::Halfedge_handle Halfedge_handle;
|
|
||||||
typedef typename Arrangement::Vertex_handle Vertex_handle;
|
|
||||||
typedef typename Arrangement::Size Size;
|
|
||||||
|
|
||||||
|
|
||||||
// Define meta-traits class for the batched point location:
|
|
||||||
typedef Partial_vd_meta_traits<Traits_2, Arrangement>
|
|
||||||
Meta_traits_2;
|
|
||||||
|
|
||||||
typedef typename Meta_traits_2::X_monotone_curve_2 X_monotone_curve_2;
|
|
||||||
typedef typename Meta_traits_2::Point_2 Point_2;
|
|
||||||
|
|
||||||
typedef std::pair<Object, Object> Vd_pair;
|
|
||||||
typedef std::list<Vd_pair> Vd_pairs_container;
|
|
||||||
typedef std::list<Vd_pair>::iterator Vd_pairs_iter;
|
|
||||||
typedef std::back_insert_iterator<Vd_pairs_container> Vd_pairs_oiter;
|
|
||||||
// Define the sweep-line visitor:
|
|
||||||
typedef Partial_vd_visitor<Meta_traits_2,
|
|
||||||
Arrangement,
|
|
||||||
Vd_pairs_oiter> Visitor;
|
|
||||||
|
|
||||||
typedef Basic_sweep_line_2<Meta_traits_2, Visitor> Sweep_line;
|
|
||||||
|
|
||||||
typedef Unique_hash_map<Halfedge_handle, Halfedge_handle> Halfedges_map;
|
|
||||||
|
|
||||||
// Do a partial vertical decomposition on existing arrangement "arr"
|
|
||||||
void operator()(Arrangement& arr)
|
|
||||||
{
|
|
||||||
// Go over all arrangement edges.
|
|
||||||
std::vector<X_monotone_curve_2> xcurves_vec;
|
|
||||||
xcurves_vec.resize(arr.number_of_edges());
|
|
||||||
typename Traits_2::Compare_xy_2 comp_xy =
|
|
||||||
arr.get_traits()->compare_xy_2_object();
|
|
||||||
Edge_const_iterator eit;
|
|
||||||
|
|
||||||
Size i = 0;
|
|
||||||
for (eit = arr.edges_begin(); eit != arr.edges_end(); ++eit, ++i)
|
|
||||||
{
|
|
||||||
// Associate each x-monotone curve with the halfedge that represent it
|
|
||||||
// that is directed from left to right.
|
|
||||||
if(comp_xy(eit->source()->point(),
|
|
||||||
eit->target()->point()) == SMALLER)
|
|
||||||
xcurves_vec[i] = X_monotone_curve_2(eit->curve(),eit);
|
|
||||||
else
|
|
||||||
xcurves_vec[i] = X_monotone_curve_2(eit->curve(),eit->twin());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Associate each isolated point with the vertex that represents it
|
|
||||||
std::vector<Point_2> iso_points;
|
|
||||||
for(Vertex_const_iterator v_itr = arr.vertices_begin();
|
|
||||||
v_itr != arr.vertices_end();
|
|
||||||
++v_itr)
|
|
||||||
{
|
|
||||||
if(v_itr->is_isolated())
|
|
||||||
iso_points.push_back(Point_2(v_itr->point(), v_itr));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform the sweep
|
|
||||||
Vd_pairs_container vd_pairs;
|
|
||||||
Visitor visitor (arr, std::back_inserter(vd_pairs));
|
|
||||||
Sweep_line sweep_line (&visitor);
|
|
||||||
|
|
||||||
sweep_line.sweep(xcurves_vec.begin(),
|
|
||||||
xcurves_vec.end(),
|
|
||||||
iso_points.begin(),
|
|
||||||
iso_points.end());
|
|
||||||
|
|
||||||
_add_vertical_edges(arr, vd_pairs);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// add the vertical edges (that were determined by the sweep) to the
|
|
||||||
// arrangement
|
|
||||||
void _add_vertical_edges(Arrangement& arr, Vd_pairs_container& vd_pairs)
|
|
||||||
{
|
|
||||||
Vertex_const_handle invalid_v(NULL);
|
|
||||||
Halfedge_const_handle invalid_he(NULL);
|
|
||||||
|
|
||||||
Halfedge_handle prev_split_he(NULL);
|
|
||||||
Base_Point_2 prev_split_pt;
|
|
||||||
Vertex_handle prev_split_v(NULL);
|
|
||||||
|
|
||||||
// map original halfedge in the arrangement to its current rightmost part
|
|
||||||
// which should be split when more than one split of this halfedge is needed
|
|
||||||
Halfedges_map map_orig_to_rightmost;
|
|
||||||
|
|
||||||
Vd_pairs_iter it = vd_pairs.begin();
|
|
||||||
for(; it != vd_pairs.end(); ++it)
|
|
||||||
{
|
|
||||||
Vd_pair cur_pair = *it;
|
|
||||||
Vertex_const_handle v1, v2;
|
|
||||||
Halfedge_const_handle h1, h2;
|
|
||||||
if (!CGAL::assign(v1, cur_pair.first))
|
|
||||||
{
|
|
||||||
CGAL_assertion(CGAL::assign(h1, cur_pair.first));
|
|
||||||
CGAL::assign(h1, cur_pair.first);
|
|
||||||
}
|
|
||||||
if (!CGAL::assign(v2, cur_pair.second))
|
|
||||||
{
|
|
||||||
CGAL_assertion(CGAL::assign(h2, cur_pair.second));
|
|
||||||
CGAL::assign(h2, cur_pair.second);
|
|
||||||
}
|
|
||||||
// we have 2 vertices, no split is needed
|
|
||||||
if (v1 != invalid_v && v2 != invalid_v)
|
|
||||||
{
|
|
||||||
if (should_add_vertical_edge(arr.non_const_handle(v1), arr.non_const_handle(v2)))
|
|
||||||
{
|
|
||||||
arr.insert_at_vertices(
|
|
||||||
arr.get_traits()->construct_vertical_2_object()(v1->point(), v2->point()),
|
|
||||||
arr.non_const_handle(v1),
|
|
||||||
arr.non_const_handle(v2));
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Vertex_handle v;
|
|
||||||
Halfedge_handle orig_split_he, split_he;
|
|
||||||
|
|
||||||
if (v1 != invalid_v)
|
|
||||||
{
|
|
||||||
// we must have h2 valid
|
|
||||||
CGAL_assertion(h2 != invalid_he);
|
|
||||||
v = arr.non_const_handle(v1);
|
|
||||||
orig_split_he = arr.non_const_handle(h2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// we must have v2 and h1 valid
|
|
||||||
CGAL_assertion(v2 != invalid_v);
|
|
||||||
CGAL_assertion(h1 != invalid_he);
|
|
||||||
v = arr.non_const_handle(v2);
|
|
||||||
orig_split_he = arr.non_const_handle(h1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!should_add_vertical_edge(v, orig_split_he))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// split split_he and connect the split point with v
|
|
||||||
if (map_orig_to_rightmost.is_defined(orig_split_he))
|
|
||||||
// we should split the rightmost halfedge instead
|
|
||||||
split_he = map_orig_to_rightmost[orig_split_he];
|
|
||||||
else
|
|
||||||
split_he = orig_split_he;
|
|
||||||
|
|
||||||
Base_Point_2 split_p;
|
|
||||||
Vertex_handle split_v;
|
|
||||||
if (prev_split_he == orig_split_he &&
|
|
||||||
arr.get_traits()->compare_x_2_object()(prev_split_pt, v->point()) == EQUAL)
|
|
||||||
{
|
|
||||||
split_p = prev_split_pt;
|
|
||||||
split_v = prev_split_v;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
split_p = arr.get_traits()->vertical_ray_shoot_2
|
|
||||||
(v->point(), split_he->curve());
|
|
||||||
Base_X_monotone_curve_2 a,b;
|
|
||||||
arr.get_traits()->split_2_object()(split_he->curve(), split_p, a, b);
|
|
||||||
split_he = arr.split_edge(split_he, a, b);
|
|
||||||
// split always returns the halfedge with source = original source
|
|
||||||
// so the current rightmost part is split_he->next()
|
|
||||||
map_orig_to_rightmost[orig_split_he] = split_he->next();
|
|
||||||
split_v = split_he->target();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_split_he = orig_split_he;
|
|
||||||
prev_split_pt = split_p;
|
|
||||||
prev_split_v = split_v;
|
|
||||||
|
|
||||||
// insert the vertical edge
|
|
||||||
arr.insert_at_vertices(
|
|
||||||
arr.get_traits()->construct_vertical_2_object()(v->point(), split_p),
|
|
||||||
v,
|
|
||||||
split_v);
|
|
||||||
}
|
|
||||||
vd_pairs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool should_add_vertical_edge(Vertex_handle v1, Vertex_handle v2)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool should_add_vertical_edge(Vertex_handle v, Halfedge_handle he)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
CGAL_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
@ -1,115 +0,0 @@
|
||||||
// Copyright (c) 2005 Tel-Aviv University (Israel).
|
|
||||||
// All rights reserved.
|
|
||||||
//
|
|
||||||
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
|
||||||
// the terms of the Q Public License version 1.0.
|
|
||||||
// See the file LICENSE.QPL distributed with CGAL.
|
|
||||||
//
|
|
||||||
// Licensees holding a valid commercial license may use this file in
|
|
||||||
// accordance with the commercial license agreement provided with the software.
|
|
||||||
//
|
|
||||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
||||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
//
|
|
||||||
// $URL$
|
|
||||||
// $Id$
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Author(s) : Michal Meyerovitch <gorgymic@post.tau.ac.il>
|
|
||||||
|
|
||||||
#ifndef CGAL_ENVELOPE_NUMBER_OF_SURFACES_H
|
|
||||||
#define CGAL_ENVELOPE_NUMBER_OF_SURFACES_H
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cassert>
|
|
||||||
#include <list>
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
CGAL_BEGIN_NAMESPACE
|
|
||||||
|
|
||||||
// return the number of different xy-monotone surfaces that appear in the
|
|
||||||
// minimization diagram "arr"
|
|
||||||
template <class MinimizationDiagram_2>
|
|
||||||
std::size_t envelope_find_number_of_surfaces(MinimizationDiagram_2& arr)
|
|
||||||
{
|
|
||||||
typedef MinimizationDiagram_2 Minimization_diagram_2;
|
|
||||||
typedef typename Minimization_diagram_2::Traits_2 Traits_2;
|
|
||||||
typedef typename Traits_2::Xy_monotone_surface_3 Xy_monotone_surface_3;
|
|
||||||
|
|
||||||
typedef std::list<Xy_monotone_surface_3> Surfaces_list;
|
|
||||||
|
|
||||||
Surfaces_list slist;
|
|
||||||
envelope_find_unique_surfaces(arr, std::back_inserter(slist));
|
|
||||||
|
|
||||||
return slist.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MinimizationDiagram_2, class OutputIterator>
|
|
||||||
OutputIterator envelope_find_unique_surfaces(MinimizationDiagram_2& arr, OutputIterator o)
|
|
||||||
{
|
|
||||||
typedef MinimizationDiagram_2 Minimization_diagram_2;
|
|
||||||
typedef typename Minimization_diagram_2::Traits_2 Traits_2;
|
|
||||||
typedef typename Traits_2::Xy_monotone_surface_3 Xy_monotone_surface_3;
|
|
||||||
|
|
||||||
typedef typename Minimization_diagram_2::Halfedge_iterator Halfedge_iterator;
|
|
||||||
typedef typename Minimization_diagram_2::Face_iterator Face_iterator;
|
|
||||||
typedef typename Minimization_diagram_2::Vertex_iterator Vertex_iterator;
|
|
||||||
typedef typename Minimization_diagram_2::Dcel::Face_data_iterator Data_iterator;
|
|
||||||
|
|
||||||
typedef std::set<Xy_monotone_surface_3> Surfaces_set;
|
|
||||||
typedef typename std::set<Xy_monotone_surface_3>::iterator Surfaces_set_it;
|
|
||||||
|
|
||||||
Surfaces_set sset;
|
|
||||||
envelope_find_unique_surfaces_set(arr, sset);
|
|
||||||
|
|
||||||
for(Surfaces_set_it it = sset.begin(); it != sset.end(); ++it)
|
|
||||||
{
|
|
||||||
*o = *it;
|
|
||||||
++o;
|
|
||||||
}
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class MinimizationDiagram_2, class Surfaces_set>
|
|
||||||
void envelope_find_unique_surfaces_set(MinimizationDiagram_2& arr, Surfaces_set& sset)
|
|
||||||
{
|
|
||||||
typedef MinimizationDiagram_2 Minimization_diagram_2;
|
|
||||||
typedef typename Minimization_diagram_2::Traits_2 Traits_2;
|
|
||||||
typedef typename Traits_2::Xy_monotone_surface_3 Xy_monotone_surface_3;
|
|
||||||
|
|
||||||
typedef typename Minimization_diagram_2::Halfedge_iterator Halfedge_iterator;
|
|
||||||
typedef typename Minimization_diagram_2::Face_iterator Face_iterator;
|
|
||||||
typedef typename Minimization_diagram_2::Vertex_iterator Vertex_iterator;
|
|
||||||
typedef typename Minimization_diagram_2::Dcel::Face_data_iterator Data_iterator;
|
|
||||||
|
|
||||||
Data_iterator di;
|
|
||||||
// vertices
|
|
||||||
Vertex_iterator vi = arr.vertices_begin();
|
|
||||||
for(; vi != arr.vertices_end(); ++vi)
|
|
||||||
{
|
|
||||||
di = vi->begin_data();
|
|
||||||
for(; di != vi->end_data(); ++di)
|
|
||||||
sset.insert(*di);
|
|
||||||
}
|
|
||||||
// edges
|
|
||||||
Halfedge_iterator hi = arr.halfedges_begin();
|
|
||||||
for(; hi != arr.halfedges_end(); ++hi)
|
|
||||||
{
|
|
||||||
di = hi->begin_data();
|
|
||||||
for(; di != hi->end_data(); ++di)
|
|
||||||
sset.insert(*di);
|
|
||||||
}
|
|
||||||
|
|
||||||
// faces
|
|
||||||
Face_iterator fi = arr.faces_begin();
|
|
||||||
for(; fi != arr.faces_end(); ++fi)
|
|
||||||
{
|
|
||||||
di = fi->begin_data();
|
|
||||||
for(; di != fi->end_data(); ++di)
|
|
||||||
sset.insert(*di);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CGAL_END_NAMESPACE
|
|
||||||
|
|
||||||
#endif
|
|
||||||
Loading…
Reference in New Issue