5 votes

Comment déterminer si une coordonnée est à l'intérieur du SVG Close Path ?

J'ai conçu un triangle de Duval (un outil de diagnostic), en SVG, composé de segments (chemins fermés) de différentes couleurs. Le résultat du diagnostic sera une coordonnée. J'ai besoin de détecter la coordonnée résultante qui se trouve dans quel chemin fermé ?

Comme dans le cas suivant, le résultat du diagnostic est un POINT ROUGE. Il faut détecter le chemin le plus proche c'est-à-dire dans ce cas : D2 enter image description here

6voto

BigBadaboom Points 6772

Vous avez plusieurs possibilités :

5voto

enxaneta Points 16926

Il s'agit d'utiliser la réponse de Paul LeBeau.

1.

D'abord une démo où l'on vérifie si le point est dans un certain chemin, le #c dans ce cas. Veuillez lire les commentaires dans mon code.

// 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.

Une deuxième démo où je dessine les polygones sur un canevas et utilise la méthode isPointInPath() du contexte : Veuillez lire les commentaires dans mon code.

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

Cette fois, en utilisant le getImageData() pour obtenir la couleur du pixel au point. Le code est similaire à celui de l'exemple précédent

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>

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X