Esempio n. 1
0
/*! For the oCCW (positive) polygon orientation a positive dOff will 
    inflate the polygon. For the oCW (negative) polygon orientation 
    a positive dOff will shrink the polygon.
 */
void Polygon2D::Offset(
   qreal dOff //!< Offset value.
)
{
   VecVertex vecNew;
   vecNew.reserve(GetCount());

   // Move each point
   for(unsigned int i=0; i<GetCount(); i++) {
      Line2D lnA = GetLine(i==0 ? GetCount()-1 : i-1);
      Line2D lnB = GetLine(i);

      // Offset both lines
      lnA.Offset(-dOff);
      lnB.Offset(-dOff);
      // Intersection gives the new point;
      Point2D ptI;
      unsigned int uStatus = lnA.GetIntersection(lnB, ptI);
      if(uStatus & Line2D::intExist) {
         vecNew.push_back(ptI);
      }
      // lnA and lnB are parallel
      else {
         vecNew.push_back(lnA.GetB());
      }
   }
   Clear();
   m_vecV = vecNew;
}
Esempio n. 2
0
/*! First all intersections are calculated. Then duplicates are removed.
    If only points on the line are required, all points that are outside
    the lnX[A,B] are removed. If bParallel is true, parallel segmets are
    checked for overlap and overlap points are included in the solution.
    
    \retval VecVertex container of intersection points. 
 */
QVector<Point2D> Polygon2D::GetIntersection(
   const Line2D& lnX, //!< line that intersects the polygon
   bool bOnLineOnly,  //!< if true, only points between A and B inclusive are counted.
   bool bParallel     //!< check parallel lines for overlap
) const
{
   // results are stored here
   QVector<Point2D> vecInt;

   // for each segment
   for(unsigned int i=0; i<GetCount(); i++) {
      Line2D ln = GetLine(i);
      Q_ASSERT(ln.IsValid());
      Point2D ptInt;
      // Check overlaps, if they are wanted
      if(bParallel && ln.IsParallel(lnX)) {
         Line2D lnO = ln.GetOverlap(lnX);
         if(lnO.IsValid()) {
            vecInt.push_back(lnO.GetA());
            vecInt.push_back(lnO.GetB());
         }
      }

      // check intersections
      if(ln.GetIntersection(lnX, ptInt) & Line2D::intFirst){
         vecInt.push_back(ptInt);
      }
   }

   // Sort the points in the vector. Same point may appear several
   // times.
   Point2DSortLineLess pred(lnX);
   std::sort(vecInt.begin(),vecInt.end(),pred);
   // remove duplicates, if any
   QVector<Point2D>::iterator f = std::unique(vecInt.begin(),vecInt.end());
   vecInt.erase(f,vecInt.end());

   // remove all points that are not inside the line
   if(bOnLineOnly) {
      QVector<Point2D>::iterator i=vecInt.begin();
      while(i!=vecInt.end()) {
         if(!(lnX.GetPosition(*i) & Line2D::posInsideEnd))
            i = vecInt.erase(i);
         else
            i++;
      }
   }

   return vecInt;
}