123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- import { SPoint } from "@persagy-web/draw/lib";
- export class generate {
- /**
- * 计算角平分线上的距离这两条直线l的点
- *
- * @param p1 第一个点
- * @param p2 第二个点 也是2条线的交点
- * @param p3 第三个点
- * @param l 距离2条线的距离
- */
- static getBisector(p1: SPoint, p2: SPoint, p3: SPoint, l: number) {
- const dy1 = p1.y - p2.y;
- const dx1 = p1.x - p2.x;
- const dy2 = p3.y - p2.y;
- const dx2 = p3.x - p2.x;
- // 线1的斜率
- const k1 = dy1 / dx1;
- // 线2的斜率
- const k2 = dy2 / dx2;
- // 线1与x轴的夹角
- const temp1 = Math.atan(k1)
- const a1 = k1 >= 0 ? temp1 : temp1 + Math.PI;
- // 线2与x轴的夹角
- const temp2 = Math.atan(k2)
- const a2 = k2 >= 0 ? temp2 : temp2 + Math.PI;
- // 角平分线斜率
- const k = Math.tan((a1 + a2) / 2);
- // 角平分线b
- const b = p2.y - k * p2.x;
- // 距离两条线l的点 到交点p2的距离
- const Lb2 = l / Math.sin(Math.abs(a1 - a2) / 2);
- // 将距离公式与直线方程连立,并且将直线方程代入,得到一元二次方程 Ax^2 + Bx + C = 0;然后根据得根公式得到2个解
- const A = k * k + 1;
- const B = 2 * k * b - 2 * p2.x - 2 * k * p2.y;
- const C = b * b - Lb2 * Lb2 + p2.x * p2.x + p2.y * p2.y - 2 * b * p2.y;
- // 求解
- const X1 = (-B + Math.sqrt(B * B - 4 * A * C)) / (2 * A);
- const X2 = (-B - Math.sqrt(B * B - 4 * A * C)) / (2 * A);
- const Y1 = k * X1 + b;
- const Y2 = k * X2 + b;
- return [Number(X1.toFixed(2)), Number(Y1.toFixed(2)), Number(X2.toFixed(2)), Number(Y2.toFixed(2))]
- }
- /**
- * 计算一条线的垂线上距离线l的2个点
- *
- * @param p1 点1
- * @param p2 点2
- * @param l 距离这条线的距离
- */
- static getVertical(p1: SPoint, p2: SPoint, l: number) {
- const dy1 = p1.y - p2.y;
- const dx1 = p1.x - p2.x;
- // 线1的斜率
- const k1 = dy1 / dx1;
- // 垂线的斜率
- const k = -1 / k1;
- // 垂线的b
- const b = p1.y - k * p1.x;
- // 将距离公式与直线方程连立,并且将直线方程代入,得到一元二次方程 Ax^2 + Bx + C = 0;然后根据得根公式得到2个解
- const A = k * k + 1;
- const B = 2 * k * b - 2 * p1.x - 2 * k * p1.y;
- const C = b * b - l * l + p1.x * p1.x + p1.y * p1.y - 2 * b * p1.y;
- // 求解
- const X1 = (-B + Math.sqrt(B * B - 4 * A * C)) / (2 * A);
- const X2 = (-B - Math.sqrt(B * B - 4 * A * C)) / (2 * A);
- const Y1 = k * X1 + b;
- const Y2 = k * X2 + b;
- return [Number(X1.toFixed(2)), Number(Y1.toFixed(2)), Number(X2.toFixed(2)), Number(Y2.toFixed(2))]
- }
- /**
- * 计算线段交点
- *
- * @param line1 线段1
- * @param line2 线段2
- * @return SPoint 交点 null 平行但不重合 'repeat' 重合
- */
- static lineIntersection(
- p1: SPoint, p2: SPoint, p3: SPoint, p4: SPoint
- ): SPoint | null | string {
- let k1 = (p2.y - p1.y) / (p2.x - p1.x);
- let b1 = p2.y - k1 * p2.x;
- let k2 = (p4.y - p3.y) / (p4.x - p3.x);
- let b2 = p3.y - k2 * p3.x;
- if (k1 == k2) {
- if (b1 == b2) {
- return "repeat";
- }
- return null;
- }
- let intersectionX = (b2 - b1) / (k1 - k2);
- let intersectionY = k1 * intersectionX + b1;
- // 取线段上的最大最小值可以上下换
- let minX = Math.min(p1.x, p2.x);
- let maxX = Math.max(p3.x, p4.x);
- if (intersectionX >= minX && intersectionX <= maxX) {
- return new SPoint(intersectionX, intersectionY);
- }
- return null;
- }
- /**
- * 去除中间多于的点
- */
- }
|