Search code examples
mathcanvas2dpolygoncoordinate-transformation

Find a point on perpendicular of a line


I have a side of a irregular polygon (x1,y1) (x2,y2) at a angle A and the midpoint of the side (mx, my).

I need to find two points (x3,y3) and (x4,y4) on a perpendicular from A passing through (mx, my), with some offset. So that I could check which point is the inside/outside of the polygon.

I'll use the outside one to show the measurement text of the side of the polygon, e.g 2cms

Click to see Visuals


Solution

  • You dont specify the language, but in almost all of them we have atan2 function for that.

    canvas.width = window.innerWidth - 10;
    canvas.height = window.innerHeight - 10;
    const ctx = canvas.getContext('2d');
    
    const line = [canvas.width/2, canvas.height/2, 10, 10];
    const pLen = 100; // Length of perpendicular
    
    function drawOrto(line) {
      // line vector
      const dx = line[2] - line[0];
      const dy = line[3] - line[1];
    
      // center point
      const mx = line[0] + dx / 2;
      const my = line[1] + dy / 2;
     
      const atan = Math.atan2(dy, dx);
      // perpendicular vector
      const pdx = - pLen * Math.sin(atan);
      const pdy = pLen * Math.cos(atan);
    
      ctx.clearRect(0, 0, canvas.width, canvas.height);  
      
      // Line 
      ctx.beginPath();
      ctx.strokeStyle = 'black';
      ctx.moveTo(line[0], line[1]);
      ctx.lineTo(line[2], line[3]);
      ctx.stroke();
      
      // Perpendicular (draw vector both sides from center) 
      ctx.beginPath();
      ctx.strokeStyle = 'red';
      ctx.moveTo(mx - pdx / 2, my - pdy / 2);
      ctx.lineTo(mx + pdx / 2, my + pdy / 2);
      ctx.stroke();
      
      // Dots
      ctx.fillStyle = 'red';
      ctx.fillRect(line[0] - 1, line[1] - 1, 3, 3);
      ctx.fillRect(line[2] - 1, line[3] - 1, 3, 3);
      
      ctx.fillStyle = 'yellow';  
      ctx.fillRect(mx - 1, my - 1, 3, 3);
      
      ctx.fillStyle = 'green';  
      ctx.fillRect(mx - pdx / 2 - 1, my - pdy / 2 - 1, 3, 3);
      ctx.fillRect(mx + pdx / 2 - 1, my + pdy / 2 - 1, 3, 3);
    }
    
    
    drawOrto(line);
    canvas.onmousemove = e => {
      line[2] = e.offsetX;
      line[3] = e.offsetY;
      drawOrto(line);
    }
    <canvas id=canvas></canvas>