sweep_line_2_impl.h

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

H
2,089
字号
  SL_DEBUG(std::cout<<"Done Handling vertical\n";)}/*! * Handles overlapping vertical curves.  * If the current event point does not contain vertical curves, nothing is * done here. * Fo the current event point, we go through the list of vertical curves  * defined in the same x coordinate (m_verticals). For each curve, we check  * if the event point is in the interior of the vertical curve. If so,  * the event is set to be an intersection point (between the two  * vertical curves).  * While going through the vertical curves, if we reach a curve that the  * event point is above the curve, we remove the curve from the list. *  * Finally, we go thorugh the vertical curves of the event. If the event  * point is the bottom end of a vertical curve, we add the vertical curve  * to the list of vertical curves (m_verticals). */template <class CurveInputIterator,  class SweepLineTraits_2,         class SweepEvent, class CurveWrap>inline void Sweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::handle_vertical_overlap_curves(){  SL_DEBUG(std::cout<<"\nhandle_vertical_overlap_curves... ("                     << m_currentEvent->get_point() << ")";)  if ( !m_currentEvent->does_contain_vertical_curve() ) {    SL_DEBUG(std::cout << "no vertical - exiting\n";)    return;  }  SL_DEBUG(std::cout << "\n";)  SL_DEBUG(PrintVerticals();)  const Point_2 &point = m_currentEvent->get_point();  SubCurveListIter iter = m_verticals.begin();  while ( iter != m_verticals.end() )  {    Subcurve *curve = *iter;       if (m_traits->point_in_x_range(curve->get_curve(), point) &&	m_traits->curve_compare_y_at_x(point, curve->get_curve()) == LARGER)    {      iter = m_verticals.erase(iter);    } else if (!curve->is_end_point(point)) {      EventQueueIter eventIter = m_queue->find(&(curve->get_top_end()));      CGAL_assertion(eventIter!=m_queue->end());      (eventIter->second)->add_vertical_curve_x_point(point, true);      m_currentEvent->mark_internal_intersection_point();      ++iter;    } else {      ++iter;    }  }  VerticalCurveList &vcurves = m_currentEvent->get_vertical_curves();  VerticalCurveListIter vciter = vcurves.begin();  while ( vciter != vcurves.end() )  {    Subcurve *vcurve = *vciter;    if ( vcurve->is_bottom_end(point) ) {      m_verticals.push_back(vcurve);    }    ++vciter;  }}/*! * Perform intersection between the specified curve and all curves in the  * given group of curves. */ template <class CurveInputIterator, class SweepLineTraits_2,         class SweepEvent, class CurveWrap>inline voidSweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::intersect_curve_group(Subcurve *c1, SubCurveList &mylist){  m_tmpOut.clear();  SL_DEBUG(std::cout << "intersecting with " << mylist.size() << " curves\n";)  SubCurveListIter i = mylist.begin();  while ( i != mylist.end())  {    intersect(c1, *i);    ++i;  }}/*! * When a curve is removed from the status line for good, its top and * bottom neighbors become neighbors. This method finds these cases and * looks for the itnersection point, if one exists. * * @param leftCurve a pointer to the curve that is about to be deleted * @return an iterator to the position where the curve will be removed from. */template <class CurveInputIterator, class SweepLineTraits_2,         class SweepEvent, class CurveWrap>inline voidSweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::remove_curve_from_status_line(Subcurve *leftCurve){  SL_DEBUG(std::cout << "remove_curve_from_status_line\n";)  SL_DEBUG(PrintStatusLine();)  SL_DEBUG(leftCurve->Print();)  StatusLineIter sliter;  sliter = leftCurve->get_hint();   m_status_line_insert_hint = sliter; ++m_status_line_insert_hint;  if ( !leftCurve->is_end_point(m_currentEvent->get_point())) {    m_statusLine->erase(sliter);    SL_DEBUG(std::cout << "remove_curve_from_status_line Done\n";)    return;  }  m_currentPos = m_prevPos;  CGAL_assertion(sliter!=m_statusLine->end());  StatusLineIter end = m_statusLine->end(); --end;  if ( sliter != m_statusLine->begin() && sliter != end )   {    SubCurveList mylist;    StatusLineIter prev = sliter; --prev;        // collect all curves that overlap with *prev    StatusLineIter tmp = prev;    mylist.push_back(*prev);    while ( tmp != m_statusLine->begin() )     {      --tmp;      if ( do_curves_overlap(*prev, *tmp))	mylist.push_back(*tmp);      else	break;    }        StatusLineIter next = sliter; ++next;        // intersect *next with the the *prev curve and all overlaps    tmp = next;    intersect_curve_group(*tmp, mylist);    // if there are curves that overlap with the *next curve, intersect    // them with the *prev curve and all overlaps    ++tmp;    while ( tmp != m_statusLine->end() )     {      if ( do_curves_overlap(*next, *tmp))      {	intersect_curve_group(*tmp, mylist);	++tmp;      }      else 	break;    }  }  m_statusLine->erase(sliter);  SL_DEBUG(std::cout << "remove_curve_from_status_line Done\n";)} /*!  * Finds intersection between two curves.  * If the two curves intersect, create a new event (or use the event that  * already exits in the intersection point) and insert the curves to the * event. * @param curve1 a pointer to the first curve * @param curve2 a pointer to the second curve * @return true if the two curves overlap.*/template <class CurveInputIterator, class SweepLineTraits_2,         class SweepEvent, class CurveWrap>inline bool Sweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::intersect(Subcurve *c1, Subcurve *c2){  SL_DEBUG(std::cout << "Looking for intersection between:\n\t";)  SL_DEBUG(c1->Print();)  SL_DEBUG(std::cout << "\t";)  SL_DEBUG(c2->Print();)  SL_DEBUG(std::cout << "\n";)  SL_DEBUG(std::cout << "relative to " << m_currentEvent->get_point() << "\n";)  if ( c1->getId() == c2->getId() ) {    SL_DEBUG(std::cout << "same curve, returning....\n";)    return false;  }  Subcurve *scv1 = c1;  Subcurve *scv2 = c2;  const X_monotone_curve_2 &cv1 = scv1->get_curve();  const X_monotone_curve_2 &cv2 = scv2->get_curve();  bool isOverlap = false;  Object res =    m_traits->nearest_intersection_to_right(cv1, cv2,                                             m_currentEvent->get_point());  if (!res.is_empty())  {    Point_2 xp;    if (!CGAL::assign(xp, res))    {      X_monotone_curve_2 cv;      if (CGAL::assign(cv, res))      {        xp = m_traits->curve_source(cv);        Point_2 xp1 = m_traits->curve_target(cv);        if ( m_traits->compare_x(xp1, xp) == LARGER )          xp = xp1;        SL_DEBUG(std::cout << "overlap detected\n";)          isOverlap = true;      }    }    SL_DEBUG(      std::cout << " a new event is created between:\n\t";      scv1->Print();      std::cout << "\t";      scv2->Print();      std::cout << "\trelative to ("                << m_sweepLinePos << ")\n\t at ("                 << xp << ")" << std::endl;    )    // check to see if an event at this point already exists...    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(c1, m_sweepLinePos);      e->add_curve_to_left(c2, m_sweepLinePos);            e->add_curve_to_right(c1);      e->add_curve_to_right(c2);            PRINT_NEW_EVENT(xp, e);      m_queue->insert(EventQueueValueType(&(e->get_point()), e));      return isOverlap;    }     else     {      SL_DEBUG(std::cout << "event already exists,updating.. (" << xp <<")\n";)      e = eqi->second;          e->add_curve_to_left(c1, m_sweepLinePos);      if ( !scv1->is_end_point(xp))       { 	      e->add_curve_to_right(c1);      }      e->add_curve_to_left(c2, m_sweepLinePos);      if ( !scv2->is_end_point(xp) )       {	      e->add_curve_to_right(c2);      }      SL_DEBUG(e->Print();)    }    return isOverlap;  }   SL_DEBUG(std::cout << "not found 2\n";)  return isOverlap;}template <class CurveInputIterator,  class SweepLineTraits_2,         class SweepEvent, class CurveWrap>inline boolSweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::is_internal_x_point(const Point_2 &p){  EventListIter itt = m_miniq.begin();  while ( itt != m_miniq.end() )  {    if ( m_traits->point_equal(p, (*itt)->get_point()))     {      if ((*itt)->is_internal_intersection_point()) {	return true;      }      (*itt)->mark_internal_intersection_point();                                      // this is to handle cases: |/ .      return false;                  // (test 50/51)             |\ .    }     ++itt;  }  CGAL_assertion(0);  return false;}/*! * Handles the case in which a curve ont he status line passes through * one of the end points of the vertical curve. * * @param vcurve the vertical curve we are dealing with * @param curve a cerve that intersects with the vertical curve * @param topEndEvent the event attached to the top end of the vertical curve * @param tag  * @return returns true if the curve passed through one of the ends of the  *              vertical curve. Returns false otherwise. */template <class CurveInputIterator,  class SweepLineTraits_2,          class SweepEvent, class CurveWrap>inline boolSweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::handle_vertical_curve_x_at_end(Subcurve *vcurve, Subcurve *curve, 			  Event *topEndEvent, SweepLineGetSubCurves tag){  const Point_2 &topEnd = vcurve->get_top_end();  // handle a curve that goes through the top point of the vertical curve  if (m_traits->point_in_x_range(curve->get_curve(), topEnd) &&      m_traits->curve_compare_y_at_x(topEnd, curve->get_curve()) == EQUAL)  {    if ( !curve->is_left_end(topEnd)) {      topEndEvent->add_curve_to_left(curve, m_prevPos);    }    if ( ! curve->is_right_end(topEnd)) {      topEndEvent->add_curve_to_right(curve);    }    return true;  }     // handle a curve that goes through the bottom point of the vertical curve  const Point_2 &currentPoint = m_currentEvent->get_point();  if (m_traits->point_in_x_range((curve)->get_curve(), currentPoint) &&      m_traits->curve_compare_y_at_x(currentPoint, (curve)->get_curve()) ==      EQUAL)  {    if ( !(curve)->is_left_end(currentPoint)) {      m_currentEvent->add_curve_to_left(curve, m_prevPos);    }    if ( ! (curve)->is_right_end(currentPoint)) {      m_currentEvent->add_curve_to_right(curve);    }    return true;  }  return false;}template <class CurveInputIterator,  class SweepLineTraits_2,          class SweepEvent, class CurveWrap>inline boolSweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::do_curves_overlap(Subcurve *c1, Subcurve *c2){  SL_DEBUG(std::cout << "do_curves_overlap " << m_sweepLinePos << "\n" 	             << "\t" << c1->get_curve() << "\n"	             << "\t" << c2->get_curve() << "\n";)  const Point_2 *p = &(c2->get_last_point());  if ( m_traits->compare_x(c1->get_last_point(), 			   c2->get_last_point()) == LARGER )    p = &(c1->get_last_point());  if ((m_traits->curves_compare_y_at_x(c1->get_curve(),				       c2->get_curve(),				       *p) != EQUAL))    return false;  if ( m_traits->curves_overlap(c1->get_curve(),c2->get_curve()) )    return true;  return false;}template <class CurveInputIterator,  class SweepLineTraits_2,         class SweepEvent, class CurveWrap>inline boolSweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::similar_curves(const X_monotone_curve_2 &a, const X_monotone_curve_2 &b){  if ( m_traits->curve_equal(a, b))    return true;  return false;}template <class CurveInputIterator,  class SweepLineTraits_2,          class SweepEvent, class CurveWrap>inline boolSweep_line_2_impl<CurveInputIterator,SweepLineTraits_2,SweepEvent,CurveWrap>::vertical_subcurve_exists(const X_monotone_curve_2 &a){  for (typename std::list<X_monotone_curve_2>::iterator iter =         m_verticalSubCurves.begin() ;       iter != m_verticalSubCurves.end() ; ++iter)  {    if (similar_curves(*iter, a))       return true;  }  return false;}//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////                 point implementation of the methods                    ///////////////////////////////////////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

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