瀏覽代碼

添加边界判断 修改蒙版画法 实现重载

haojianlong 5 年之前
父節點
當前提交
8dc09d9daa

+ 4 - 4
package-lock.json

@@ -1,6 +1,6 @@
 {
     "name": "cad-engine",
-    "version": "2.0.151",
+    "version": "2.0.191",
     "lockfileVersion": 1,
     "requires": true,
     "dependencies": {
@@ -30,9 +30,9 @@
             "integrity": "sha512-sBFWAn/cqOT9P4r+CSgj381QbLp9XavDkKNRRm9iQZbMv2+/AkYcXcmDhI7wJIJNwz8kR6wjRvMBeUEpFIvqnA=="
         },
         "@sybotan-web/draw": {
-            "version": "2.1.39",
-            "resolved": "http://dev.dp.sagacloud.cn:8082/repository/npm-saga/@sybotan-web/draw/-/draw-2.1.39.tgz",
-            "integrity": "sha512-P7HMsYKM3dNITIpZPUJPkeH9Vsor2v/Yt+cMyUdpqKj3brZRk+8yadBtTlxCzkWc6CU3wZVD66xwENGbae4J3A==",
+            "version": "2.1.47",
+            "resolved": "http://dev.dp.sagacloud.cn:8082/repository/npm-saga/@sybotan-web/draw/-/draw-2.1.47.tgz",
+            "integrity": "sha512-YnSczTJg2pNmGTHqkfC6LXdZiNavHUhFjfi2sYDqWpNcKQPTBmG9p9Rkf0ldyi2HvShAID/H0eSCOQB6UpmxSA==",
             "requires": {
                 "@sybotan-web/base": "^2.1.2"
             }

+ 2 - 2
package.json

@@ -1,6 +1,6 @@
 {
     "name": "cad-engine",
-    "version": "2.0.174",
+    "version": "2.0.196",
     "description": "上格云 CAD图形引擎。",
     "main": "lib/index.js",
     "types": "lib/index.d.js",
@@ -32,7 +32,7 @@
     },
     "dependencies": {
         "@sybotan-web/base": "2.1.2",
-        "@sybotan-web/draw": "2.1.39",
+        "@sybotan-web/draw": "2.1.47",
         "@sybotan-web/graphy": "2.1.13",
         "axios": "^0.18.0",
         "pako": "^1.0.10"

+ 1 - 1
src/FloorScene.ts

@@ -318,7 +318,7 @@ export class FloorScene extends SGraphyScene {
      */
     addDoor(door: Door): void {
         let item = new DoorItem(null, door);
-        item.zOrder = 1;
+        item.zOrder = 99;
         item.visible = this.isShowDoor;
         this.doorList.push(item);
         this.addItem(item);

+ 13 - 0
src/divideFloorScene.ts

@@ -51,6 +51,19 @@ export class DivideFloorScene extends FloorScene {
     } // Constructor
 
     /**
+     * 添加轮廓线
+     *
+     * @param   data
+     */
+    addSceneMark(data: SPoint[]): void {
+        if (data.length) {
+            let sceneMark = new SceneMarkItem(null, data);
+            this.addItem(sceneMark);
+            this.grabItem = sceneMark;
+        }
+    } // Function addSceneMark
+
+    /**
      * 清除蒙版
      *
      */

+ 51 - 5
src/items/ColumnItem.ts

@@ -31,8 +31,16 @@ import { Opt } from "../types/Opt";
 export class ColumnItem extends SGraphyItem {
     /** 柱子数据    */
     data: Column;
+    /** X坐标最小值  */
+    private minX = 0;
+    /** X坐标最大值  */
+    private maxX = 0;
+    /** Y坐标最小值  */
+    private minY = 0;
+    /** Y坐标最大值  */
+    private maxY = 0;
     /** 柱子轮廓线坐标list  */
-    private readonly pointArr: SPoint[] = [];
+    private readonly pointArr: SPoint[][] = [];
 
     /**
      * 构造函数
@@ -43,14 +51,50 @@ export class ColumnItem extends SGraphyItem {
     constructor(parent: SGraphyItem | null, data: Column) {
         super(parent);
         this.data = data;
-        if (this.data.OutLine.length) {
-            this.pointArr = this.data.OutLine[0].map(t => {
-                return new SPoint(t.X, -t.Y);
+        let tempArr = this.data.OutLine;
+        if (tempArr && tempArr.length) {
+            this.minX = tempArr[0][0].X;
+            this.maxX = this.minX;
+            this.minY = -tempArr[0][0].Y;
+            this.maxY = this.minY;
+            this.pointArr = tempArr.map(t => {
+                let temp = t.map(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;
+                    }
+                    return new SPoint(x, y);
+                });
+                return temp;
             });
         }
     } // Constructor
 
     /**
+     * Item对象边界区域
+     *
+     * @return SRect
+     */
+    boundingRect(): SRect {
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
+    } // Function boundingRect()
+
+    /**
      * Item绘制操作
      *
      * @param   painter       painter对象
@@ -61,7 +105,9 @@ export class ColumnItem extends SGraphyItem {
             painter.pen.color = Opt.columnColor;
             painter.pen.lineWidth = 10;
             painter.brush.color = Opt.columnColor;
-            painter.drawPolygon(this.pointArr);
+            this.pointArr.map(t => {
+                painter.drawPolygon(t);
+            });
         }
     } // Function onDraw()
 } // Class ColumnItem

+ 8 - 8
src/items/DoorItem.ts

@@ -142,14 +142,14 @@ export class DoorItem extends SGraphyItem {
             painter.drawLine(0, 0, this.r, 0);
 
             painter.pen.lineDash = [50, 100];
-            painter.drawArc(
-                -this.r,
-                -this.r,
-                this.r * 2,
-                this.r * 2,
-                this.startAng,
-                this.endAng
-            );
+            // painter.drawArc(
+            //     -this.r,
+            //     -this.r,
+            //     this.r * 2,
+            //     this.r * 2,
+            //     this.startAng,
+            //     this.endAng
+            // );
         }
     } // Function onDraw()
 } // Class DoorItem

+ 33 - 28
src/items/SceneMarkItem.ts

@@ -24,8 +24,10 @@ import {
     SPainter,
     SPath2D,
     SPoint,
+    SPolygonUtil,
     SRect
 } from "@sybotan-web/draw/lib";
+import { Opt } from "../types/Opt";
 
 /**
  * 蒙版item
@@ -48,10 +50,31 @@ export class SceneMarkItem extends SGraphyItem {
      * @param parent    指向父对象
      * @param data      蒙版起点数据
      */
-    constructor(parent: SGraphyItem | null, data: SPoint) {
+    constructor(parent: SGraphyItem | null, data: SPoint); // Constructor
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      蒙版轮廓线数据
+     */
+    constructor(parent: SGraphyItem | null, data: SPoint[]); // Constructor
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      蒙版起点数据 | 蒙版轮廓线数据
+     */
+    constructor(parent: SGraphyItem | null, data: SPoint[] | SPoint) {
         super(parent);
-        this.outLine.push(data);
-        this.lastPoint = data;
+        if (data instanceof Array) {
+            this.outLine = data;
+            this.createMask();
+        } else {
+            this.outLine.push(data);
+            this.lastPoint = data;
+        }
         this.zOrder = Number.MAX_SAFE_INTEGER;
     } // Constructor
 
@@ -62,7 +85,6 @@ export class SceneMarkItem extends SGraphyItem {
      * @return	boolean
      */
     onMouseDown(event: SMouseEvent): boolean {
-        console.log(arguments);
         if (!this.closeFlag && event.buttons == 1) {
             let p = new SPoint(event.x, event.y);
             this.lastPoint.x = p.x;
@@ -81,6 +103,7 @@ export class SceneMarkItem extends SGraphyItem {
     onMouseMove(event: SMouseEvent): boolean {
         if (!this.closeFlag) {
             this.lastPoint = new SPoint(event.x, event.y);
+            console.log(this.lastPoint);
         }
         return true;
     } // Function onMouseMove()
@@ -109,34 +132,15 @@ export class SceneMarkItem extends SGraphyItem {
         this.mask.lineTo(Number.MIN_SAFE_INTEGER, Number.MAX_SAFE_INTEGER);
         this.mask.lineTo(Number.MIN_SAFE_INTEGER, Number.MIN_SAFE_INTEGER);
 
-        let antiArr = this.outLine;
-        if (this.isAntiClockWise(this.outLine)) {
-            antiArr = this.outLine.reverse();
+        let antiArr = this.outLine.concat([]);
+        // (计算基于数学坐标系统,在绘图坐标系由于y轴方向相反结果也要取反)
+        if (SPolygonUtil.clockDir(antiArr) > 0) {
+            antiArr = antiArr.reverse();
         }
         this.mask.polygon(antiArr);
     } // Function createMask()
 
     /**
-     * 判断多边形点是否逆时针排列
-     *
-     * @param   pArr    点数组
-     * @return  boolean 是-true 否-false
-     */
-    private isAntiClockWise(pArr: SPoint[]): boolean {
-        let newArr = pArr.concat([]);
-        let rightPoint = newArr[0],
-            index = 0;
-        for (let i = 1; i < newArr.length; i++) {
-            if (newArr[i].x > rightPoint.x) {
-                index = i;
-                rightPoint = newArr[i];
-            }
-        }
-        index = index == 0 ? newArr.length - 1 : index - 1;
-        return rightPoint.y > newArr[index].y;
-    } // Function isAntiClockWise
-
-    /**
      * Item绘制操作
      *
      * @param   painter       painter对象
@@ -145,10 +149,11 @@ export class SceneMarkItem extends SGraphyItem {
     onDraw(painter: SPainter, rect?: SRect): void {
         if (this.closeFlag) {
             painter.pen.color = SColor.Transparent;
-            painter.brush.color = new SColor("#FFFF0080");
+            painter.brush.color = Opt.sceneMarkColor;
             painter.drawPath(this.mask);
         } else {
             painter.pen.color = new SColor("#ff0000");
+            painter.pen.lineWidth = painter.toPx(5);
             painter.drawPolyline(this.outLine);
             painter.drawLine(
                 this.outLine[this.outLine.length - 1],

+ 50 - 62
src/items/SpaceItem.ts

@@ -24,6 +24,7 @@ import {
     SPainter,
     SPath2D,
     SPoint,
+    SPolygonUtil,
     SRect
 } from "@sybotan-web/draw/lib";
 import { Space } from "../types/Space";
@@ -60,31 +61,33 @@ export class SpaceItem extends SGraphyItem {
         super(parent);
         this.data = data;
         let tempArr = this.data.OutLine;
-        this.minX = tempArr[0][0].X;
-        this.maxX = this.minX;
-        this.minY = -tempArr[0][0].Y;
-        this.maxY = this.minY;
-        this.pointArr = tempArr.map(t => {
-            let temp = t.map(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;
-                }
-                return new SPoint(x, y);
+        if (tempArr && tempArr.length) {
+            this.minX = tempArr[0][0].X;
+            this.maxX = this.minX;
+            this.minY = -tempArr[0][0].Y;
+            this.maxY = this.minY;
+            this.pointArr = tempArr.map(t => {
+                let temp = t.map(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;
+                    }
+                    return new SPoint(x, y);
+                });
+                this.path.polygon(temp);
+                return temp;
             });
-            this.path.addPolygon(temp);
-            return temp;
-        });
+        }
     } // Constructor
 
     /**
@@ -108,40 +111,19 @@ export class SpaceItem extends SGraphyItem {
      * @param y
      */
     contains(x: number, y: number): boolean {
-        if (this.data.OutLine.length) {
-            let nCross = 0,
-                point = [x, y],
-                APoints = this.data.OutLine[0],
-                length = APoints.length,
-                p1,
-                p2,
-                i,
-                xinters;
-            p1 = APoints[0];
-            for (i = 1; i <= length; i++) {
-                p2 = APoints[i % length];
-                if (
-                    point[0] > Math.min(p1.X, p2.X) &&
-                    point[0] <= Math.max(p1.X, p2.X)
-                ) {
-                    if (point[1] <= Math.max(p1.Y, p2.Y)) {
-                        if (p1.X != p2.X) {
-                            //计算位置信息
-                            xinters =
-                                ((point[0] - p1.X) * (p2.Y - p1.Y)) /
-                                    (p2.X - p1.X) +
-                                p1.Y;
-                            if (p1.Y == p2.Y || point[1] <= xinters) {
-                                nCross++;
-                            }
-                        }
-                    }
-                }
-                p1 = p2;
+        let arr = this.pointArr;
+        if (arr.length < 1 || !SPolygonUtil.pointIn(x, y, arr[0])) {
+            return false;
+        }
+        if (arr.length == 1) {
+            return true;
+        }
+        for (let i = 1; i < arr.length; i++) {
+            if (SPolygonUtil.pointIn(x, y, arr[i])) {
+                return false;
             }
-            return nCross % 2 === 1;
         }
-        return false;
+        return true;
     } // Function contains()
 
     /**
@@ -151,11 +133,17 @@ export class SpaceItem extends SGraphyItem {
      * @param   rect          绘制区域
      */
     onDraw(painter: SPainter, rect?: SRect): void {
-        if (this.visible) {
-            painter.pen.color = SColor.Transparent;
-            painter.brush.color = Opt.spaceColor;
-            painter.pen.lineWidth = 200;
-            painter.drawPath(this.path);
-        }
+        painter.pen.color = SColor.Transparent;
+        painter.brush.color = Opt.spaceColor;
+        painter.pen.lineWidth = 200;
+        painter.drawPath(this.path);
+
+        painter.brush.color = SColor.Black;
+        painter.font.size = painter.toPx(10);
+        painter.drawText(
+            this.data.Name,
+            this.data.Location.Points[0].X,
+            -this.data.Location.Points[0].Y
+        );
     } // Function onDraw()
 } // Class SpaceItem

+ 51 - 5
src/items/VirtualWallItem.ts

@@ -31,8 +31,16 @@ import { Opt } from "../types/Opt";
 export class VirtualWallItem extends SGraphyItem {
     /** 虚拟墙数据   */
     data: VirtualWall;
+    /** X坐标最小值  */
+    private minX = 0;
+    /** X坐标最大值  */
+    private maxX = 0;
+    /** Y坐标最小值  */
+    private minY = 0;
+    /** Y坐标最大值  */
+    private maxY = 0;
     /** 虚拟墙轮廓线坐标list  */
-    private readonly pointArr: SPoint[] = [];
+    private readonly pointArr: SPoint[][] = [];
 
     /**
      * 构造函数
@@ -43,14 +51,50 @@ export class VirtualWallItem extends SGraphyItem {
     constructor(parent: SGraphyItem | null, data: VirtualWall) {
         super(parent);
         this.data = data;
-        if (this.data.OutLine.length) {
-            this.pointArr = this.data.OutLine[0].map(t => {
-                return new SPoint(t.X, -t.Y);
+        let tempArr = this.data.OutLine;
+        if (tempArr && tempArr.length) {
+            this.minX = tempArr[0][0].X;
+            this.maxX = this.minX;
+            this.minY = -tempArr[0][0].Y;
+            this.maxY = this.minY;
+            this.pointArr = tempArr.map(t => {
+                let temp = t.map(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;
+                    }
+                    return new SPoint(x, y);
+                });
+                return temp;
             });
         }
     } // Constructor
 
     /**
+     * Item对象边界区域
+     *
+     * @return SRect
+     */
+    boundingRect(): SRect {
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
+    } // Function boundingRect()
+
+    /**
      * Item绘制操作
      *
      * @param   painter       painter对象
@@ -61,7 +105,9 @@ export class VirtualWallItem extends SGraphyItem {
             painter.pen.lineWidth = 100;
             painter.pen.color = Opt.virtualWallColor;
             painter.pen.lineDash = [200, 200];
-            painter.drawPolyline(this.pointArr);
+            this.pointArr.map(t => {
+                painter.drawPolyline(t);
+            });
         }
     } // Function onDraw()
 } // Class VirtualWall

+ 46 - 6
src/items/WallItem.ts

@@ -22,7 +22,6 @@ import { SGraphyItem, SMouseEvent } from "@sybotan-web/graphy/lib";
 import { SColor, SPainter, SPoint, SRect } from "@sybotan-web/draw/lib";
 import { Wall } from "../types/Wall";
 import { Opt } from "../types/Opt";
-import {Point} from "../types/Point";
 
 /**
  * 墙item
@@ -32,6 +31,14 @@ import {Point} from "../types/Point";
 export class WallItem extends SGraphyItem {
     /** 墙数据 */
     data: Wall;
+    /** X坐标最小值  */
+    private minX = 0;
+    /** X坐标最大值  */
+    private maxX = 0;
+    /** Y坐标最小值  */
+    private minY = 0;
+    /** Y坐标最大值  */
+    private maxY = 0;
     /** 墙轮廓线坐标list  */
     private readonly pointArr: SPoint[][] = [];
 
@@ -44,17 +51,50 @@ export class WallItem extends SGraphyItem {
     constructor(parent: SGraphyItem | null, data: Wall) {
         super(parent);
         this.data = data;
-        if (this.data.OutLine.length) {
-            this.pointArr = this.data.OutLine.map(t => {
-                let tempArr = t.map(it => {
-                    return new SPoint(it.X, -it.Y);
+        let tempArr = this.data.OutLine;
+        if (tempArr && tempArr.length) {
+            this.minX = tempArr[0][0].X;
+            this.maxX = this.minX;
+            this.minY = -tempArr[0][0].Y;
+            this.maxY = this.minY;
+            this.pointArr = tempArr.map(t => {
+                let temp = t.map(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;
+                    }
+                    return new SPoint(x, y);
                 });
-                return tempArr;
+                return temp;
             });
         }
     } // Constructor
 
     /**
+     * Item对象边界区域
+     *
+     * @return SRect
+     */
+    boundingRect(): SRect {
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
+    } // Function boundingRect()
+
+    /**
      * Item绘制操作
      *
      * @param   painter       painter对象

+ 1 - 2
src/items/ZoneItem.ts

@@ -26,7 +26,6 @@ import {
     SPoint,
     SRect
 } from "@sybotan-web/draw/lib";
-import { Space } from "../types/Space";
 import { Opt } from "../types/Opt";
 import { Zone } from "../types/Zone";
 
@@ -87,7 +86,7 @@ export class ZoneItem extends SGraphyItem {
                         }
                         return new SPoint(x, y);
                     });
-                    spath.addPolygon(array);
+                    spath.polygon(array);
                     return array;
                 });
                 this.pathList.push(spath);

+ 3 - 1
src/types/Opt.ts

@@ -33,9 +33,11 @@ export class Opt {
     /** 虚拟墙颜色 */
     static virtualWallColor = SColor.Black;
     /** 空间颜色 */
-    static spaceColor = new SColor("#f1fffd");
+    static spaceColor = new SColor("#f1fffd80");
     /** 门颜色 */
     static doorColor = new SColor("#f5b36f");
     /** 窗户颜色 */
     static windowColor = new SColor("#fcd6ff");
+    /** 蒙版颜色    */
+    static sceneMarkColor = new SColor("#00000080");
 } // Interface Opt