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?
CodePudding user response:
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("circle");
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">
<circle
id="circle"
cx="50"
cy="50"
r="45"
fill="white"
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.