فهرست منبع

item及scene添加;数据格式定义

haojianlong 5 سال پیش
والد
کامیت
965302244f
9فایلهای تغییر یافته به همراه654 افزوده شده و 14 حذف شده
  1. 1 1
      .eslintrc.js
  2. 89 2
      src/TopoScene.ts
  3. 1 1
      src/TopoView.ts
  4. 59 7
      src/items/EquipItem.ts
  5. 76 3
      src/items/RelationItem.ts
  6. 39 0
      src/types/Anchor.ts
  7. 37 0
      src/types/Equip.ts
  8. 35 0
      src/types/Relation.ts
  9. 317 0
      src/util/SMathUtil.ts

+ 1 - 1
.eslintrc.js

@@ -11,7 +11,7 @@
  *          ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
  *          $@*   ;@@@%=!:                *@*
  *          =@$    ;;;!=%@@@@=!           =@!
- *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2020.  北京上格云技术有限公司
  *            ;%@@$=$@@%*       *@@@$=%@@%;
  *               ::;::             ::;::                                              All rights reserved.
  *

+ 89 - 2
src/TopoScene.ts

@@ -11,7 +11,7 @@
  *          ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
  *          $@*   ;@@@%=!:                *@*
  *          =@$    ;;;!=%@@@@=!           =@!
- *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2020.  北京上格云技术有限公司
  *            ;%@@$=$@@%*       *@@@$=%@@%;
  *               ::;::             ::;::                                              All rights reserved.
  *
@@ -20,10 +20,97 @@
 
 import { SGraphyScene } from "@saga-web/graphy/lib";
 import Axios from "axios";
+import { Equip } from "./types/Equip";
+import { Relation } from "./types/Relation";
+import { EquipItem } from "./items/EquipItem";
+import { RelationItem } from "./items/RelationItem";
 
 /**
  * 拓扑图场景
  *
  * @author  郝建龙
  */
-export class TopoScene extends SGraphyScene {} // Class TopoScene
+export class TopoScene extends SGraphyScene {
+    /** 所有设备    */
+    EquipList: EquipItem[] = [];
+    /** 所有关系item    */
+    RelationList: RelationItem[] = [];
+    /** 设备是否隐藏  */
+    _isShowEquip: boolean = true;
+    get isShowEquip(): boolean {
+        return this._isShowEquip;
+    } // Get isShowEquip
+    set isShowEquip(v: boolean) {
+        if (this._isShowEquip === v) {
+            return;
+        }
+        this._isShowEquip = v;
+        this.EquipList.map(
+            (t: EquipItem): EquipItem => {
+                t.visible = this._isShowEquip;
+                return t;
+            }
+        );
+    } // Set isShowEquip
+
+    /** 设备是否隐藏  */
+    _isShowRelation: boolean = true;
+    get isShowRelation(): boolean {
+        return this._isShowRelation;
+    } // Get isShowEquip
+    set isShowRelation(v: boolean) {
+        if (this._isShowRelation === v) {
+            return;
+        }
+        this._isShowRelation = v;
+        this.RelationList.map(
+            (t: RelationItem): RelationItem => {
+                t.visible = this._isShowRelation;
+                return t;
+            }
+        );
+    } // Set isShowEquip
+
+    loadData() {} // Function loadData()
+
+    /**
+     * 添加所有设备item
+     *
+     */
+    addAllEquip(list: Equip[]): void {
+        if (list.length) {
+            list.forEach(t => {
+                this.addEquip(t);
+            });
+        }
+    } // Function addAllEquip()
+    /**
+     *  添加设备item
+     */
+    addEquip(equip: Equip): void {
+        let item = new EquipItem(null, equip);
+        item.visible = this.isShowEquip;
+        this.EquipList.push(item);
+        this.addItem(item);
+    } // Function addEquip()
+    /**
+     * 添加所有设备item
+     *
+     */
+    addAllRelation(list: Relation[]): void {
+        if (list.length) {
+            list.forEach(t => {
+                this.addRelation(t);
+            });
+        }
+    } // Function addAllRelation()
+    /**
+     *  添加设备item
+     */
+    addRelation(equip: Relation): void {
+        let item = new RelationItem(null, equip);
+        item.visible = this.isShowRelation;
+        this.RelationList.push(item);
+        this.addItem(item);
+    } // Function addRelation()
+} // Class TopoScene

+ 1 - 1
src/TopoView.ts

@@ -11,7 +11,7 @@
  *          ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
  *          $@*   ;@@@%=!:                *@*
  *          =@$    ;;;!=%@@@@=!           =@!
- *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2020.  北京上格云技术有限公司
  *            ;%@@$=$@@%*       *@@@$=%@@%;
  *               ::;::             ::;::                                              All rights reserved.
  *

+ 59 - 7
src/items/EquipItem.ts

@@ -11,7 +11,7 @@
  *          ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
  *          $@*   ;@@@%=!:                *@*
  *          =@$    ;;;!=%@@@@=!           =@!
- *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2020.  北京上格云技术有限公司
  *            ;%@@$=$@@%*       *@@@$=%@@%;
  *               ::;::             ::;::                                              All rights reserved.
  *
@@ -21,6 +21,7 @@
 import { SGraphyItem } from "@saga-web/graphy/lib";
 import { SColor, SPainter, SPoint, SRect } from "@saga-web/draw/lib";
 import { SMouseEvent } from "@saga-web/base/lib";
+import { Equip } from "../types/Equip";
 
 /**
  * 柱子item
@@ -29,11 +30,39 @@ import { SMouseEvent } from "@saga-web/base/lib";
  */
 export class EquipItem extends SGraphyItem {
     /** 宽度  */
-    width: number = 400;
+    _width: number = 400;
+    /** X轴坐标 */
+    get width(): number {
+        return this._width;
+    } // Get width
+    set width(v: number) {
+        this._width = v;
+        this.minX = this.pos.x - v / 2;
+        this.maxX = this.pos.x + v / 2;
+        this.update();
+    } // Set width
     /** 高度  */
-    height: number = 300;
-    /** */
-
+    _height: number = 300;
+    /** X轴坐标 */
+    get height(): number {
+        return this._height;
+    } // Get width
+    set height(v: number) {
+        this._height = v;
+        this.minY = this.pos.y - v / 2;
+        this.maxY = this.pos.y + v / 2;
+        this.update();
+    } // Set width
+    /** 设备数据    */
+    data: Equip | null = null;
+    /** X坐标最小值  */
+    private minX = Number.MAX_SAFE_INTEGER;
+    /** X坐标最大值  */
+    private maxX = Number.MIN_SAFE_INTEGER;
+    /** Y坐标最小值  */
+    private minY = Number.MAX_SAFE_INTEGER;
+    /** Y坐标最大值  */
+    private maxY = Number.MIN_SAFE_INTEGER;
     /** 位置 */
     pos: SPoint = new SPoint(0, 0);
     /** X轴坐标 */
@@ -42,6 +71,8 @@ export class EquipItem extends SGraphyItem {
     } // Get x
     set x(v: number) {
         this.pos.x = v;
+        this.minX = v - this.width / 2;
+        this.maxX = v + this.width / 2;
         this.update();
     } // Set x
     /** Y轴坐标 */
@@ -50,16 +81,35 @@ export class EquipItem extends SGraphyItem {
     } // Get y
     set y(v: number) {
         this.pos.y = v;
+        this.minY = v - this.height / 2;
+        this.maxY = v + this.height / 2;
         this.update();
     } // Set y
 
+    constructor(parent: SGraphyItem | null, data: Equip) {
+        super(parent);
+        if (data.width) {
+            this.width = data.width;
+        }
+        if (data.height) {
+            this.height = data.height;
+        }
+        this.data = data;
+        this.pos = data.pos;
+    } // Constructor
+
     /**
      * Item对象边界区域
      *
      * @return SRect
      */
     boundingRect(): SRect {
-        return new SRect(this.pos.x, this.pos.y, this.width, this.height);
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
     } // Function boundingRect()
 
     /**
@@ -79,5 +129,7 @@ export class EquipItem extends SGraphyItem {
      *
      * @param   painter       painter对象
      */
-    onDraw(painter: SPainter): void {} // Function onDraw()
+    onDraw(painter: SPainter): void {
+        painter.drawRect(this.minX, this.minY, this.width, this.height);
+    } // Function onDraw()
 } // Class EquipItem

+ 76 - 3
src/items/RelationItem.ts

@@ -11,7 +11,7 @@
  *          ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
  *          $@*   ;@@@%=!:                *@*
  *          =@$    ;;;!=%@@@@=!           =@!
- *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2020.  北京上格云技术有限公司
  *            ;%@@$=$@@%*       *@@@$=%@@%;
  *               ::;::             ::;::                                              All rights reserved.
  *
@@ -20,10 +20,83 @@
 
 import { SGraphyItem } from "@saga-web/graphy/lib";
 import { SPainter, SPoint, SRect } from "@saga-web/draw/lib";
+import { Relation } from "../types/Relation";
+import { SMouseEvent } from "@saga-web/base/lib";
 
 /**
- * 柱子item
+ * 关系item
  *
  * @author  郝建龙
  */
-export class RelationItem extends SGraphyItem {} // Class RelationItem
+export class RelationItem extends SGraphyItem {
+    /** 关系数据    */
+    data: Relation | null = null;
+    /** 折点信息    */
+    pointList: SPoint[] = [];
+    /** X坐标最小值  */
+    private minX = Number.MAX_SAFE_INTEGER;
+    /** X坐标最大值  */
+    private maxX = Number.MIN_SAFE_INTEGER;
+    /** Y坐标最小值  */
+    private minY = Number.MAX_SAFE_INTEGER;
+    /** Y坐标最大值  */
+    private maxY = Number.MIN_SAFE_INTEGER;
+
+    constructor(parent: SGraphyItem | null, data: Relation) {
+        super(parent);
+        this.data = data;
+        this.pointList = data.pointList;
+        data.pointList.forEach(it => {
+            let x = it.x,
+                y = it.y;
+            if (x < this.minX) {
+                this.minX = x;
+            }
+            if (y < this.minY) {
+                this.minY = y;
+            }
+            if (x > this.maxX) {
+                this.maxX = x;
+            }
+            if (y > this.maxY) {
+                this.maxY = y;
+            }
+        });
+    } // Constructor
+
+    /**
+     * Item对象边界区域
+     *
+     * @return SRect
+     */
+    boundingRect(): SRect {
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
+    } // Function boundingRect()
+
+    /**
+     *  点击事件
+     *
+     */
+    onClick(event: SMouseEvent): boolean {
+        if (this.selectable) {
+            this.selected = !this.selected;
+        }
+        this.$emit("click", event);
+        return true;
+    } // Function onClick
+
+    /**
+     * Item绘制操作
+     *
+     * @param   painter       painter对象
+     */
+    onDraw(painter: SPainter): void {
+        painter.pen.lineWidth = 50;
+        painter.drawPolyline(this.pointList);
+    } // Function onDraw()
+} // Class RelationItem

+ 39 - 0
src/types/Anchor.ts

@@ -0,0 +1,39 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *                      :*$@@%$*:                         ;:                ;;    ;;
+ *                    :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+ *                   :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+ *                   =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+ *                   =@*                                  %!              @ $= % %@=   =%@!      %=
+ *              *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+ *            %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+ *          ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+ *          $@*   ;@@@%=!:                *@*
+ *          =@$    ;;;!=%@@@@=!           =@!
+ *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2020.  北京上格云技术有限公司
+ *            ;%@@$=$@@%*       *@@@$=%@@%;
+ *               ::;::             ::;::                                              All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+import { SPoint } from "@saga-web/draw/lib";
+
+/**
+ * 锚点item接口
+ *
+ * @author  郝建龙
+ */
+export interface Anchor {
+    /** 宽度  */
+    width?: number;
+    /** 高度  */
+    height?: number;
+    /** 名称  */
+    name?: string;
+    /** 位置-锚点中心点  */
+    pos: SPoint;
+    /** 联机条数限制  */
+    connectNum?: number;
+} // Interface Anchor

+ 37 - 0
src/types/Equip.ts

@@ -0,0 +1,37 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *                      :*$@@%$*:                         ;:                ;;    ;;
+ *                    :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+ *                   :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+ *                   =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+ *                   =@*                                  %!              @ $= % %@=   =%@!      %=
+ *              *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+ *            %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+ *          ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+ *          $@*   ;@@@%=!:                *@*
+ *          =@$    ;;;!=%@@@@=!           =@!
+ *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2020.  北京上格云技术有限公司
+ *            ;%@@$=$@@%*       *@@@$=%@@%;
+ *               ::;::             ::;::                                              All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+import { SPoint } from "@saga-web/draw/lib";
+
+/**
+ * 设备item接口
+ *
+ * @author  郝建龙
+ */
+export interface Equip {
+    /** 宽度  */
+    width?: number;
+    /** 高度  */
+    height?: number;
+    /** 名称  */
+    name?: string;
+    /** 位置-equip中心点  */
+    pos: SPoint;
+} // Interface Equip

+ 35 - 0
src/types/Relation.ts

@@ -0,0 +1,35 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *                      :*$@@%$*:                         ;:                ;;    ;;
+ *                    :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+ *                   :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+ *                   =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+ *                   =@*                                  %!              @ $= % %@=   =%@!      %=
+ *              *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+ *            %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+ *          ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+ *          $@*   ;@@@%=!:                *@*
+ *          =@$    ;;;!=%@@@@=!           =@!
+ *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2020.  北京上格云技术有限公司
+ *            ;%@@$=$@@%*       *@@@$=%@@%;
+ *               ::;::             ::;::                                              All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+import { SPoint } from "@saga-web/draw/lib";
+
+/**
+ * 关系item接口
+ *
+ * @author  郝建龙
+ */
+export interface Relation {
+    /** 类型  */
+    type?: number;
+    /** id  */
+    id?: string;
+    /** 名称  */
+    pointList: SPoint[];
+} // Interface Relation

+ 317 - 0
src/util/SMathUtil.ts

@@ -0,0 +1,317 @@
+/*
+ * ********************************************************************************************************************
+ *
+ *                      :*$@@%$*:                         ;:                ;;    ;;
+ *                    :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+ *                   :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+ *                   =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+ *                   =@*                                  %!              @ $= % %@=   =%@!      %=
+ *              *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+ *            %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+ *          ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+ *          $@*   ;@@@%=!:                *@*
+ *          =@$    ;;;!=%@@@@=!           =@!
+ *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *            ;%@@$=$@@%*       *@@@$=%@@%;
+ *               ::;::             ::;::                                              All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+import { SLine, SPoint, SRect } from "@saga-web/draw/lib";
+import { MinDis } from "../types/MinDis";
+import { Point } from "../types/Point";
+import { PointToLine } from "../types/PointToLine";
+import { Outline } from "../types/Outline";
+// @ts-ignore
+import { intersect } from "polybooljs";
+
+export class SMathUtil {
+    /**
+     * 计算点到点距离
+     *
+     * @return  距离
+     * @param x1
+     * @param y1
+     * @param x2
+     * @param y2
+     */
+    static pointDistance(
+        x1: number,
+        y1: number,
+        x2: number,
+        y2: number
+    ): number {
+        return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+    } // Function pointDistance()
+
+    /**
+     * 计算点到点集中点最小距离,返回该点和该距离
+     *
+     * @param   p       第一个点
+     * @param   arr     点集
+     * @return  距离,点坐标
+     */
+    static getMinDisPoint(p: SPoint, arr: Point[]): MinDis | null {
+        if (!arr.length) {
+            return null;
+        }
+        let minDis = {
+            MinDis: SMathUtil.pointDistance(p.x, p.y, arr[0].X, -arr[0].Y),
+            Point: arr[0]
+        };
+        for (let i = 1; i < arr.length; i++) {
+            let ds = SMathUtil.pointDistance(p.x, p.y, arr[i].X, -arr[i].Y);
+            if (ds < minDis.MinDis) {
+                minDis.MinDis = ds;
+                minDis.Point = arr[i];
+            }
+        }
+        return minDis;
+    } // Function getMinDisPoint()
+
+    /**
+     * 计算点到线段垂线与线段的交点
+     *
+     * @param   p   点
+     * @param   l   线段
+     * @return  距离
+     */
+    static pointToLine(p: SPoint, l: SLine): PointToLine {
+        let d = {
+            MinDis: Number.MAX_SAFE_INTEGER,
+            Line: new SLine(),
+            Point: new SPoint()
+        };
+        let bgX = Math.max(l.x1, l.x2);
+        let smX = Math.min(l.x1, l.x2);
+        if (l.dx == 0) {
+            // l.dx为0 说明线段是垂直于x轴的
+            let bgY = Math.max(l.y1, l.y2);
+            let smY = Math.min(l.y1, l.y2);
+            if (p.y > smY && p.y < bgY) {
+                d.MinDis = Math.abs(p.x - l.x1);
+                d.Line = l;
+                d.Point = new SPoint(l.x1, p.y);
+            }
+        } else if (l.dy == 0) {
+            // l.dy为0 说明线段是平行于x轴的
+            if (p.x > smX && p.x < bgX) {
+                d.MinDis = Math.abs(p.y - l.y1);
+                d.Line = l;
+                d.Point = new SPoint(p.x, l.y1);
+            }
+        } else {
+            // 直线1
+            let k1 = (l.y1 - l.y2) / (l.x1 - l.x2);
+            let b1 = l.y1 - k1 * l.x1;
+            // 直线2
+            let k2 = -1 / k1;
+            let b2 = p.y - k2 * p.x;
+            // 交点
+            let x = (b1 - b2) / (k2 - k1);
+            let y = k1 * x + b1;
+            if (x > smX && x < bgX) {
+                d.MinDis = SMathUtil.pointDistance(p.x, p.y, x, y);
+                d.Line = l;
+                d.Point = new SPoint(x, y);
+            }
+        }
+        return d;
+    } // Function pointDistance()
+
+    /**
+     * 计算点到点集中线段最小距离,返回该点和该距离
+     *
+     * @param   p       第一个点
+     * @param   arr     点集
+     * @return  距离,点坐标
+     */
+    static getMinDisLine(p: SPoint, arr: Point[]): PointToLine | null {
+        if (arr.length < 2) {
+            return null;
+        }
+        let PTL = SMathUtil.pointToLine(
+            p,
+            new SLine(
+                arr[arr.length - 1].X,
+                -arr[arr.length - 1].Y,
+                arr[0].X,
+                -arr[0].Y
+            )
+        );
+        for (let i = 0; i < arr.length - 1; i++) {
+            let temp = SMathUtil.pointToLine(
+                p,
+                new SLine(arr[i].X, -arr[i].Y, arr[i + 1].X, -arr[i + 1].Y)
+            );
+            if (temp.MinDis < PTL.MinDis) {
+                PTL = temp;
+            }
+        }
+        return PTL;
+    } // Function getMinDisPoint()
+
+    /**
+     * 计算矩形是否有交集(外包矩形算法)
+     *
+     * @param   rect1   矩形1
+     * @param   rect2   矩形2
+     * @return  boolean
+     * */
+    static rectIntersection(rect1: SRect, rect2: SRect): boolean {
+        let minX = rect1.x < rect2.x ? rect1.x : rect2.x;
+        let minY = rect1.y < rect2.y ? rect1.y : rect2.y;
+        let maxX = rect1.right > rect2.right ? rect1.right : rect2.right;
+        let maxY = rect1.bottom > rect2.bottom ? rect2.bottom : rect2.bottom;
+        return (
+            rect1.width + rect2.width > maxX - minX &&
+            rect1.height + rect2.height > maxY - minY
+        );
+    } // Function rectIntersection()
+
+    /**
+     * 计算线段交点
+     *
+     * @param   line1   线段1
+     * @param   line2   线段2
+     * @return  SPoint  交点 null 平行但不重合 'repeat' 重合
+     */
+    static lineIntersection(
+        line1: SLine,
+        line2: SLine
+    ): SPoint | null | string {
+        let k1 = line1.dy / line1.dx;
+        let b1 = line1.y1 - k1 * line1.x1;
+        let k2 = line2.dy / line2.dx;
+        let b2 = line2.y1 - k2 * line2.x1;
+        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(line1.x1, line1.x2);
+        let maxX = Math.min(line2.x1, line2.x2);
+        if (intersectionX >= minX && intersectionX <= maxX) {
+            return new SPoint(intersectionX, intersectionY);
+        }
+        return null;
+    } // Function lineIntersection()
+
+    /**
+     * 转化数据格式为[][]
+     *
+     * @param  SP  SPoint[]
+     * @return Arr number[][]
+     */
+    static transferToArray(SP: SPoint[]): number[][] {
+        return SP.map((t): number[] => {
+            return [t.x, t.y];
+        });
+    } // Function transferToArray()
+
+    /**
+     * 转化数据格式为SPoint[]
+     *
+     * @param   arr number[][]
+     * @return  SP  SPoint[]
+     */
+    static transferToSPoint(arr: number[][]): SPoint[] {
+        return arr.map(
+            (t): SPoint => {
+                return new SPoint(t[0], t[1]);
+            }
+        );
+    } // Function transferToSPoint()
+
+    /**
+     * 计算数组中每一项的交集,并返回外轮廓与内轮廓
+     *
+     */
+    static getIntersectInArray(array: number[][][]): Outline[] {
+        let outlineList: Outline[] = [];
+        if (!array.length) {
+            // 无数据不做处理
+        } else if (array.length == 1) {
+            // 只有一条则为外轮廓
+            let outline: Outline = {
+                Outer: [],
+                Inner: []
+            };
+            outline.Outer = array[0].map(
+                (t): SPoint => {
+                    return new SPoint(t[0], t[1]);
+                }
+            );
+            outlineList.push(outline);
+        } else {
+            // 多条的时候,最后一条未外轮廓,倒序遍历与之相交的为内轮廓,不相交为另外的外轮廓
+            let poly2 = {
+                regions: [],
+                inverted: false
+            };
+            // @ts-ignore
+            poly2.regions.push(array[array.length - 1]);
+            let indexArr: number[] = [array.length - 1];
+            for (let i = array.length - 2; i > 0; i--) {
+                let poly1 = {
+                    regions: [],
+                    inverted: false
+                };
+                // @ts-ignore
+                poly1.regions.push(array[i]);
+                let intersectObj = intersect(poly1, poly2);
+                console.log(intersectObj);
+                if (!intersectObj.regions.length) {
+                    indexArr.unshift(i);
+                    poly2.regions = [];
+                    // @ts-ignore
+                    poly2.regions.push(array[i]);
+                }
+            }
+            indexArr.unshift(0);
+            console.log(indexArr);
+            for (let i = 0; i < indexArr.length - 1; i++) {
+                let axArr = array.slice(
+                    i == 0 ? 0 : indexArr[i] + 1,
+                    indexArr[i + 1]
+                );
+                let outline: Outline = {
+                    Outer: [],
+                    Inner: []
+                };
+                outline.Outer = array[indexArr[i + 1]].map(
+                    (t): SPoint => {
+                        return new SPoint(t[0], t[1]);
+                    }
+                );
+                outline.Inner = axArr.map((t): SPoint[] => {
+                    return t.map(
+                        (item): SPoint => {
+                            return new SPoint(item[0], item[1]);
+                        }
+                    );
+                });
+                outlineList.push(outline);
+            }
+        }
+        console.log(outlineList);
+        return outlineList;
+    } // Function getIntersectInArray()
+
+    /**
+     * 计算轮廓线面积
+     * */
+    static calculateArea(arr: SPoint[]): number {
+        let sum = 0;
+        let n = arr.length;
+        arr[n] = arr[0];
+        for (let i = 1; i <= n; i++) {
+            sum += arr[i].x * arr[i - 1].y - arr[i - 1].x * arr[i].y;
+        }
+        return sum / 2;
+    }
+} // Class SMathUtil