"center" of irregular polygon

190 views
Skip to first unread message

dusadrian

unread,
Nov 21, 2015, 5:30:11 AM11/21/15
to Raphaël
Hi all,

Let's say I need to put a text in the middle of the area of a triangle.
I can calculate the coordinates of the triangle's center using getBBox():

var triangle = "M0,0 L100,0 100,50 z";
var BBox = triangle.getBBox();
var middle;
middle.x = BBox.x + BBox.width/2;
middle.y =BBox.y + BBox.height/2;

This results in the coordinates (50, 50) which are always on the long side of the triangle.
How can I make sure the calculated "middle" is <inside> the triangle?

The correct coordinates should be approximately: (75, 25).

The code should of course be independent of this particular example, it should work for any kind of shape.

Chris Williams

unread,
Nov 21, 2015, 11:14:32 AM11/21/15
to raph...@googlegroups.com
If you google "calculate center of irregular polygon" there are a number of solutions.  Some highly complex, some not so.  Perhaps the most accurate is the inner circle approach where you determine the center of the largest circle that will be fully enclosed.

My favorite is the simple one where you average the X coordinates, then the Y coordinates.  In the case you give that would give 66, 16 which, as you note is significantly closer to the visual "center" of the object.  Seems like that's the easiest place to start.

--
You received this message because you are subscribed to the Google Groups "Raphaël" group.
To unsubscribe from this group and stop receiving emails from it, send an email to raphaeljs+...@googlegroups.com.
To post to this group, send email to raph...@googlegroups.com.
Visit this group at http://groups.google.com/group/raphaeljs.
For more options, visit https://groups.google.com/d/optout.

dusadrian

unread,
Nov 23, 2015, 6:07:26 AM11/23/15
to Raphaël
Thanks very much, I think that is exactly what I was looking for.
This wiki page explains it:

And here is the code I've come up with:

function getCentroid(path) {
    var x = new Array(11);
    var y = new Array(11);
    var asum = 0, cxsum = 0, cysum = 0;
    var totlength = path.getTotalLength();
    for (var j = 0; j < 11; j++) {
        if (j < 10) {
            var location = path.getPointAtLength(j*totlength/10);
            x[j] = location.x;
            y[j] = location.y;
        }
        else {
            x[10] = x[0];
            y[10] = y[0];
        }
        
        if (j > 0) {
            asum += x[j - 1]*y[j] - x[j]*y[j - 1];
            cxsum += (x[j - 1] + x[j])*(x[j - 1]*y[j] - x[j]*y[j - 1]);
            cysum += (y[j - 1] + y[j])*(x[j - 1]*y[j] - x[j]*y[j - 1]);
        }
    }
    
    return({x: (1/(3*asum))*cxsum, y: (1/(3*asum))*cysum});
Reply all
Reply to author
Forward
0 new messages