1

Let's take the example of this simple .svg : enter image description here

For that shape I get this code :

   <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
         width="1000px" height="1000px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
    <path d="M1000,500c0,276.143-223.857,500-500,500c-276.143,0-57.729-467.521-313.389-571.889C-252.278,248.944,223.858,0,500,0
        C776.143,0,1000,223.857,1000,500z"/>
    </svg>

I there a way to get the value of the area deduced from the <path> info of the .svg ?

<path d="M1000,500c0,276.143-223.857,500-500,500c-276.143,0-57.729-467.521-313.389-571.889C-252.278,248.944,223.858,0,500,0
        C776.143,0,1000,223.857,1000,500z"/>
  • @RobertLongson that could be an idea.. do you have an example on the top of your head? –  Apr 26 '18 at 19:08
  • ok thanks, I'll dig that direction –  Apr 27 '18 at 09:24
  • @user9234196: OK, old question ... But you might also try this helper I described [here: How can I calculate the area of a bezier curve?](https://stackoverflow.com/questions/10039679/how-can-i-calculate-the-area-of-a-bezier-curve#73325702). It's a way faster method, since you don't need to create dozens/hindreds of polygon points. – herrstrietzel Aug 11 '22 at 19:12

1 Answers1

2

You could convert the path to a polygon, then use the "area of a polygon" algorithm.

The accuracy will depend on how many points you use during the conversion, and any floating point errors that may accumulate.

I don't know how its accuracy compares to the count-the-pixels method. But I would expect it to be more accurate.

function calculateAreaOfPolygon(points)
{
  if (points.length < 3)
    return 0;
  var area = 0, n = points.length;
  for (var i=0; i<(n-1); i++) {
    area += points[i].x * points[i+1].y;
    area -= points[i+1].x * points[i].y;
  }
  area += points[n-1].x * points[0].y;
  area -= points[0].x * points[n-1].y;
  return Math.abs(area) / 2;
}

function convertPathToPolygon(pathId)
{
  var pathElem = document.getElementById(pathId);
  var pathLen = pathElem.getTotalLength();
  var numSteps = Math.floor(pathLen * 2);
  var points = [];
  for (var i=0; i<numSteps; i++) {
    var p = pathElem.getPointAtLength(i * pathLen / numSteps);
    points.push(p);
  }
  return points;
}

var pathPointsArray = convertPathToPolygon("mypath");

console.log(calculateAreaOfPolygon(pathPointsArray));
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
         width="1000px" height="1000px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
    <path id="mypath" d="M1000,500c0,276.143-223.857,500-500,500c-276.143,0-57.729-467.521-313.389-571.889C-252.278,248.944,223.858,0,500,0
        C776.143,0,1000,223.857,1000,500z"/>
</svg>
Paul LeBeau
  • 97,474
  • 9
  • 154
  • 181
  • WHAOOO great ! for a circle of 100 by 100 I get this result => 7853.850216621853 (should get 7850). So that's quite accurate... I'll try other solution but I'll be more than happy to tick your answer.. simple and efficient =). To adjust the accuracy it's this line I have to parameter "var numSteps = Math.floor(pathLen * 2) ; " ? I see that it changes the number of polygons but not the final result ..... –  Apr 28 '18 at 15:25
  • Yes, I based the number of steps on the path length. But you may wish to make it a parameter. Or calculate the number of steps a different way. The number of steps does make a difference, generally the more the better. But the number you choose will be a compromise between speed and accuracy. – Paul LeBeau Apr 29 '18 at 06:38