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.