Search code examples
javascripthtmlgeometryhtml5-canvasgeometry-surface

Canvas HTML | Track a line perpendicular to two point and passing through a point


In a html canvas I draw a line starting from point A and ending at point B. I should, given a point C, draw a line perpendicular to the line from A and B and that passes from C.

Below is how I create the line that passes from A and B (the points are taken as input, for convenience in this example they are supplied by variable.

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.moveTo(50, 100);
ctx.lineTo(150, 100);
ctx.stroke();
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

Now given C (for example C = 80, 130) I would like to draw a line that is perpendicular to the line between A and B and that passes from C How can I calculate points that allow me to create this line?

For example this:

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");
ctx.beginPath();
ctx.moveTo(50, 100);
ctx.lineTo(150, 100);
ctx.stroke();
ctx.beginPath();
ctx.moveTo(80, 10);
ctx.lineTo(80, 130);
 ctx.arc(80, 130, 2, 0, 360, false); // C
ctx.stroke();
<canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

Thanks so much for helping!


Solution

  • In the not trivial (line isn't vertical or horizontal) case, you just need to know that the gradient of the perpendicular line is minus one over the gradient of the line. I hope the below code snippet helps.

    var c = document.getElementById("myCanvas");
    var ctx = c.getContext("2d");
    var pointA = {
      x: 0.0,
      y: 0.0
    };
    var pointB = {
      x: 200.0,
      y: 150.0
    };
    var pointC = {
      x: 80.0,
      y: 130.0
    };
    var pointD = {
      x: 0.0,
      y: 0.0
    };
    
    if (pointA.y == pointB.y) { // AB is horizontal
      pointD.x = pointC.x
      pointD.y = pointA.y
    } else if (pointA.x == pointB.x) { // AB is vertical
      pointD.x = pointA.x
      pointD.y = pointC.y
    } else { // need some geometry
      var gradientOfAB = (pointA.y - pointB.y) / (pointA.x - pointB.x);
      var interceptOfAB = pointA.y - gradientOfAB * pointA.x;
    
      var gradientOfCD = -1 / gradientOfAB;
      var interceptOfCD = pointC.y - gradientOfCD * pointC.x;
    
      pointD.x = (interceptOfAB - interceptOfCD) / (gradientOfCD - gradientOfAB);
      pointD.y = gradientOfCD * pointD.x + interceptOfCD;
    }
    
    ctx.beginPath();
    ctx.moveTo(pointA.x, pointA.y);
    ctx.lineTo(pointB.x, pointB.y);
    ctx.stroke();
    ctx.beginPath();
    ctx.moveTo(pointD.x, pointD.y);
    ctx.lineTo(pointC.x, pointC.y);
    ctx.arc(pointC.x, pointC.y, 2, 0, 360, false);
    ctx.stroke();
    <canvas id="myCanvas" width="300" height="150" style="border:1px solid #d3d3d3;">
    		Your browser does not support the HTML5 canvas tag.
    </canvas>