sweep_line_2_impl.h

来自「CGAL is a collaborative effort of severa」· C头文件 代码 · 共 2,089 行 · 第 1/5 页

H
2,089
字号
  void handle_left_curves(OutpoutIterator out, SweepLineGetPoints &tag)  {    SL_DEBUG(std::cout << "Handling left curve" << std::endl;)    SL_DEBUG(m_currentEvent->Print();)    const Point_2 &eventPoint = m_currentEvent->get_point();    if ( !m_currentEvent->has_left_curves())    {      if (m_includeEndPoints || 	  m_currentEvent->is_internal_intersection_point())      {	SL_DEBUG(std::cout << "Reporting point (2): " << eventPoint << "\n";)	  //*out = eventPoint; ++out;    	add_point_to_output(eventPoint, out);	m_found_intersection = true;      }      return;    }    // delete the curve from the status line    EventCurveIter leftCurveIter = m_currentEvent->left_curves_begin();    m_currentPos = m_prevPos;    m_use_hint_for_erase = false;    while ( leftCurveIter != m_currentEvent->left_curves_end() )    {      // before deleting check new neighbors that will become after deletion      remove_curve_from_status_line(*leftCurveIter);      m_use_hint_for_erase = true;      PRINT_ERASE((*leftCurveIter));      m_currentPos = m_prevPos;      Subcurve *leftCurve = *leftCurveIter;       leftCurve->set_last_point(eventPoint);      ++leftCurveIter;    }    if ( m_includeEndPoints || 	 m_currentEvent->is_internal_intersection_point() )    {	      SL_DEBUG(std::cout << "Reporting point (3): " << eventPoint << "\n";)      //*out = eventPoint; ++out;      add_point_to_output(eventPoint, out);      m_found_intersection = true;    }  }  #ifndef NDEBUG  void PrintEventQueue();  void PrintSubCurves();  void PrintStatusLine();  void PrintVerticals();#endifprotected:  /*! a pointer to a traits object */  Traits *m_traits;  /*! an indication to whether the traits should be deleted in the distructor   */  bool m_traitsOwner;  /*! if false, overlapping subcurves are reported only one.     Otherwise, they are reported as many times as they appeard. */  bool m_overlapping;  /*! if true, end points are reported as intersection points */  bool m_includeEndPoints;  /*! this is true when get_intersection_points() is called */  bool m_stop_at_first_int;  /*! used to hold all event, processed or not, so that they can `     all be deleted at the end */  EventPtrContainer m_events;   /*! the queue of events (intersection points) to handle */  EventQueue *m_queue;  /*! The subcurves, as created on the fly */  SubCurveList m_subCurves;  /*! The status line */  StatusLine *m_statusLine;  /*! a struct that holds params associated with the curve compare functor */  CompareParams *m_comp_param;  /*! A reference point that is used for comapring curves. It is used      when inserting/erasing curves from the status line. */  Point_2 m_currentPos;  /*! A reference point that is used for comapring curves */  Point_2 m_prevPos;  /*! The current position (in X) of the sweep line */  Point_2 m_sweepLinePos;  /*! if non x-monotone are specified, this hold the x-monotone     curves created when splitting them into x-monotone curves. */  std::vector<X_monotone_curve_2> m_xcurves;  /*! a pointer to the current event */  Event *m_currentEvent;  /*! a queue that holds all the events that have the same x coordinate as       the status line. */  EventList m_miniq;  /*! a list of vertical curves at the x coordinate of the current event       point.*/  SubCurveList m_verticals;  CurveList m_verticalSubCurves;  /*! when an intersection point is found this is turned to true */  bool m_found_intersection;  /*! An iterator of the  status line that is used as a hint for inserts. */  StatusLineIter m_status_line_insert_hint;  /*! A an indication wether the hint can be used to erase from the status    line */  bool m_use_hint_for_erase;  SubCurveList m_tmpOut;  Point_2 m_lastReportedPoint;  bool is_first_point;  /*! a counter the is used to assign unique ids to the curves. */  int m_curveId;#ifndef NDEBUG  int m_eventId;#endif  bool CurveStartsAtCurve(Subcurve *one, Subcurve *two)  {    SL_DEBUG(std::cout << "CurveStartsAtCurve: \n";)    SL_DEBUG(std::cout << one->get_curve() << "\n" << two->get_curve()                        << "\n";)    if ( m_traits->point_equal(one->get_left_end(),two->get_left_end()))      return false;    if ( !m_traits->point_equal(one->get_left_end(),				m_currentEvent->get_point()) )      return false;    if ( m_traits->curve_compare_y_at_x(one->get_left_end(), 					two->get_curve()) == EQUAL )      return true;    return false;  }};template <class CurveInputIterator,  class SweepLineTraits_2,         class SweepEvent, class CurveWrap>Sweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::~Sweep_line_2_impl() {  if ( m_traitsOwner ) delete m_traits;  for ( SubCurveListIter sci = m_subCurves.begin() ; 	sci != m_subCurves.end() ; ++sci)  {    delete *sci;  }  for ( EventPtrContainerIter ei = m_events.begin();	ei != m_events.end() ; ++ei)  {    delete *ei;  }  delete m_queue;  delete m_statusLine;  delete m_comp_param;}/*! initializes the data structures to work with: *  - x-monotonize the inf\put curves *  - for each end point of each curve create an event *  - initialize the event queue *  - */template <class CurveInputIterator,  class SweepLineTraits_2,          class SweepEvent, class CurveWrap>inline void Sweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::init(CurveInputIterator begin, CurveInputIterator end){  PointLess pred(m_traits);  m_queue = new EventQueue(pred);  m_comp_param = new CompareParams(m_traits);  StatusLineCurveLess slcurveless(m_comp_param);  m_statusLine = new StatusLine(slcurveless);  m_status_line_insert_hint = m_statusLine->begin();#ifndef NDEBUG  m_eventId = 0;#endif  m_curveId = 0;  int count = 0;  CurveInputIterator iter;  for ( iter = begin ; iter != end ; ++iter)  {    std::list<X_monotone_curve_2> xcurves;    m_traits->curve_make_x_monotone(*iter, std::back_inserter(xcurves));    SL_DEBUG(             std::cout << "curve " << *iter << " was split into "              << xcurves.size() << " curves." << std::endl;             )    for (typename std::list<X_monotone_curve_2>::iterator i = xcurves.begin();         i != xcurves.end() ; ++i )    {      m_xcurves.push_back(*i);      init_curve(m_xcurves[count]);      count++;    }  }}/*! Given an x-monotone curve, create events for each end (if  *  one doesn't exist already).  *  For each curve create a Subcurve instance. */template <class CurveInputIterator,  class SweepLineTraits_2,         class SweepEvent, class CurveWrap>inline void Sweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::init_curve(X_monotone_curve_2 &curve){  const Point_2 &source = m_traits->curve_source(curve);  const Point_2 &target = m_traits->curve_target(curve);  Event *e = 0;    Subcurve *subCv = new Subcurve(m_curveId++, curve, &m_currentPos, m_traits);  m_subCurves.push_back(subCv);    // handle the source point  EventQueueIter eventIter = m_queue->find(&source);   if ( eventIter != m_queue->end() )  // check if the event already in the event queue  {    SL_DEBUG(std::cout << "event " << source << " already exists\n";)    e = eventIter->second;  }  else  // the event is not in the event-queue  {    e = new Event(source, m_traits); #ifndef NDEBUG    e->id = m_eventId++;#endif    m_events.push_back(e);    m_queue->insert(EventQueueValueType(&(e->get_point()), e));  }  e->add_curve(subCv);  PRINT_NEW_EVENT(source, e);      // handle the target point  eventIter = m_queue->find(&target);  if ( eventIter != m_queue->end() )  {    SL_DEBUG(std::cout << "event " << target << " already exists\n";)    e = eventIter->second;  }  else   {    e = new Event(target, m_traits); #ifndef NDEBUG    e->id = m_eventId++;#endif    m_events.push_back(e);    m_queue->insert(EventQueueValueType(&(e->get_point()), e));  }  e->add_curve(subCv);  PRINT_NEW_EVENT(target, e);}/*! * Handles the degenerate case of vertical curves. Most of the cases * that occur with vertical curves are handled by this method and  * handle_vertical_curve_top method. * When the current event is the bottom end of a vertical curve, we look * for intersection points between the vertical curve and any curve * in the status line that in the y-range that is defined by the bottom  * and top ends of the vertical curve. When those are found, we create * new events, unless ones already exist, in which case we update the events. *  * @param tag a tag that indicates the version of this method * \sa handle_vertical_curve_top */template <class CurveInputIterator,  class SweepLineTraits_2,         class SweepEvent, class CurveWrap>inline void Sweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::handle_vertical_curve_bottom(SweepLineGetSubCurves &tag){  SL_DEBUG(std::cout<<"\nhandle_vertical_curve_bottom... ("                    << m_currentEvent->get_point() << ")\n";)  if ( !m_currentEvent->does_contain_vertical_curve() )  {    SL_DEBUG(std::cout<<" - not vertical - exiting\n ";)    return;  }  SL_DEBUG(std::cout<<"\n ";)  VerticalCurveList &vcurves = m_currentEvent->get_vertical_curves();  VerticalCurveListIter vciter = vcurves.begin();  const Point_2 &currentPoint = m_currentEvent->get_point();  SL_DEBUG(std::cout << vcurves.size() << " vertical curves in event\n";)  while ( vciter != vcurves.end() )  {    Subcurve *vcurve = *vciter;    SL_DEBUG(std::cout << "working on " << vcurve->get_curve() << "\n";)    if ( vcurve->is_top_end(currentPoint))    {      vciter++;      continue;    }        SL_DEBUG(std::cout<<"handling bottom point of vertical curve\n";)    StatusLineIter slIter = m_statusLine->lower_bound(vcurve);    if ( slIter == m_statusLine->end() ) {      SL_DEBUG(std::cout<<"no curves intersecting. exiting\n";)      vciter++;      continue;    }            SL_DEBUG(std::cout<<"starting at curve \n";)    SL_DEBUG((*slIter)->Print();)    const Point_2 &topEnd = vcurve->get_top_end();    EventQueueIter topEndEventIter = m_queue->find(&topEnd);    CGAL_assertion(topEndEventIter!=m_queue->end());    Event *topEndEvent = topEndEventIter->second;    bool lastEventCreatedHere = false;    Event *prevEvent = 0;    while (slIter != m_statusLine->end() &&	   (! m_traits->point_in_x_range((*slIter)->get_curve(), 					    topEnd) ||	    m_traits->curve_compare_y_at_x(	           topEnd, (*slIter)->get_curve()) != SMALLER) &&	   (! m_traits->point_in_x_range((*slIter)->get_curve(), 					 currentPoint) ||	    m_traits->curve_compare_y_at_x(currentPoint,                                           (*slIter)->get_curve()) != LARGER))    {      SL_DEBUG(std::cout<<"intersecting with \n";)      SL_DEBUG((*slIter)->Print();) 	      if ( handle_vertical_curve_x_at_end(vcurve, *slIter, topEndEvent, tag)) {	++slIter;	continue;      }            // handle a curve that goes through the interior of the vertical curve      const X_monotone_curve_2 &cv1 = vcurve->get_curve();      const X_monotone_curve_2 &cv2 = (*slIter)->get_curve();      Object res = m_traits->nearest_intersection_to_right(cv1, cv2,                                                           currentPoint);      CGAL_assertion(!res.is_empty());      Point_2 xp;      if (!CGAL::assign(xp, res))        CGAL_assertion(0);            EventQueueIter eqi = m_queue->find(&xp);      Event *e = 0;      if ( eqi == m_queue->end() )      {	e = new Event(xp, m_traits); #ifndef NDEBUG	e->id = m_eventId++;#endif	m_events.push_back(e);		e->add_curve_to_left(*slIter, m_sweepLinePos);	e->add_curve_to_right(*slIter);	PRINT_NEW_EVENT(xp, e);	m_queue->insert(EventQueueValueType(&(e->get_point()), e));	lastEventCreatedHere = true;      } else {	e = eqi->second;		// the only time we need to update the event is when the event	// is created here (which also includes overlapping curves)	if ( e == prevEvent ) {	  if ( lastEventCreatedHere )	  {	    if ( !(*slIter)->is_left_end(xp) ) 	      e->add_curve_to_left(*slIter, m_sweepLinePos);	    if ( !(*slIter)->is_right_end(xp) ) 	      e->add_curve_to_right(*slIter);	  } 	}	else	  lastEventCreatedHere = false;	SL_DEBUG(std::cout << "Updating event \n";)	SL_DEBUG(e->Print();)      }            topEndEvent->add_vertical_curve_x_point(xp);      ++slIter;      prevEvent = e;    }        vciter++;  }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?