<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  <meta http-equiv="X-UA-Compatible" content="ie=edge" />
  <title>点到直线的距离</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }
  </style>
</head>

<body>
  <svg width="100%" height="400px">
    <polyline id="polyline" fill="none" stroke-width="5px" stroke-linecap="round" stroke-linejoin="round" stroke="black" points="20,100 40,60 70,80 100,20 300,300 600,300 600,100" />
  </svg>
  <h1>Click and show in console.</h1>
  <script>
    function sqr(x) {
      return x * x;
    }

    function dist2(v, w) {
      return sqr(v.x - w.x) + sqr(v.y - w.y);
    }

    function distToSegmentSquared(p, v, w) {
      var length = dist2(v, w);
      if (length == 0) return dist2(p, v);
      var t =
        ((p.x - v.x) * (w.x - v.x) + (p.y - v.y) * (w.y - v.y)) / length;
      if (t < 0) return dist2(p, v);
      if (t > 1) return dist2(p, w);
      return dist2(p, {
        x: v.x + t * (w.x - v.x),
        y: v.y + t * (w.y - v.y)
      });
    }

    function distToSegment(p, v, w) {
      return Math.sqrt(distToSegmentSquared(p, v, w));
    }
    var polyline = document.getElementById("polyline");

    function clickHandler(e) {
      var point = {
        x: e.clientX,
        y: e.clientY,
      };
      var i = 0,
        length = polyline.points.length;
      for (; i < length - 1; i++) {
        var start = polyline.points[i];
        var end = polyline.points[i + 1];
        var dist = distToSegment(point, start, end);
        console.log("距离线段最短的距离:", dist);
        console.log("距离直线垂足的距离:", distToLine(point, start, end));
        vectorMethod(point, start, end);
        console.log("\n");
      }
    }
    document.addEventListener("click", clickHandler, false);

    function distToLine(p, start, end) {
      if (start.x === end.x) {
        return Math.abs(start.x - p.x);
      }
      if (start.y === end.y) {
        return Math.abs(start.y - p.y);
      }
      var k = (end.y - start.y) / (end.x - start.x);
      var b = start.y - k * start.x;
      var A = -k;
      var B = 1;
      var C = -b;
      return Math.abs(A * p.x + B * p.y + C) / Math.sqrt(A * A + B * B);
    }
    /**
     * 向量运算
     * 点 p 到线段 ab 的最短距离
     */
    function vectorMethod(p, a, b) {
      let r =
        ((p.x - a.x) * (b.x - a.x) + (p.y - a.y) * (b.y - a.y)) /
        ((a.x - b.x) ** 2 + (a.y - b.y) ** 2);
      if (r > 0 && r < 1) {
        let c = {
          x: a.x + r * (b.x - a.x),
          y: a.y + r * (b.y - a.y)
        };
        let pc = Math.sqrt((c.x - p.x) ** 2 + (c.y - p.y) ** 2);
        console.log(r, pc, c);
      } else if (r >= 1) {
        let bp = Math.sqrt((b.x - p.x) ** 2 + (b.y - p.y) ** 2);
        console.log(r, bp);
      } else if (r <= 0) {
        let ap = Math.sqrt((a.x - p.x) ** 2 + (a.y - p.y) ** 2);
        console.log(r, ap);
      }
    }
    let test = vectorMethod({
      x: 0,
      y: -310
    }, {
      x: -80,
      y: -310
    }, {
      x: 30,
      y: -310
    })
    console.log(test)
  </script>
</body>
/* More https://jsfiddle.net/beentaken/9k1sf6p2/ */

* {
  margin: 0;
  padding: 0;
}

External CSS

This Pen doesn't use any external CSS resources.

External JavaScript

This Pen doesn't use any external JavaScript resources.