class Rectangle extends egret.Rectangle { /** * 获取矩形的最大点,即右下角 */ public get max() { return new Vector2(this.right, this.bottom); } /** 中心点坐标 */ public get center() { return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2)); } /** 左上角的坐标 */ public get location() { return new Vector2(this.x, this.y); } /** 左上角的坐标 */ public set location(value: Vector2) { this.x = value.x; this.y = value.y; } public get size() { return new Vector2(this.width, this.height); } public set size(value: Vector2) { this.width = value.x; this.height = value.y; } /** * 是否与另一个矩形相交 * @param value */ public intersects(value: egret.Rectangle) { return value.left < this.right && this.left < value.right && value.top < this.bottom && this.top < value.bottom; } /** * 判断点是否在矩形内 * @param value */ public containsInVec(value: Vector2) { return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && (this.y <= value.y)) && (value.y < (this.y + this.height))); } /** * 获取所提供的矩形是否在此矩形的边界内 * @param value */ public containsRect(value: Rectangle) { return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && (this.y <= value.y)) && (value.y < (this.y + this.height))); } public getHalfSize() { return new Vector2(this.width * 0.5, this.height * 0.5); } /** * 创建一个矩形的最小/最大点(左上角,右下角的点) * @param minX * @param minY * @param maxX * @param maxY */ public static fromMinMax(minX: number, minY: number, maxX: number, maxY: number) { return new Rectangle(minX, minY, maxX - minX, maxY - minY); } /** * 获取矩形边界上与给定点最近的点 * @param point */ public getClosestPointOnRectangleBorderToPoint(point: Vector2): { res: Vector2, edgeNormal: Vector2 } { let edgeNormal = Vector2.zero; // 对于每个轴,如果点在盒子外面 let res = new Vector2(); res.x = MathHelper.clamp(point.x, this.left, this.right); res.y = MathHelper.clamp(point.y, this.top, this.bottom); // 如果点在矩形内,我们需要推res到边界,因为它将在矩形内 if (this.containsInVec(res)) { let dl = res.x - this.left; let dr = this.right - res.x; let dt = res.y - this.top; let db = this.bottom - res.y; let min = Math.min(dl, dr, dt, db); if (min == dt) { res.y = this.top; edgeNormal.y = -1; } else if (min == db) { res.y = this.bottom; edgeNormal.y = 1; } else if (min == dl) { res.x = this.left; edgeNormal.x = -1; } else { res.x = this.right; edgeNormal.x = 1; } } else { if (res.x == this.left) edgeNormal.x = -1; if (res.x == this.right) edgeNormal.x = 1; if (res.y == this.top) edgeNormal.y = -1; if (res.y == this.bottom) edgeNormal.y = 1; } return { res: res, edgeNormal: edgeNormal }; } /** * */ public getClosestPointOnBoundsToOrigin() { let max = this.max; let minDist = Math.abs(this.location.x); let boundsPoint = new Vector2(this.location.x, 0); if (Math.abs(max.x) < minDist) { minDist = Math.abs(max.x); boundsPoint.x = max.x; boundsPoint.y = 0; } if (Math.abs(max.y) < minDist) { minDist = Math.abs(max.y); boundsPoint.x = 0; boundsPoint.y = max.y; } if (Math.abs(this.location.y) < minDist) { minDist = Math.abs(this.location.y); boundsPoint.x = 0; boundsPoint.y = this.location.y; } return boundsPoint; } /** * 给定多边形的点,计算边界 * @param points */ public static rectEncompassingPoints(points: Vector2[]) { // 我们需要求出x/y的最小值/最大值 let minX = Number.POSITIVE_INFINITY; let minY = Number.POSITIVE_INFINITY; let maxX = Number.NEGATIVE_INFINITY; let maxY = Number.NEGATIVE_INFINITY; for (let i = 0; i < points.length; i++) { let pt = points[i]; if (pt.x < minX) minX = pt.x; if (pt.x > maxX) maxX = pt.x; if (pt.y < minY) minY = pt.y; if (pt.y > maxY) maxY = pt.y; } return this.fromMinMax(minX, minY, maxX, maxY); } }