Skip to content
Advertisement

How to know if a point is inside an arbitrary contour in Javascript?

I have some SVG arbitrary closed shapes composed of lines and curve paths. I want to check if some points are inside the shape. I have found Point in Polygon algorithm that seems to work well, but I will have to decompose my path into a multitude of lines. Is there a more direct solution to this problem? If not, what good algorithm I can use to decompose my paths?

Advertisement

Answer

Let me demonstrate how to use isPointInFill by this live code.

/*
https://developer.mozilla.org/en-US/docs/Web/API/SVGGeometryElement/isPointInFill
*/

const circle = document.getElementById("circle1");

try {
  // Point not in circle
  console.log("Point at 10,10:", circle.isPointInFill(new DOMPoint(10, 10)));

  // Point in circle but not stroke
  console.log("Point at 40,30:", circle.isPointInFill(new DOMPoint(40, 30)));

  // Point in circle stroke
  console.log("Point at 83,17:", circle.isPointInFill(new DOMPoint(83, 17)));
} catch (e) {
  // for the browsers that still support the deprecated interface SVGPoint
  let tof = false;
  const svg = document.getElementsByTagName("svg")[0];
  const point = svg.createSVGPoint();
  if (tof == true) {
    document.getElementById("p1").setAttribute("fill", "red");
  }
  // Point not in circle
  point.x = 10;
  point.y = 10;
  tof = circle.isPointInFill(point);
  console.log("Point at 10,10:", tof);
  if (tof == true) {
    document.getElementById("p1").setAttribute("fill", "red");
  }

  // Point in circle but not stroke
  point.x = 40;
  point.y = 30;
  tof = circle.isPointInFill(point);
  console.log("Point at 40,30:", tof);
  if (tof == true) {
    document.getElementById("p2").setAttribute("fill", "red");
  }

  // Point in circle stroke
  point.x = 83;
  point.y = 17;
  tof = circle.isPointInFill(point);
  console.log("Point at 83,17:", tof);
  if (tof == true) {
    document.getElementById("p3").setAttribute("fill", "red");
  }
} //end_catch
//EOF
<svg
  viewBox="0 0 100 100"
  width="150"
  height="150"
  xmlns="http://www.w3.org/2000/svg">
  <style>
    svg { background-color: lightgray; }
    #circle1 { fill: #FFDDDD; }
  </style>
  <circle
    id="circle1"
    cx="50"
    cy="50"
    r="45"
    stroke="black"
    stroke-width="10" />

  <circle id="p1" cx="10" cy="10" r="5" fill="seagreen" />
  <circle id="p2" cx="40" cy="30" r="5" fill="seagreen" />
  <circle id="p3" cx="83" cy="17" r="5" fill="seagreen" />
</svg>

If isPointInStroke is used instead, the third point will be the one that turns to red.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement