Wagmare
Wagmare

Reputation: 1406

Calculating the fill area of QPainterPath

In a qgraphicsItem using QPainterPath in paint() function i have drawn a free form drawing over the scene.I'd like to ask if there's a way to calculate the area of a closed painter path. I'd like to display the area the painterpath covered in the scene not as the boundingRect.

Upvotes: 2

Views: 3151

Answers (4)

eSKon
eSKon

Reputation: 449

qreal getPathArea(QPainterPath *p, qreal step)
{
    QPointF a,b;
    qreal len;
    qreal area=0;
    for(len=0; len<p->length(); len+=step)
    {
        a=p->pointAtPercent(p->percentAtLength(len));
        b=p->pointAtPercent(p->percentAtLength(len+step>p->length()?p->length():len+step));
        area+=(b.x()-a.x())*(a.y+b.y);
    }
    return area/qreal(2);
}

Upvotes: 1

Ruslan Uss
Ruslan Uss

Reputation: 71

PyQt/PySide method for non-self-intersecting polygons:

def frange(start, stop, step):
    '''Helper float generator'''
    while start < stop:
        yield start
        start += step

def painterPathArea(path, precision = 10000):
    '''QPainterPath area calculation'''
    points = [(point.x(), point.y()) for point in (path.pointAtPercent(perc) for perc in frange (0, 1, 1.0 / precision))]
    points.append(points[0])

    return 0.5 * abs(reduce(
        lambda sum, i: sum + (points[i][0] * points[i + 1][1] - points[i + 1][0] * points[i][1]),
        xrange (len (points) - 1),
        0
    ))

Same without reduce:

def painterPathArea(path, precision = 10000):
    '''QPainterPath area calculation'''
    points = [(point.x(), point.y()) for point in (path.pointAtPercent(perc) for perc in frange (0, 1, 1.0 / precision))]
    points.append(points[0])

    sum = 0
    for i in xrange (len (points) - 1):
        sum += points[i][0] * points[i + 1][1] - points[i + 1][0] * points[i][1]

    return abs(sum) / 2

In fact precision is just the number of vertices of the approximating polygon. The more, the better and slower.

Upvotes: 2

Marek R
Marek R

Reputation: 37927

To calculate area of polygon you can do in two ways:

slow but universal (there might be problem with precision): get point from pointAtPercent with some step and perform standard calculation for such polygon

fast but will work only for QPainterPath which segments are LineToElement. Just iterate through all polygon corners using elementAt and elementCount and again perform standard calculation to calculate area of polygon.

Upvotes: 3

Tim Meyer
Tim Meyer

Reputation: 12600

I'm not totally sure if this is what you are looking for, but if you simply want to fill the area of a closed painter path, there is a QPainter::fillPath function:

void QPainter::fillPath ( const QPainterPath & path, const QBrush & brush )

Upvotes: 2

Related Questions