/*! 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; }
/*! 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; }