ofPolyline.getArea() calculation

I’m getting negative values trying to get area of a polyline - the algorithm works fine on paper, but produces negative values when running. Am I missing something fundamental?

        // area
        for(int i=0;i<(int)points.size()-1;i++){
            area += points[i].x * points[i+1].y - points[i+1].x * points[i].y;
        }
        area += points[points.size()-1].x * points[0].y - points[0].x * points[points.size()-1].y;
        area *= 0.5;

I don’t know what you’re trying to do in that algorithm. It’s not one that looks to me like an area calculation I’m familiar with.

And I don’t know what the area of a polyline would even be, given a polyline is a continuous line composed of one or more line segments… not a bounded region.

Looking at the calculation, you’re accumulating numbers including subtractions without any guarantee I can intuit that you’d end up with a positive number.

What is the concept and algorithm you’re trying to do, in English?

1 Like

I think they are looking at the code inside of ofPolyline – if helpful

https://mathworld.wolfram.com/PolygonArea.html

see especially this point

Note that the area of a convex polygon is defined to be positive if the points are arranged in a counterclockwise order, and negative if they are in clockwise order (Beyer 1987).

2 Likes

this code is straight from openframeworks polyline area calculation function.
All polylines in question are closed contours. It works perfectly ok on paper with basic polygons i tried calculating by hand, but goes a bit awry with with the actual geometry when running. Please see the screenshot attached. The contours are marked id : area : perimeter and they don’t quite relate to the visual output.

yes, Zach - you’re correct - this is ofPolyline code. And thank you for the wolfram link - I was looking for a description of the algorithm itself. As you can see from the post above - area and calculations don’t look quite consistent.

Yeah, even if those are drawn clockwise and so giving negative areas, the absolute values of those areas don’t seem to correspond to the areas of the shapes in that screenshot.

1 Like

Exactly. But after a bit of fiddling around I noticed that the problem is actually not with the calculation of area, but with assigning ID’s to the contour. So I’ll keep digging but in a different direction now. Will probably post another question soon :slight_smile:

Thank you for looking into this!

1 Like

Hmm this definitely looks like a bug with ofPolyine::getArea().

The rect on the right is drawn with the opposite order as the one on the left.
Feel free to open an issue on Github and I can add it to our 0.11.1 patch release checklist.

    ofSetColor(190, 190, 0);
    
    ofPolyline line;
    line.addVertex(100,100);
    line.addVertex(200,100);
    line.addVertex(200,200);
    line.addVertex(100,200);
    line.setClosed(true);
    line.draw();
        
    ofSetColor(30);
    ofDrawBitmapString("area: " + ofToString(line.getArea()), 80, 80);
    
    ofSetColor(190, 190, 0);
    
    ofTranslate(300, 0);
    
     line.clear();
     line.addVertex(100,200);
     line.addVertex(200,200);
     line.addVertex(200,100);
     line.addVertex(100,100);
     line.setClosed(true);
     line.draw();
         
     ofSetColor(30);
     ofDrawBitmapString("area: " + ofToString(line.getArea()), 80, 80);

Thanks for finding this!
Theo

I actually don’t think this is an bug but a product of the algorithm for polygon area, which returns negative values for clockwise shapes (and positive for counterclockwise) -->

https://mathworld.wolfram.com/PolygonArea.html

I’ve seen this in other libraries, such as opencv

Oh wow!

Interesting to see that it’s intended behavior ( at least from the original algorithm ).

For a recent project it felt more like a bug as we were mapping area to another value and couldn’t figure out why things didn’t correspond.

I imagine for most users using ofPolyline a negative value for area is not very useful and might feel like the function is broken.

I wonder if making this always positive but then having another function for querying winding might be less confusing?

Theo

1 Like

Hello,

Or do the same than the opencv contourArea( bool oriented ) function, add a new “oriented” parameter, and make it true by default ? This might be a solution to keep backward compatibility.

Hi

I think that backward compatibility should be mantained as far as possible. So maybe a better approach can be write clearly in the ofPolyline.getArea() function documentation that you can get negative values, and what that means.
Aside from this, create another function, maybe like getAbsArea(), that return only positive values.

1 Like