如何确定坐标是否在SVG关闭路径内?

时间:2019-03-21 17:51:26

标签: javascript html svg

我已经在SVG上设计了Duval三角形(诊断工具), 合并不同颜色的线段(封闭路径)。 诊断结果将是一个坐标。 是否需要检测结果坐标位于哪个闭合路径?

在以下情况下,诊断结果是红色点。 需要检测关闭路径,即在这种情况下:D2 enter image description here

2 个答案:

答案 0 :(得分:2)

您有几种选择:

答案 1 :(得分:1)

这是使用保罗·勒博的答案。

1。

首先是一个演示,您在其中检查该点是否在某个路径中,在这种情况下为#c路径。 请阅读我的代码中的注释。

// creating a new SVG point
let point = svg.createSVGPoint()
point.x = 300;
point.y = 300;
//checking if the point is in the path c
console.log(c.isPointInFill(point));
svg{border:1px solid}
<svg id="svg" viewBox="0 0 606.731 526.504"  width="200" >
<polygon id="a" fill="#D9D1E0" stroke="#020202" stroke-miterlimit="10" points="300.862,1.001 0.862,526.001 605.862,526.001 "/>
<polygon id="b" fill="#926BB5" stroke="#020202" stroke-miterlimit="10" points="289.576,19.681 442.34,283.546 411.092,343.437 
	515.705,526.001 428.453,525.716 337.314,365.138 385.054,280.945 262.668,66.555 "/>
<polygon id="c" fill="#8ED5ED" stroke="#020202" stroke-miterlimit="10" points="334.4,193.005 384.186,280.946 337.315,364.272 
	428.453,525.716 142.019,525.716 "/>  
<circle cx="300" cy="300" r="5" fill="red" />
</svg>

2。

第二个演示,其中我在画布上绘制多边形并使用上下文的方法isPointInPath(): 请阅读我的代码中的注释。

let ctx = canv.getContext("2d");
canv.width = 606.731;
canv.height = 526.504;
// the main triangle
let duval = [300.862, 1.001, 0.862, 526.001, 605.862, 526.001];
// the arrays of points for the 2 polygons inside the main triangle
let rys = [
  [
    289.576,
    19.681,
    442.34,
    283.546,
    411.092,
    343.437,
    515.705,
    526.001,
    428.453,
    525.716,
    337.314,
    365.138,
    385.054,
    280.945,
    262.668,
    66.555
  ],
  [
    334.4,
    193.005,
    384.186,
    280.946,
    337.315,
    364.272,
    428.453,
    525.716,
    142.019,
    525.716
  ]
];

// drawing the polygons
drawPoly(duval, "#D9D1E0");
drawPoly(rys[0], "#926BB5");
drawPoly(rys[1], "#8ED5ED");


// the point to check
let p = { x: 300, y: 300 };
drawPoint(p);

// looping through the array of shapes to check if the point is in path
for (let i = 0; i < rys.length; i++) {
  // draw again the polygon without stroking or filling
  drawPoly(rys[i]);
  //chect if the point is in path
  if (ctx.isPointInPath(p.x, p.y)) {
    // do something
    console.log(i);
    // if found break the loop
    break;
  }
}


// a function to draw a polygon from an array
function drawPoly(ry, color) {
  ctx.fillStyle = color;
  ctx.beginPath();
  ctx.moveTo(ry[0], ry[1]);
  for (let i = 2; i < ry.length; i += 2) {
    ctx.lineTo(ry[i], ry[i + 1]);
  }
  ctx.closePath();
  if (color) {
    ctx.fill();
    ctx.stroke();
  }
}

function drawPoint(p) {
  ctx.fillStyle = "red";
  ctx.beginPath();
  ctx.arc(p.x, p.y, 5, 0, 2 * Math.PI);
  ctx.fill();
}
canvas{border:1px solid}
<canvas id="canv"></canvas>

3

这次使用getImageData()方法获取该点的像素颜色。 该代码类似于上一个示例中的代码

let ctx = canv.getContext("2d");
canv.width = 606.731;
canv.height = 526.504;

let duval = [300.862, 1.001, 0.862, 526.001, 605.862, 526.001];

let rys = [
  [
    289.576,
    19.681,
    442.34,
    283.546,
    411.092,
    343.437,
    515.705,
    526.001,
    428.453,
    525.716,
    337.314,
    365.138,
    385.054,
    280.945,
    262.668,
    66.555
  ],
  [
    334.4,
    193.005,
    384.186,
    280.946,
    337.315,
    364.272,
    428.453,
    525.716,
    142.019,
    525.716
  ]
];

drawPoly(duval, "#D9D1E0");
drawPoly(rys[0], "#926BB5");
drawPoly(rys[1], "#8ED5ED");



function drawPoly(ry, color) {
  ctx.fillStyle = color;
  ctx.beginPath();
  ctx.moveTo(ry[0], ry[1]);
  for (let i = 2; i < ry.length; i += 2) {
    ctx.lineTo(ry[i], ry[i + 1]);
  }
  ctx.closePath();
  if (color) {
    ctx.fill();
    ctx.stroke();
  }
}


// HERE BEGINS THE IMPORTANT PART

let imgData = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);

let p = { x: 300, y: 300 };
// mark the point with an empty circle
ctx.beginPath();
ctx.arc(p.x,p.y,5,0,2*Math.PI);
ctx.stroke();

// the index of the point p in the imgData.data array
let index = (p.y*imgData.width + p.x)*4;
//the red,green and blue components of the color of the pixel at the index
let r = imgData.data[index];
let g = imgData.data[index + 1];
let b = imgData.data[index + 2];

//test the color
test.style.background = `rgb(${r},${g},${b})`;
canvas{border:1px solid}
#test{width:50px; height:50px; border:1px solid;}
<canvas id="canv"></canvas>
<div id="test"></div>