2 votes

Existe-t-il un moyen d'utiliser le canevas HTML pour dessiner un chemin/forme autour de ces 2 cercles?

Je veux ajouter une forme/trajet autour des 2 cercles. Image de ce que je veux

Voici mon code actuel.

var longueur = 200
var taille = 50
// cercles
ctx.beginPath();
ctx.arc(123,120,100,0,2*Math.PI);
ctx.stroke();
ctx.fill()
ctx.beginPath();
ctx.arc(longueur,longueur,taille,0,2*Math.PI);
ctx.stroke();
ctx.fill()
// ligne entre les 2 cercles
ctx.beginPath();
ctx.moveTo(123,120);
ctx.lineTo(longueur,longueur);
ctx.stroke();

3voto

user3297291 Points 14888

Si vous trouvez les tangentes extérieures des deux cercles, vous pouvez dessiner deux lignes entre eux. Vous pouvez ensuite utiliser .arc pour dessiner les parties restantes du cercle :

// Configuration
const cvs = document.createElement("canvas");
cvs.width = cvs.height = 400;
const ctx = cvs.getContext("2d");
const inputs = Array.from(document.querySelectorAll("input"));
inputs.forEach(el => el.addEventListener("input", onChange));
document.body.appendChild(cvs);
onChange();

// Utilitaires de dessin
function drawCircle({ x, y, r }, color = "black", width = 1) {
  ctx.strokeStyle = color;
  ctx.lineWidth = width;
  ctx.beginPath();
  ctx.arc(x, y, r, 0, 2*Math.PI);
  ctx.stroke();
}

function drawLine(x1, y1, x2, y2, color = "black", width = 1) {
  ctx.strokeStyle = color;
  ctx.lineWidth = width;

  ctx.beginPath();
  ctx.moveTo(x1, y1);
  ctx.lineTo(x2, y2);
  ctx.stroke();
}

function drawArc(x, y, r, a1, a2, color = "black", width = 1) {
  ctx.strokeStyle = color;
  ctx.lineWidth = width;

  ctx.beginPath();
  ctx.arc(x, y, r, a1, a2);
  ctx.stroke();
}

function render(c1, c2) {
  ctx.clearRect(0, 0, cvs.width, cvs.height);

  // cercles
  drawCircle(c1);
  drawCircle(c2);

  // ligne entre les 2 cercles
  drawLine(c1.x, c1.y, c2.x, c2.y);

  // tangentes
  const tangents = outerTangents(c1, c2);
  tangents.lines.forEach(
    ([[x1, y1], [x2, y2]]) => drawLine(x1, y1, x2, y2, "rgba(255, 0, 0, 0.5)", 5)
  );

  // Arcs
  const [ a1, a2 ] = tangents.angles;
  const from = a2 + a1;
  const to = a1 - a2;
  drawArc(c1.x, c1.y, c1.r, from, to, "rgba(0, 255, 255, 0.5)", 5);
  drawArc(c2.x, c2.y, c2.r, to, from, "rgba(255, 0, 255, 0.5)", 5);
}

function onChange() {
  const [ x1, y1, r1, x2, y2, r2 ] = inputs.map(el => el.valueAsNumber);
  render({ x: x1, y: y1, r: r1 }, { x: x2, y: y2, r: r2 });
}

// https://en.wikipedia.org/wiki/Tangent_lines_to_circles#Outer_tangent
function outerTangents({ x: x1, y: y1, r: r1 }, { x: x2, y: y2, r: r2 }) {
  const dx = x2 - x1;
  const dy = y2 - y1;
  const dxy = Math.sqrt(dx ** 2 + dy ** 2);

  if (dxy <= Math.abs(r2 - r1)) {
    return { lines: [], angles: [] };
  }

  const a1 = Math.atan2(dy, dx);
  const a2 = Math.acos((r1 - r2) / dxy);

  return {
    lines: [
      [
        [x1 + r1 * Math.cos(a1 + a2), y1 + r1 * Math.sin(a1 + a2)],
        [x2 + r2 * Math.cos(a1 + a2), y2 + r2 * Math.sin(a1 + a2)]
      ],
      [
        [x1 + r1 * Math.cos(a1 - a2), y1 + r1 * Math.sin(a1 - a2)],
        [x2 + r2 * Math.cos(a1 - a2), y2 + r2 * Math.sin(a1 - a2)]
      ]
    ],
    angles: [ a1, a2 ]
  };
}

X1 
Y1 
R1 

X2 
Y2 
R2

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