|
@@ -0,0 +1,115 @@
|
|
|
+
|
|
|
+import { SGraphyItem } from '@sybotan-web/graphy'
|
|
|
+import { SRect, SSize, SPoint } from "@sybotan-web/base";
|
|
|
+import { SPen, SPainter, SColor } from "@sybotan-web/draw";
|
|
|
+
|
|
|
+/**
|
|
|
+ * 不规则多边形Item类
|
|
|
+ *
|
|
|
+ */
|
|
|
+export class SGraphyPolygonItem extends SGraphyItem {
|
|
|
+ pointArr: SPoint[];
|
|
|
+ color: SColor = SColor.Black;
|
|
|
+ width: number = 1;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构造函数
|
|
|
+ *
|
|
|
+ * @param pointArr 点坐标list
|
|
|
+ * @param width 线的宽度
|
|
|
+ *
|
|
|
+ * @param color 线的颜色
|
|
|
+ * @param parent
|
|
|
+ */
|
|
|
+ constructor(
|
|
|
+ parent: SGraphyItem | null,
|
|
|
+ pointArr: SPoint[],
|
|
|
+ color: SColor = SColor.Black,
|
|
|
+ width: number = 1
|
|
|
+ ) {
|
|
|
+ super(parent);
|
|
|
+ this.pointArr = pointArr;
|
|
|
+ this.color = color;
|
|
|
+ this.width = width;
|
|
|
+ } // Constructor()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Item对象边界区域
|
|
|
+ *
|
|
|
+ * @return SRect
|
|
|
+ */
|
|
|
+ boundingRect(): SRect {
|
|
|
+ let minX = this.pointArr[0].x;
|
|
|
+ let maxX = minX;
|
|
|
+ let minY = this.pointArr[0].y;
|
|
|
+ let maxY = minY;
|
|
|
+ for (let i = 1; i < this.pointArr.length; i++) {
|
|
|
+ if (this.pointArr[i].x < minX) {
|
|
|
+ minX = this.pointArr[i].x
|
|
|
+ }
|
|
|
+ if (this.pointArr[i].y < minY) {
|
|
|
+ minY = this.pointArr[i].y
|
|
|
+ }
|
|
|
+ if (this.pointArr[i].x > maxX) {
|
|
|
+ maxX = this.pointArr[i].x
|
|
|
+ }
|
|
|
+ if (this.pointArr[i].y > maxY) {
|
|
|
+ maxY = this.pointArr[i].y
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return new SRect(
|
|
|
+ minX,
|
|
|
+ minY,
|
|
|
+ maxX - minX,
|
|
|
+ maxY - minY
|
|
|
+ );
|
|
|
+ } // Function boundingRect()
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断点是否在区域内
|
|
|
+ *
|
|
|
+ * @param x
|
|
|
+ * @param y
|
|
|
+ */
|
|
|
+ contains(x: number, y: number): boolean {
|
|
|
+ let nCross = 0,
|
|
|
+ point = [x, y],
|
|
|
+ APoints = this.pointArr,
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ console.log(nCross % 2 === 1)
|
|
|
+ return nCross % 2 === 1
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * Item绘制操作
|
|
|
+ *
|
|
|
+ * @param painter painter对象
|
|
|
+ * @param rect 绘制区域
|
|
|
+ */
|
|
|
+ onDraw(painter: SPainter, rect: SRect): void {
|
|
|
+ if (this.pointArr.length) {
|
|
|
+ painter.pen = new SPen(this.color, this.width);
|
|
|
+ painter.drawPolygon(this.pointArr)
|
|
|
+ }
|
|
|
+ }
|
|
|
+} // Class SGraphyPolygonItem
|