Browse Source

矩形选择区域修改 遮罩层添加 空间高亮状态添加

haojianlong 5 years ago
parent
commit
ef9bca42f9

+ 11 - 1
package-lock.json

@@ -1,6 +1,6 @@
 {
 {
     "name": "@saga-web/cad-engine",
     "name": "@saga-web/cad-engine",
-    "version": "2.0.303",
+    "version": "2.0.369",
     "lockfileVersion": 1,
     "lockfileVersion": 1,
     "requires": true,
     "requires": true,
     "dependencies": {
     "dependencies": {
@@ -943,6 +943,16 @@
             "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
             "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
             "dev": true
             "dev": true
         },
         },
+        "poly-decomp": {
+            "version": "0.3.0",
+            "resolved": "http://dev.dp.sagacloud.cn:8082/repository/npm-saga/poly-decomp/-/poly-decomp-0.3.0.tgz",
+            "integrity": "sha512-hWeBxGzPYiybmI4548Fca7Up/0k1qS5+79cVHI9+H33dKya5YNb9hxl0ZnDaDgvrZSuYFBhkCK/HOnqN7gefkQ=="
+        },
+        "polybooljs": {
+            "version": "1.2.0",
+            "resolved": "http://dev.dp.sagacloud.cn:8082/repository/npm-saga/polybooljs/-/polybooljs-1.2.0.tgz",
+            "integrity": "sha1-tDkMLgedTCYtOyUExiiNlbp6R1g="
+        },
         "prelude-ls": {
         "prelude-ls": {
             "version": "1.1.2",
             "version": "1.1.2",
             "resolved": "http://dev.dp.sagacloud.cn:8082/repository/npm-saga/prelude-ls/-/prelude-ls-1.1.2.tgz",
             "resolved": "http://dev.dp.sagacloud.cn:8082/repository/npm-saga/prelude-ls/-/prelude-ls-1.1.2.tgz",

+ 5 - 3
package.json

@@ -1,6 +1,6 @@
 {
 {
     "name": "@saga-web/cad-engine",
     "name": "@saga-web/cad-engine",
-    "version": "2.0.366",
+    "version": "2.0.388",
     "description": "上格云 CAD图形引擎。",
     "description": "上格云 CAD图形引擎。",
     "main": "lib/index.js",
     "main": "lib/index.js",
     "types": "lib/index.d.js",
     "types": "lib/index.d.js",
@@ -20,13 +20,13 @@
         "registry": "http://dev.dp.sagacloud.cn:8082/repository/npm-hosted/"
         "registry": "http://dev.dp.sagacloud.cn:8082/repository/npm-hosted/"
     },
     },
     "devDependencies": {
     "devDependencies": {
+        "@types/jest": "^24.0.15",
         "@typescript-eslint/eslint-plugin": "^1.12.0",
         "@typescript-eslint/eslint-plugin": "^1.12.0",
         "@typescript-eslint/parser": "^1.12.0",
         "@typescript-eslint/parser": "^1.12.0",
         "eslint": "^6.0.1",
         "eslint": "^6.0.1",
         "eslint-config-prettier": "^6.0.0",
         "eslint-config-prettier": "^6.0.0",
         "eslint-plugin-prettier": "^3.1.0",
         "eslint-plugin-prettier": "^3.1.0",
         "prettier": "^1.18.2",
         "prettier": "^1.18.2",
-        "@types/jest": "^24.0.15",
         "ts-jest": "^24.0.2",
         "ts-jest": "^24.0.2",
         "typescript": "^3.5.3"
         "typescript": "^3.5.3"
     },
     },
@@ -35,6 +35,8 @@
         "@saga-web/draw": "2.1.58",
         "@saga-web/draw": "2.1.58",
         "@saga-web/graphy": "2.1.30",
         "@saga-web/graphy": "2.1.30",
         "axios": "^0.18.0",
         "axios": "^0.18.0",
-        "pako": "^1.0.10"
+        "pako": "^1.0.10",
+        "poly-decomp": "^0.3.0",
+        "polybooljs": "^1.2.0"
     }
     }
 }
 }

+ 92 - 4
src/DivideFloorScene.ts

@@ -24,12 +24,15 @@ import { SceneMarkItem } from "./items/SceneMarkItem";
 import { ZoneItem } from "./items/ZoneItem";
 import { ZoneItem } from "./items/ZoneItem";
 import { Zone } from "./types/Zone";
 import { Zone } from "./types/Zone";
 import { SMouseEvent } from "@saga-web/base/lib";
 import { SMouseEvent } from "@saga-web/base/lib";
-import { SGraphyItem } from "@saga-web/graphy/lib";
 import { HighlightItem } from "./items/HighlightItem";
 import { HighlightItem } from "./items/HighlightItem";
 import { SMathUtil } from "./utils/SMathUtil";
 import { SMathUtil } from "./utils/SMathUtil";
 import { MinDis } from "./types/MinDis";
 import { MinDis } from "./types/MinDis";
 import { PointToLine } from "./types/PointToLine";
 import { PointToLine } from "./types/PointToLine";
 import { RectSelectItem } from "./items/RectSelectItem";
 import { RectSelectItem } from "./items/RectSelectItem";
+// @ts-ignore
+import { intersect } from "polybooljs";
+import { ShadeItem } from "./items/ShadeItem";
+import { SGraphyItem } from "@saga-web/graphy/lib";
 
 
 /**
 /**
  * 划分业务空间
  * 划分业务空间
@@ -50,10 +53,13 @@ export class DivideFloorScene extends FloorScene {
     } // Set isMarking
     } // Set isMarking
 
 
     /** 蒙版item  */
     /** 蒙版item  */
-    sceneMark: SGraphyItem | null = null;
+    sceneMark: SceneMarkItem | null = null;
     /** 业务空间list   */
     /** 业务空间list   */
     zoneList: ZoneItem[] = [];
     zoneList: ZoneItem[] = [];
 
 
+    /** 遮罩List  */
+    shadeList: ShadeItem[] = [];
+
     /** 业务空间是否可选    */
     /** 业务空间是否可选    */
     _isZoneSelectable: boolean = true;
     _isZoneSelectable: boolean = true;
     get isZoneSelectable(): boolean {
     get isZoneSelectable(): boolean {
@@ -112,7 +118,11 @@ export class DivideFloorScene extends FloorScene {
      */
      */
     addSceneMark(data: SPoint[]): void {
     addSceneMark(data: SPoint[]): void {
         if (data.length) {
         if (data.length) {
-            let sceneMark = new SceneMarkItem(null, data);
+            let outline = data.map(t => {
+                t.y = -t.y;
+                return t;
+            });
+            let sceneMark = new SceneMarkItem(null, outline);
             this.addItem(sceneMark);
             this.addItem(sceneMark);
             this.sceneMark = sceneMark;
             this.sceneMark = sceneMark;
         }
         }
@@ -132,6 +142,34 @@ export class DivideFloorScene extends FloorScene {
     } // Function clearSceneMark()
     } // Function clearSceneMark()
 
 
     /**
     /**
+     * 添加所有遮罩层
+     *
+     * @param   data    遮罩数据
+     */
+    addAllShade(data: SPoint[][]) {
+        if (data.length) {
+            data.map(t => {
+                this.addShade(t);
+            });
+        }
+    } // Function addAllShade()
+
+    /**
+     * 添加单个遮罩
+     *
+     * @param   data    遮罩数据
+     */
+    addShade(data: SPoint[]) {
+        let outLine = data.map(t => {
+            t.y = -t.y;
+            return t;
+        });
+        let item = new ShadeItem(null, outLine);
+        this.shadeList.push(item);
+        this.addItem(item);
+    } // Function addShade()
+
+    /**
      * 鼠标按下事件
      * 鼠标按下事件
      *
      *
      * @param   event   保存事件参数
      * @param   event   保存事件参数
@@ -183,6 +221,7 @@ export class DivideFloorScene extends FloorScene {
     onMouseUp(event: SMouseEvent): boolean {
     onMouseUp(event: SMouseEvent): boolean {
         if (this.rectSelectItem) {
         if (this.rectSelectItem) {
             this.isRectSelection = false;
             this.isRectSelection = false;
+            this.getIntersect();
             this.removeItem(this.rectSelectItem);
             this.removeItem(this.rectSelectItem);
             this.rectSelectItem = null;
             this.rectSelectItem = null;
         }
         }
@@ -208,7 +247,7 @@ export class DivideFloorScene extends FloorScene {
     } // Function onMouseMove
     } // Function onMouseMove
 
 
     /***
     /***
-     * 键盘按下事件
+     * 键盘弹起事件
      *
      *
      * @param      event   保存事件参数
      * @param      event   保存事件参数
      */
      */
@@ -422,4 +461,53 @@ export class DivideFloorScene extends FloorScene {
     } // Function absorbLine
     } // Function absorbLine
 
 
     /** */
     /** */
+    getIntersect(): void {
+        if (this.sceneMark) {
+            let poly2 = {
+                regions: [
+                    // [
+                    //     [
+                    //         this.rectSelectItem.startPoint.x,
+                    //         this.rectSelectItem.startPoint.y
+                    //     ],
+                    //     [
+                    //         this.rectSelectItem.startPoint.x,
+                    //         this.rectSelectItem.endPoint.y
+                    //     ],
+                    //     [
+                    //         this.rectSelectItem.endPoint.x,
+                    //         this.rectSelectItem.endPoint.y
+                    //     ],
+                    //     [
+                    //         this.rectSelectItem.endPoint.x,
+                    //         this.rectSelectItem.startPoint.y
+                    //     ]
+                    // ]
+                ],
+                inverted: false
+            };
+            poly2.regions.push(
+                // @ts-ignore
+                SMathUtil.transferToArray(this.sceneMark.outLine)
+            );
+            console.log(poly2);
+            this.spaceList.map(t => {
+                let poly1 = {
+                    regions: [],
+                    inverted: false
+                };
+                // @ts-ignore
+                poly1.regions = t.pointArr.map(item => {
+                    return SMathUtil.transferToArray(item);
+                });
+                console.log(poly1);
+                let intersectObj = intersect(poly1, poly2);
+                if (intersectObj.regions.length) {
+                    t.selected = true;
+                } else {
+                    t.selected = false;
+                }
+            });
+        }
+    }
 } // Class DivideFloorScene
 } // Class DivideFloorScene

+ 0 - 27
src/FloorScene.ts

@@ -35,7 +35,6 @@ import { ColumnItem } from "./items/ColumnItem";
 import { VirtualWallItem } from "./items/VirtualWallItem";
 import { VirtualWallItem } from "./items/VirtualWallItem";
 import { DoorItem } from "./items/DoorItem";
 import { DoorItem } from "./items/DoorItem";
 import { WindowItem } from "./items/WindowItem";
 import { WindowItem } from "./items/WindowItem";
-import { SPoint } from "@saga-web/draw/lib";
 
 
 /**
 /**
  * 楼层场景
  * 楼层场景
@@ -380,32 +379,6 @@ export class FloorScene extends SGraphyScene {
     } // Function addCasement
     } // Function addCasement
 
 
     /**
     /**
-     *  扩大数组中相应字段一定倍数
-     *
-     *  @param  arr     itemList
-     *  @param  k       倍数
-     *  @param  name    字段key值
-     */
-    changeMap(arr: any, k: any, name: any) {
-        let data = arr.map((items: any) => {
-            if (items[name] && items[name].length) {
-                items[name].map((children: any) => {
-                    if (Array.isArray(children)) {
-                        return children.map(res => {
-                            res.Y = res.Y * k;
-                            return res;
-                        });
-                    } else {
-                        children.Y = children.Y * k;
-                        return children;
-                    }
-                });
-            }
-        });
-        return data;
-    } // Function changeMap
-
-    /**
      *  解压文件
      *  解压文件
      *
      *
      *  @param  b64Data    base64数据
      *  @param  b64Data    base64数据

+ 1 - 0
src/items/RectSelectItem.ts

@@ -34,6 +34,7 @@ export class RectSelectItem extends SGraphyItem {
     startPoint: SPoint = new SPoint();
     startPoint: SPoint = new SPoint();
     /** 终点  */
     /** 终点  */
     endPoint: SPoint = new SPoint();
     endPoint: SPoint = new SPoint();
+    /** 轮廓线 */
 
 
     /**
     /**
      * 构造函数
      * 构造函数

+ 85 - 0
src/items/ShadeItem.ts

@@ -0,0 +1,85 @@
+// eslint-disable-next-line max-len
+/* * ********************************************************************************************************************
+ *
+ *                      :*$@@%$*:                         ;:                ;;    ;;
+ *                    :@@%!  :!@@%:                       %!             ;%%@@%$ =@@@@@@@%;     @%@@@%%%%@@@@@
+ *                   :@%;       :$=                       %%$$$%$$         ;$$  ;$@=   !@$
+ *                   =@!                                  %!              @ $=;%   !@@@%:      !$$$$$$$$$$$$$$=
+ *                   =@*                                  %!              @ $= % %@=   =%@!      %=
+ *              *$%%! @@=        ;=$%%%$*:                %!              @ $= % =%%%%%%@$      *%:         =%
+ *            %@@!:    !@@@%=$@@@@%!  :*@@$:              %!              @ $= % $*     ;@      @*          :%*
+ *          ;@@!          ;!!!;:         ;@%:      =======@%========*     @ $$ % $%*****$@     :@$=*********=@$
+ *          $@*   ;@@@%=!:                *@*
+ *          =@$    ;;;!=%@@@@=!           =@!
+ *           %@$:      =@%: :*@@@*       %@=                    Copyright (c) 2016-2019.  北京上格云技术有限公司
+ *            ;%@@$=$@@%*       *@@@$=%@@%;
+ *               ::;::             ::;::                                              All rights reserved.
+ *
+ * ********************************************************************************************************************
+ */
+
+import { Opt } from "../types/Opt";
+import { SGraphyItem } from "@saga-web/graphy/lib";
+import { SColor, SPainter, SPoint, SPolygonUtil } from "@saga-web/draw/lib";
+import { SMouseEvent } from "@saga-web/base/lib";
+import { ItemOrder } from "../types/ItemOrder";
+
+/**
+ * 遮罩item
+ *
+ * @author  郝建龙
+ */
+export class ShadeItem extends SGraphyItem {
+    /** 轮廓线坐标  */
+    outLine: SPoint[] = [];
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      遮罩数据
+     */
+    constructor(parent: SGraphyItem | null, data: SPoint[]) {
+        super(parent);
+        this.outLine = data;
+        this.zOrder = ItemOrder.shadeOrder;
+    } // Constructor
+
+    /**
+     * 判断点是否在区域内
+     *
+     * @param x
+     * @param y
+     */
+    contains(x: number, y: number): boolean {
+        let arr = this.outLine;
+        if (SPolygonUtil.pointIn(x, y, arr)) {
+            return true;
+        }
+        return false;
+    } // Function contains()
+
+    /**
+     * 鼠标点击事件
+     *
+     * @param	event         事件参数
+     * @return	boolean
+     */
+    onMouseDown(event: SMouseEvent): boolean {
+        this.$emit("mouseDown");
+        return true;
+    }
+
+    /**
+     * Item绘制操作
+     *
+     * @param   painter       painter对象
+     * @param   rect          绘制区域
+     */
+    onDraw(painter: SPainter): void {
+        painter.pen.color = SColor.Transparent;
+        painter.pen.lineWidth = 10;
+        painter.brush.color = Opt.sceneMarkColor;
+        painter.drawPolygon(this.outLine);
+    } // Function onDraw()
+} // Class SceneMarkItem

+ 23 - 6
src/items/SpaceItem.ts

@@ -21,6 +21,7 @@
 import { SGraphyItem } from "@saga-web/graphy/lib";
 import { SGraphyItem } from "@saga-web/graphy/lib";
 import {
 import {
     SColor,
     SColor,
+    SGradient,
     SPainter,
     SPainter,
     SPath2D,
     SPath2D,
     SPoint,
     SPoint,
@@ -41,7 +42,7 @@ export class SpaceItem extends SGraphyItem {
     /** 空间所有数据  */
     /** 空间所有数据  */
     data: Space;
     data: Space;
     /** 空间轮廓线坐标list  */
     /** 空间轮廓线坐标list  */
-    private readonly pointArr: SPoint[][] = [];
+    readonly pointArr: SPoint[][] = [];
     /** X坐标最小值  */
     /** X坐标最小值  */
     minX = 0;
     minX = 0;
     /** X坐标最大值  */
     /** X坐标最大值  */
@@ -50,10 +51,16 @@ export class SpaceItem extends SGraphyItem {
     minY = 0;
     minY = 0;
     /** Y坐标最大值  */
     /** Y坐标最大值  */
     maxY = 0;
     maxY = 0;
-    /** path对象     */
+    /** path对象      */
     private path = new SPath2D();
     private path = new SPath2D();
-    /** 选中时颜色   */
-    private selectColor = new SColor("#1abc9c");
+    /** 高亮状态    */
+    private _highLightFlag: boolean = false;
+    get highLightFlag(): boolean {
+        return this._highLightFlag;
+    } // Get highLightFlag
+    set highLightFlag(value: boolean) {
+        this._highLightFlag = value;
+    } // Set highLightFlag
     /**
     /**
      * 构造函数
      * 构造函数
      *
      *
@@ -122,6 +129,11 @@ export class SpaceItem extends SGraphyItem {
         return true;
         return true;
     } // Function onClick()
     } // Function onClick()
 
 
+    /**
+     * 鼠标移动事件
+     *
+     * @param event 事件参数
+     */
     onMouseMove(event: SMouseEvent): boolean {
     onMouseMove(event: SMouseEvent): boolean {
         return false;
         return false;
     }
     }
@@ -150,11 +162,16 @@ export class SpaceItem extends SGraphyItem {
      * Item绘制操作
      * Item绘制操作
      *
      *
      * @param   painter       painter对象
      * @param   painter       painter对象
-     * @param   rect          绘制区域
      */
      */
     onDraw(painter: SPainter): void {
     onDraw(painter: SPainter): void {
         painter.pen.color = SColor.Transparent;
         painter.pen.color = SColor.Transparent;
-        painter.brush.color = this.selected ? this.selectColor : Opt.spaceColor;
+        if (this.selected) {
+            painter.brush.color = Opt.selectColor;
+        } else if (this.highLightFlag) {
+            painter.brush.color = Opt.spaceHighColor;
+        } else {
+            painter.brush.color = Opt.spaceColor;
+        }
         painter.pen.lineWidth = 200;
         painter.pen.lineWidth = 200;
         painter.drawPath(this.path);
         painter.drawPath(this.path);
 
 

+ 8 - 6
src/types/ItemOrder.ts

@@ -27,19 +27,21 @@ export class ItemOrder {
     /** 空间层级 */
     /** 空间层级 */
     static spaceOrder = 2;
     static spaceOrder = 2;
     /** 业务空间层级 */
     /** 业务空间层级 */
-    static zoneOrder = 3;
+    static zoneOrder = 8;
     /** 柱子层级 */
     /** 柱子层级 */
-    static columnOrder = 4;
+    static columnOrder = 12;
     /** 墙层级 */
     /** 墙层级 */
-    static wallOrder = 5;
+    static wallOrder = 16;
     /** 虚拟墙层级 */
     /** 虚拟墙层级 */
-    static virtualWallOrder = 6;
+    static virtualWallOrder = 20;
     /** 门层级 */
     /** 门层级 */
-    static doorOrder = 7;
+    static doorOrder = 24;
     /** 窗户层级 */
     /** 窗户层级 */
-    static windowOrder = 8;
+    static windowOrder = 28;
     /** 位置标签对象层级 */
     /** 位置标签对象层级 */
     static markOrder = 99;
     static markOrder = 99;
+    /** 遮罩层级    */
+    static shadeOrder = 120;
     /** 框选矩形对象层级 */
     /** 框选矩形对象层级 */
     static rectSelectOrder = 999;
     static rectSelectOrder = 999;
     /** 高亮对象层级 */
     /** 高亮对象层级 */

+ 6 - 2
src/types/Opt.ts

@@ -44,8 +44,12 @@ export class Opt {
     static highLightPointColor = new SColor("#ff8d00");
     static highLightPointColor = new SColor("#ff8d00");
     /** 高亮item吸附线颜色    */
     /** 高亮item吸附线颜色    */
     static highLightLineColor = new SColor("#409EFF");
     static highLightLineColor = new SColor("#409EFF");
-    /** 矩形选择对象边框颜色    */
+    /** 矩形选择对象边框颜色  */
     static rectSelectOutColor = new SColor("#3e78f9e8");
     static rectSelectOutColor = new SColor("#3e78f9e8");
-    /** 矩形选择对象填充颜色    */
+    /** 矩形选择对象填充颜色  */
     static rectSelectInColor = new SColor("#8cf2fd73");
     static rectSelectInColor = new SColor("#8cf2fd73");
+    /** 空间,业务空间选中颜色 */
+    static selectColor = new SColor("#1abc9c");
+    /** 空间高亮颜色 */
+    static spaceHighColor = new SColor("#fbb029");
 } // Interface Opt
 } // Interface Opt

+ 147 - 1
src/utils/SMathUtil.ts

@@ -18,7 +18,7 @@
  * ********************************************************************************************************************
  * ********************************************************************************************************************
  */
  */
 
 
-import { SLine, SPoint, SRect } from "@saga-web/draw/lib";
+import { SLine, SPoint, SPolygonUtil, SRect } from "@saga-web/draw/lib";
 import { MinDis } from "../types/MinDis";
 import { MinDis } from "../types/MinDis";
 import { Point } from "../types/Point";
 import { Point } from "../types/Point";
 import { PointToLine } from "../types/PointToLine";
 import { PointToLine } from "../types/PointToLine";
@@ -164,4 +164,150 @@ export class SMathUtil {
             rect1.height + rect2.height > maxY - minY
             rect1.height + rect2.height > maxY - minY
         );
         );
     } // Function rectIntersection()
     } // 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[][] {
+        let Arr = SP.map(t => {
+            return [t.x, t.y];
+        });
+        return Arr;
+    } // Function transferToArray()
+
+    /**
+     * 转化数据格式为SPoint[]
+     *
+     * @param   arr number[][]
+     * @return  SP  SPoint[]
+     */
+    transferToSPoint(arr: number[][]): SPoint[] {
+        let Arr = arr.map(t => {
+            return new SPoint(t[0], t[1]);
+        });
+        return Arr;
+    } // Function transferToSPoint()
+
+    /**
+     * 计算多边形交集
+     *
+     * @param
+     */
+    getPolygonOutline() {
+        let arr = [
+            { x: 0, y: 0 },
+            { x: 100, y: 0 },
+            { x: 100, y: 100 },
+            { x: 0, y: 100 }
+        ];
+        arr = arr.map(t => {
+            return new SPoint(t.x, t.y);
+        });
+        let brr = [
+            { x: 50, y: 50 },
+            { x: 150, y: 50 },
+            { x: 150, y: 150 },
+            { x: 50, y: 150 }
+        ];
+        brr = brr.map(t => {
+            return new SPoint(t.x, t.y);
+        });
+        let arrIndex = 0,
+            brrIndex = 0,
+            ARRAY = [];
+        for (let i = 0; i < arr.length; i++) {
+            let firstLine = new SLine(
+                // @ts-ignore
+                arr[i],
+                arr[i + 1 == arr.length ? 0 : i + 1]
+            );
+            for (let j = 0; j < brr.length; j++) {
+                let secondLine = new SLine(
+                    // @ts-ignore
+                    brr[j],
+                    brr[j + 1 == brr.length ? 0 : j + 1]
+                );
+                let jiaodian = SMathUtil.lineIntersection(
+                    firstLine,
+                    secondLine
+                );
+                if (jiaodian) {
+                    arrIndex = i;
+                    brrIndex = j;
+                    ARRAY.push(jiaodian);
+                    break;
+                }
+            }
+        }
+        // @ts-ignore
+        if (SPolygonUtil.pointIn(brr[brrIndex].x, brr[brrIndex].y, arr)) {
+            ARRAY.push(brr[brrIndex]);
+            for (let k = brrIndex - 1; k > 0; k--) {
+                // @ts-ignore
+                if (SPolygonUtil.pointIn(brr[k].x, brr[k].y, arr)) {
+                    ARRAY.push(brr[k]);
+                    continue;
+                }
+
+                let firstLine = new SLine(
+                    // @ts-ignore
+                    brr[k],
+                    brr[k == 0 ? brr.length - 1 : k - 1]
+                );
+
+                for (let q = 0; q < arr.length; q++) {
+                    let secondLine = new SLine(
+                        // @ts-ignore
+                        arr[q],
+                        arr[q + 1 == arr.length ? 0 : q + 1]
+                    );
+                    let jiaodian = SMathUtil.lineIntersection(
+                        firstLine,
+                        secondLine
+                    );
+                    if (jiaodian) {
+                        arrIndex = q;
+                        brrIndex = k;
+                        ARRAY.push(jiaodian);
+                    }
+                }
+            }
+        } else {
+            ARRAY.push(brr[brrIndex + 1 == brr.length ? 0 : brrIndex + 1]);
+        }
+    } // Function getPolygonOutline()
 } // Class SMathUtil
 } // Class SMathUtil