// Return the X projections of the edges that overlap y1,y2. void ExclusionPolygon::computeEdgeIntersections(float y1, float y2, Vector<ExclusionInterval>& result) const { Vector<ExclusionPolygon::EdgeInterval> overlappingEdges; m_edgeTree.allOverlaps(ExclusionPolygon::EdgeInterval(y1, y2, 0), overlappingEdges); EdgeIntersection intersection; for (unsigned i = 0; i < overlappingEdges.size(); i++) { const ExclusionPolygonEdge *edge = static_cast<ExclusionPolygonEdge*>(overlappingEdges[i].data()); float x1; float x2; if (edge->minY() < y1) { computeXIntersection(edge, y1, intersection); x1 = intersection.point.x(); } else x1 = (edge->vertex1().y() < edge->vertex2().y()) ? edge->vertex1().x() : edge->vertex2().x(); if (edge->maxY() > y2) { computeXIntersection(edge, y2, intersection); x2 = intersection.point.x(); } else x2 = (edge->vertex1().y() > edge->vertex2().y()) ? edge->vertex1().x() : edge->vertex2().x(); if (x1 > x2) std::swap(x1, x2); if (x2 > x1) result.append(ExclusionInterval(x1, x2)); } sortExclusionIntervals(result); }
static void computeOverlappingEdgeXProjections(const FloatPolygon& polygon, float y1, float y2, Vector<ExclusionInterval>& result) { Vector<const FloatPolygonEdge*> edges; if (!polygon.overlappingEdges(y1, y2, edges)) return; EdgeIntersection intersection; for (unsigned i = 0; i < edges.size(); ++i) { const FloatPolygonEdge *edge = edges[i]; float x1; float x2; if (edge->minY() < y1) { computeXIntersection(edge, y1, intersection); x1 = intersection.point.x(); } else x1 = (edge->vertex1().y() < edge->vertex2().y()) ? edge->vertex1().x() : edge->vertex2().x(); if (edge->maxY() > y2) { computeXIntersection(edge, y2, intersection); x2 = intersection.point.x(); } else x2 = (edge->vertex1().y() > edge->vertex2().y()) ? edge->vertex1().x() : edge->vertex2().x(); if (x1 > x2) std::swap(x1, x2); if (x2 > x1) result.append(ExclusionInterval(x1, x2)); } sortExclusionIntervals(result); }
static inline bool appendIntervalX(float x, bool inside, Vector<ExclusionInterval>& result) { if (!inside) result.append(ExclusionInterval(x)); else result[result.size() - 1].x2 = x; return !inside; }
void subtractExclusionIntervals(const Vector<ExclusionInterval>& v1, const Vector<ExclusionInterval>& v2, Vector<ExclusionInterval>& rv) { size_t v1Size = v1.size(); size_t v2Size = v2.size(); if (!v1Size) return; if (!v2Size) rv.appendRange(v1.begin(), v1.end()); else { size_t i1 = 0, i2 = 0; rv.appendRange(v1.begin(), v1.end()); while (i1 < rv.size() && i2 < v2Size) { ExclusionInterval& interval1 = rv[i1]; const ExclusionInterval& interval2 = v2[i2]; if (interval2.x1 <= interval1.x1 && interval2.x2 >= interval1.x2) rv.remove(i1); else if (interval2.x2 < interval1.x1) i2 += 1; else if (interval2.x1 > interval1.x2) i1 += 1; else if (interval2.x1 > interval1.x1 && interval2.x2 < interval1.x2) { rv.insert(i1, ExclusionInterval(interval1.x1, interval2.x1)); interval1.x1 = interval2.x2; i2 += 1; } else if (interval2.x1 <= interval1.x1) { interval1.x1 = interval2.x2; i2 += 1; } else { // (interval2.x2 >= interval1.x2) interval1.x2 = interval2.x1; i1 += 1; } } } }