BWAPI
|
00001 // Copyright (c) 2005 Tel-Aviv University (Israel). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Arrangement_on_surface_2/include/CGAL/Arr_point_location/Arr_naive_point_location_impl.h $ 00015 // $Id: Arr_naive_point_location_impl.h 35350 2006-11-29 12:31:07Z efif $ 00016 // 00017 // 00018 // Author(s) : Ron Wein <wein@post.tau.ac.il> 00019 // (based on old version by Eyal Flato) 00020 #ifndef CGAL_ARR_NAIVE_POINT_LOCATION_FUNCTIONS_H 00021 #define CGAL_ARR_NAIVE_POINT_LOCATION_FUNCTIONS_H 00022 00028 CGAL_BEGIN_NAMESPACE 00029 00030 //----------------------------------------------------------------------------- 00031 // Locate the arrangement feature containing the given point. 00032 // 00033 template <class Arrangement> 00034 Object Arr_naive_point_location<Arrangement>::locate (const Point_2& p) const 00035 { 00036 // Go over the arrangement vertices and check whether one of them equals 00037 // the query point. 00038 typename Traits_adaptor_2::Equal_2 equal = geom_traits->equal_2_object(); 00039 typename Arrangement_2::Vertex_const_iterator vit; 00040 Vertex_const_handle vh; 00041 00042 for (vit = p_arr->vertices_begin(); vit != p_arr->vertices_end(); ++vit) 00043 { 00044 vh = vit; 00045 if (equal (p, vh->point())) 00046 return (CGAL::make_object (vh)); 00047 } 00048 00049 // Go over arrangement halfedges and check whether one of them contains 00050 // the query point in its interior. 00051 typename Traits_adaptor_2::Is_in_x_range_2 is_in_x_range = 00052 geom_traits->is_in_x_range_2_object(); 00053 typename Traits_adaptor_2::Compare_y_at_x_2 compare_y_at_x = 00054 geom_traits->compare_y_at_x_2_object(); 00055 typename Arrangement_2::Edge_const_iterator eit; 00056 Halfedge_const_handle hh; 00057 00058 for (eit = p_arr->edges_begin(); eit != p_arr->edges_end(); ++eit) 00059 { 00060 hh = eit; 00061 00062 if (is_in_x_range (hh->curve(), p) && 00063 compare_y_at_x (p, hh->curve()) == EQUAL) 00064 { 00065 return (CGAL::make_object (hh)); 00066 } 00067 } 00068 00069 // Go over all faces an locate the innermost one that contains the query 00070 // point in its interior. 00071 typename Arrangement_2::Face_const_iterator fit; 00072 Face_const_handle fh; 00073 Face_const_handle f_inner; 00074 const Face_const_handle invalid_f; 00075 00076 for (fit = p_arr->faces_begin(); fit != p_arr->faces_end(); ++fit) 00077 { 00078 fh = fit; 00079 00080 if (top_traits->is_in_face (&(*fh), p, NULL)) 00081 { 00082 // The current face contains p in its interior. 00083 if (f_inner == invalid_f || 00084 f_inner->is_unbounded() || 00085 f_inner->number_of_outer_ccbs() == 0) 00086 { 00087 // This is the first face that contains p we encounter: 00088 f_inner = fh; 00089 } 00090 else if (! fh->is_unbounded() && fh->number_of_outer_ccbs() > 0) 00091 { 00092 // As we have already some other containing face, one face must be 00093 // contained inside the other. Two check that, we select a 00094 // representative vertex of inner_f and check whether it is contained 00095 // in our current face. 00096 00097 // This is a workaround for MSVC. For some reason the compiler barfs 00098 // when the iterator is not saved in a variable and only then the 00099 // source() of its value_type is accessed. 00100 typename Arrangement_2::Outer_ccb_const_iterator it = 00101 fh->outer_ccbs_begin(); 00102 Vertex_const_handle v = (*it)->source(); 00103 00104 if (top_traits->is_in_face (&(*f_inner), v->point(), NULL)) 00105 f_inner = fh; 00106 } 00107 } 00108 } 00109 00110 // Return the innermost face. 00111 CGAL_assertion (f_inner != invalid_f); 00112 return (CGAL::make_object (f_inner)); 00113 } 00114 00115 CGAL_END_NAMESPACE 00116 00117 #endif