⚠ 因为使用的是斜率来处理的垂直逻辑 tan,当为被除数为0时做了特殊处理,两点自由变换时到达零界点会有卡顿。

开始复习初中二年级数学知识
斜率k的公式:k=(y1−y2)(x1−x2)k = \dfrac{(y_1 -y_2)}{(x_1 - x_2)}k=(x1−x2)(y1−y2)
两条垂直相交直线的斜率相乘积为-1:k1×k2=−1k_1 \times k_2 = -1k1×k2=−1
如图已知P1P_1P1和P2P_2P2的坐标,以及d的值,求点P4P_4P4的坐标。 😂怀念初中算题的生活

⚠ 仅个人观点非正确答案
k1×k2=−1k_1 \times k_2 = -1k1×k2=−1
设:
P1P2P_1P_2P1P2的斜率为k1k_1k1
P3P4P_3P_4P3P4的斜率为k2k_2k2
k1=(y2−y1)(x2−x1)k_1 = \dfrac{(y_2 -y_1)}{(x_2 - x_1)}k1=(x2−x1)(y2−y1)
k2=(y4−y3)(x4−x3)k_2 = \dfrac{(y_4 -y_3)}{(x_4 - x_3)}k2=(x4−x3)(y4−y3)
k1×(y4−y3)(x4−x3)=−1k_1 \times \dfrac{(y_4 -y_3)}{(x_4 - x_3)}=-1k1×(x4−x3)(y4−y3)=−1
根据勾股定理可知
d=(y4−y3)2+(x4−x3)2d = \sqrt{(y_4 -y_3)^2 + (x_4 - x_3)^2}d=(y4−y3)2+(x4−x3)2
可知下列俩公式
(y4−y3)=d2−(x4−x3)2(y_4 -y_3)=\sqrt{d^2 - (x_4 - x_3)^2}(y4−y3)=d2−(x4−x3)2
(y4−y3)=−(x4−x3)k1(y_4 -y_3)=-\dfrac{ (x_4 - x_3)}{k_1}(y4−y3)=−k1(x4−x3)
合并继续推
d2−(x4−x3)2=−(x4−x3)k1\sqrt{d^2 - (x_4 - x_3)^2}=-\dfrac{ (x_4 - x_3)}{k_1}d2−(x4−x3)2=−k1(x4−x3)
d2−(x4−x3)2=(x4−x3)2k12d^2 - (x_4 - x_3)^2=\dfrac{ (x_4 - x_3)^2}{k_1^2}d2−(x4−x3)2=k12(x4−x3)2
(x4−x3)2k12+(x4−x3)2=d2\dfrac{ (x_4 - x_3)^2}{k_1^2}+(x_4 - x_3)^2=d^2k12(x4−x3)2+(x4−x3)2=d2
(x4−x3)2×(1k12+1)=d2(x_4 - x_3)^2 \times (\dfrac{1}{k_1^2} + 1)=d^2(x4−x3)2×(k121+1)=d2
(x4−x3)2=d21k12+1(x_4 - x_3)^2 =\dfrac{d^2}{\dfrac{1}{k_1^2} + 1}(x4−x3)2=k121+1d2
可知
(x4−x3)=d21k12+1(x_4 - x_3)=\sqrt{\dfrac{d^2}{\dfrac{1}{k_1^2} + 1}}(x4−x3)=k121+1d2
(y4−y3)=−(x4−x3)k1(y_4 - y_3)=-\dfrac{ (x_4 - x_3)}{k_1}(y4−y3)=−k1(x4−x3)
将x4x_4x4和y4y_4y4套入公式中的(x4−x3)(x_4 - x_3)(x4−x3)和(y4−y3)(y_4 - y_3)(y4−y3)
// 已知 A⊥B 则 斜率 k1 * k2 = -1
// 因 k1 = (y2 - y1)/(x2 - x1)
// 所以 (y4 - y3)/(x4 - x3) = - (y2 - y1)/(x2 - x1)
let x1 = startX
let y1 = startY
let x2 = endX
let y2 = endYlet k = (y2 - y1) / (x2 - x1)let y3 = (y1 + y2) / 2
let x3 = (x1 + x2) / 2// 设 d 为箭头末端距离线的距离
let d = 20;let x4 = 0
let y4 = 0
if (x1 == x2) x4 = Math.sign(redirect) * d;
else if (y1 == y2) y4 = Math.sign(redirect) * d;
else {x4 = Math.sign(redirect) * Math.sqrt(Math.pow(d, 2) / (1 + Math.pow(1 / k, 2)))y4 = - 1 / k * x4;
}
其中redirect是指对应方向
// 获得角度
let a = Math.atan2(y4, x4) * 180 / Math.PI
// 角度偏移值
a += 90
// 角度转弧度
let rd = a * Math.PI / 180
// 保存画布
ctx.save()
// 移动画布
ctx.translate(x4 + x3, y4 + y3)
// 旋转画布
ctx.rotate(rd)
// 绘制箭头
ctx.drawImage(arrowImage, -10, -20, 20, 22)
// 画布还原
ctx.rotate(-rd)
ctx.translate(-x4 - x3, -y4 - y3)
ctx.restore()
画垂直线