Beispiel #1
0
// 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);
}
Beispiel #2
0
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);
}
Beispiel #3
0
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;
}
Beispiel #4
0
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;
            }
        }
    }
}