点关于直线的对称点
<!DOCTYPE HTML><html><head> <script> class Vector2D { constructor (x, y) { this.x = x; this.y = y; } // add add_ (b) { this.x += b.x; this.y += b.y; return this; } add (b) { return Vector2D.Add(this, b); } add_scalar_ (s) { this.x += s; this.y += s; return this; } add_scalar (s) { return Vector2D.Add_Scalar(this, s); } // minus minus_ (b) { this.x -= b.x; this.y -= b.y; return this; } minus (b) { return Vector2D.Minus(this, b); } minus_scalar_ (s) { this.x -= s; this.y -= s; return this; } minus_scalar (s) { return Vector2D.Minus_scalar(this, s); } // mul mul(b) { return Vector2D.Mul(this, b); } mul_scalar_ (s) { this.x *= s; this.y *= s; return this; } mul_scalar (s) { return Vector2D.Mul_Scalar(this, s); } mul_mat_left (M) { return Vector2D.Mul_Mat_Left(this, M); } mul_mat_left_ (M) { var x = this.x * M.a + this.y * M.c; var y = this.x * M.b + this.y * M.d; this.x = x; this.y = y; return this; } // static method static Ones () { return new Vector2D (1, 1); } static Add (a, b) { return new Vector2D (a.x + b.x, a.y + b.y); } static Add_Scalar(a, s) { return new Vector2D (a.x + s, a.y + s); } static Minus (a, b) { return new Vector2D (a.x - b.x, a.y - b.y); } static Minus_Scalar (a, s) { return new Vector2D (a.x - s, a.y - s); } static Mul(a, b) { return a.x * b.x + a.y * b.y; } static Mul_Scalar (a, s) { return new Vector2D(a.x * s, a.y * s); } static Mul_Mat_Left (v, M) { return new Vector2D (v.x * M.a + v.y * M.c, v.x * M.b + v.y * M.d); } static Mul_Mat_Right (v, M) { return new Vector2D (M.a * v.x + M.b * v.y, M.c * v.x + M.d * v.y); } }; class Matrix2x2 { /* a b c d */ constructor (a, b, c, d) { this.a = a; this.b = b; this.c = c; this.d = d; } // add add_ (B) { this.a += B.a; this.b += B.b; this.c += B.c; this.d += B.d; return this; } add (B) { return Matrix2x2.Add(this, B); } add_scalar_ (s) { this.a += s; this.b += s; this.c += s; this.d += s; return this; } add_scalar (s) { return Matrix2x2.Add_Scalar(this, s) } // minus minus_ (B) { this.a -= B.a; this.b -= B.b; this.c -= B.c; this.d -= B.d; return this; } minus (B) { return Matrix2x2.Minus(this, B); } minus_scalar_ (s) { this.a -= s; this.b -= s; this.c -= s; this.d -= s; return this; } minus_scalar (s) { return Matrix2x2.Minus_scalar(this, s) } // mul mul(B) { return Matrix2x2.Mul(this, B); } mul_(B) { var a = this.a * B.a + this.b * B.c; var b = this.a * B.b + this.b * B.d; var c = this.c * B.a + this.d * B.c; var d = this.c * B.b + this.d * b.d; this.a = a; this.b = b; this.c = c; this.d = d; return this; } mul_scalar (s) { return Matrix2x2.Mul_Scalar(this, s); } mul_scalar_ (s) { this.a *= s; this.b *= s; this.c *= s; this.d *= s; return this; } mul_vector_left (v) { return Matrix2x2.Mul_Vector_Left(v, this); } mul_vector_right (v) { return Matrix2x2.Mul_Vector_Right(v, this); } transport () { return Matrix2x2.Transport(this); } transport_ () { var c = this.c; this.c = this.b; this.b = c; return this; } minor () { return Matrix2x2.Minor(this); } minor_ () { var a = this.d; var b = -1 * this.b; var c = -1 * this.c; var d = this.a; this.a = a; this.b = b; this.c = c; this.d = d; return this; } det () { return Matrix2x2.Det(this); } inv () { return Matrix2x2.Inv(this); } inv_ () { var _det = this.det(); if (_det == 0) { console.error("Det of matrix is 0"); return this; } this.minor_(); this.mul_scalar_(1 / _det); return this; } // static method static Eye () { return new Matrix2x2 (1, 0, 0, 1); } static Add (A, B) { return new Matrix2x2 ( A.a + B.a, A.b + B.b, A.c + B.c, A.d + B.d); } static Add_Scalar (A, s) { return new Matrix2x2 ( A.a + s, A.b + s, A.c + s, A.d + s); } static Minus (A, B) { return new Matrix2x2 ( A.a - B.a, A.b - B.b, A.c - B.c, A.d - B.d); } static Minus_Scalar (A, s) { return new Matrix2x2 ( A.a - s, A.b - s, A.c - s, A.d - s); } static Mul (A, B) { return new Matrix2x2( A.a * B.a + A.b * B.c, A.a * B.b + A.b * B.d, A.c * B.a + A.d * B.c, A.c * B.b + A.d * B.d ); } static Mul_Scalar (A, s) { return new Matrix2x2 ( A.a * s, A.b * s, A.c * s, A.d * s); } static Mul_Vector_Left (v, M) { return Vector2D.Mul_Mat_Left(v, M); } static Mul_Vector_Right (v, M) { return Vector2D.Mul_Mat_Right(v, M); } static Transport (M) { return new Matrix2x2 ( M.a, M.c, M.b, M.d ); } static Minor (M) { return new Matrix2x2 ( M.d, -M.b, -M.c, M.a, ); } static Det (M) { return M.a * M.d - M.b * M.c; } static Inv (M) { var _det = Matrix2x2.Det(M); if (_det == 0) { console.error("Det of matrix is 0"); return null; } var minor = Matrix2x2.Minor (M); return Matrix2x2.Mul_Scalar(minor, 1 / _det); } }; function randomInt(left, right) { return Math.floor(Math.random() * (right - left + 1)) + left; } </script></head><body> <canvas id="m_canvas" width="900" height="600"></canvas> <script> function drawPoint (ctx, point, size, color) { ctx.beginPath(); ctx.arc(point.x, point.y, size, 0, 2*Math.PI); ctx.fillStyle = color; ctx.fill(); } function drawLine (a, b, width, color) { ctx.beginPath(); ctx.moveTo(a.x, a.y); ctx.lineTo(b.x, b.y); ctx.strokeStyle = color; ctx.lineWidth = width; ctx.stroke(); } </script> <script> var m_canvas = document.getElementById("m_canvas"); var ctx = m_canvas.getContext("2d"); // 随机两点为l1 var pa = new Vector2D(randomInt(0, 300), randomInt(0, 200)); pa = new Vector2D(100, 150); var pb = new Vector2D(randomInt(600, 900), randomInt(400, 600)); ctx.strokeStyle = "rgba(0, 0, 255, 1.0)"; ctx.strokeRect(0, 0, 900, 600); // 添加鼠标跟踪 m_canvas.onmousemove = function (e) { // 清空 ctx.clearRect(0, 0, 900, 600); // 绘制边界 ctx.strokeStyle = "rgba(0, 0, 255, 1.0)"; ctx.strokeRect(0, 0, 900, 600); // 画l1直线 drawLine(pa, pb, 3, "rgba(255, 0, 0, 1.0)"); // 绘制l1两点 drawPoint(ctx, pa, 5, "rgba(0, 0, 0, 1.0)"); drawPoint(ctx, pb, 5, "rgba(0, 0, 0, 1.0)"); // 鼠标当前坐标 var x = e.offsetX; var y = e.offsetY; var pc = new Vector2D(x, y); drawPoint(ctx, pc, 5, "rgba(0, 0, 0, 1.0)"); // 计算点坐标 var xl = pa.x - pb.x; var yl = pa.y - pb.y; var matrix_l = new Matrix2x2(yl, -xl, xl, yl); var matrix_A = new Matrix2x2(pb.x, -pb.y, pc.y, pc.x); var vector_l = new Vector2D(yl, xl); var po = matrix_l.inv().mul(matrix_A).mul_vector_right(vector_l); drawPoint(ctx, po, 5, "rgba(0, 0, 0, 1.0)"); // 绘制d点 var pd = po.mul_scalar(2).minus(pc); drawPoint(ctx, pd, 5, "rgba(0, 0, 0, 1.0)"); }; </script></body></html>