Reputation: 1406
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
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
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
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
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