Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

179
Vistas
How to convert a line to a rotated rectangle?

Let's say I had a line with the form: x1, y1, x2, y2 and a given thickness.

I am looking for a way to convert that line to a rectangle rotated around its origin, such that if you were to draw both of them on a canvas, they would overlap completely.

I've developed a complete reproduction of the problem I'm facing below:

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

const thickness = 7;
const lineX1 = 25, lineY1 = 50;
const lineX2 = 100, lineY2 = 100;

function rotateCanvas(x, y, a) {
  ctx.translate(x, y);
  ctx.rotate(a);
  ctx.translate(-x, -y);
}

function drawRectangle(rX, rY, rW, rH, rA, color) {
  ctx.beginPath();
  ctx.fillStyle = "#dd3333";
  rotateCanvas(rX + rW / 2, rY + rH / 2, rA);
  ctx.rect(rX, rY, rW, rH);
  rotateCanvas(rX + rW / 2, rY + rH / 2, -rA);
  ctx.fill();
}

function drawLine(x1, y1, x2, y2) {
  ctx.lineWidth = thickness;
  ctx.strokeStyle = "#33dd33";
  ctx.beginPath();
  ctx.moveTo(x1, y1);
  ctx.lineTo(x2, y2);
  ctx.stroke();
}

function calcRectFromLine(x1, y1, x2, y2) {
  const dx = x2 - x1;
  const dy = y2 - y1;
  const mag = Math.sqrt(dx * dx + dy * dy);
  const angle = Math.atan2(dy, dx);

  return { x: x1, y: y1, w: mag, h: thickness, a: angle };
}

drawLine(lineX1, lineY1, lineX2, lineY2);

const r = calcRectFromLine(lineX1, lineY1, lineX2, lineY2);

drawRectangle(r.x, r.y, r.w, r.h, r.a);
<canvas></canvas>

If you run the code, you'll see that the red rectangle is not on top of the green line. I would like to fix that somehow.

I believe the only function that needs to be fixed is calcRectFromLine. Ideally that would return a rectangle that, when passed to drawRectangle, would cause the green line to no longer be visible, as it would be covered completely by the red rectangle.

I also believe I need to use some sort of sin and cos to offset the red rectangle, but I'm not sure of the exact math to accomplish that.

about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

You calculate rectangle left and top improperly, using coordinates of rotated line. Correction:

return { x: (x1+x2)/2 - mag/2, y: (y1+y2)/2 - thickness/2, 
         w: mag, h: thickness, a: angle };`

const canvas = document.querySelector("canvas");
const ctx = canvas.getContext("2d");

const thickness = 7;
const lineX1 = 25, lineY1 = 50;
const lineX2 = 100, lineY2 = 100;

function rotateCanvas(x, y, a) {
  ctx.translate(x, y);
  ctx.rotate(a);
  ctx.translate(-x, -y);
}

function drawRectangle(rX, rY, rW, rH, rA, color) {
  ctx.beginPath();
  ctx.fillStyle = "#dd3333";
rotateCanvas(rX + rW / 2, rY + rH / 2, rA);
  ctx.rect(rX, rY, rW, rH);
  rotateCanvas(rX + rW / 2, rY + rH / 2, -rA);
  ctx.fill();
}

function drawLine(x1, y1, x2, y2) {
  ctx.lineWidth = thickness;
  ctx.strokeStyle = "#33dd33";
  ctx.beginPath();
  ctx.moveTo(x1, y1);
  ctx.lineTo(x2, y2);
  ctx.stroke();
}

function calcRectFromLine(x1, y1, x2, y2) {
  const dx = x2 - x1;
  const dy = y2 - y1;
  const mag = Math.sqrt(dx * dx + dy * dy);
  const angle = Math.atan2(dy, dx);

  return { x: (x1+x2)/2 - mag/2, y: (y1+y2)/2 - thickness/2, w: mag, h: thickness, a: angle };
}

drawLine(lineX1, lineY1, lineX2, lineY2);

const r = calcRectFromLine(lineX1, lineY1, lineX2, lineY2);

drawRectangle(r.x, r.y, r.w, r.h, r.a);
<canvas><\canvas>

about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda