| | |
| | | const grayRects = glassDetails.filter(r => r.isRemain);
|
| | | const nonGrayRects = glassDetails.filter(r => !r.isRemain);
|
| | |
|
| | | // 按坐标排序,优先按x坐标,其次按y坐标
|
| | | // 按坐标排序,优先按y坐标,其次按x坐标(这样更符合从上到下、从左到右的阅读习惯)
|
| | | grayRects.sort((a, b) => {
|
| | | if (a.x !== b.x) return a.x - b.x;
|
| | | return a.y - b.y;
|
| | | if (a.y !== b.y) return a.y - b.y;
|
| | | return a.x - b.x;
|
| | | });
|
| | |
|
| | | if (grayRects.length === 0) return;
|
| | |
|
| | | const merged = [];
|
| | |
|
| | | // 从第一个矩形开始
|
| | | let current = { ...grayRects[0] };
|
| | |
|
| | | // 遍历所有余料矩形进行合并
|
| | |
| | | current = { ...next };
|
| | | }
|
| | | }
|
| | |
|
| | | // 添加最后一个矩形
|
| | | merged.push({
|
| | | x: Math.round(current.x),
|
| | | y: Math.round(current.y),
|
| | | width: Math.round(current.width),
|
| | | height: Math.round(current.height),
|
| | | isRemain: true
|
| | | });
|
| | |
|
| | | // 重新构建数组:非余料 + 合并后的余料
|
| | | glassDetails.splice(0, glassDetails.length, ...nonGrayRects, ...merged);
|
| | | };
|
| | |
| | | const newRemaining = [];
|
| | |
|
| | | remainingAreas.forEach(area => {
|
| | | // 如果障碍物与当前区域有重叠
|
| | | if (checkOverlap(area, obstacle)) {
|
| | | // 切分当前区域为最多4个新区域
|
| | | // 如果障碍物与当前区域没有重叠,保留原区域
|
| | | if (!checkOverlap(area, obstacle)) {
|
| | | newRemaining.push(area);
|
| | | return;
|
| | | }
|
| | |
|
| | | // 左侧区域
|
| | | if (obstacle.x > area.x) {
|
| | | // 计算重叠区域的边界
|
| | | const overlapLeft = Math.max(area.x, obstacle.x);
|
| | | const overlapRight = Math.min(area.x + area.width, obstacle.x + obstacle.width);
|
| | | const overlapTop = Math.max(area.y, obstacle.y);
|
| | | const overlapBottom = Math.min(area.y + area.height, obstacle.y + obstacle.height);
|
| | |
|
| | | // 生成四个可能的新区域(上、下、左、右)
|
| | |
|
| | | // 上方区域
|
| | | if (overlapTop > area.y) {
|
| | | newRemaining.push({
|
| | | x: area.x,
|
| | | y: area.y,
|
| | | width: obstacle.x - area.x,
|
| | | height: area.height
|
| | | width: area.width,
|
| | | height: overlapTop - area.y
|
| | | });
|
| | | }
|
| | |
|
| | | // 右侧区域
|
| | | if (obstacle.x + obstacle.width < area.x + area.width) {
|
| | | // 下方区域
|
| | | if (overlapBottom < area.y + area.height) {
|
| | | newRemaining.push({
|
| | | x: obstacle.x + obstacle.width,
|
| | | y: area.y,
|
| | | width: area.x + area.width - (obstacle.x + obstacle.width),
|
| | | height: area.height
|
| | | x: area.x,
|
| | | y: overlapBottom,
|
| | | width: area.width,
|
| | | height: area.y + area.height - overlapBottom
|
| | | });
|
| | | }
|
| | |
|
| | | // 上方区域(仅在障碍物左右边界之间的区域)
|
| | | if (obstacle.y > area.y) {
|
| | | const startX = Math.max(area.x, obstacle.x);
|
| | | const endX = Math.min(area.x + area.width, obstacle.x + obstacle.width);
|
| | | if (endX > startX) {
|
| | | // 左方区域(仅在重叠区域的垂直范围内)
|
| | | if (overlapLeft > area.x) {
|
| | | const regionTop = overlapTop;
|
| | | const regionBottom = overlapBottom;
|
| | | newRemaining.push({
|
| | | x: startX,
|
| | | y: area.y,
|
| | | width: endX - startX,
|
| | | height: obstacle.y - area.y
|
| | | x: area.x,
|
| | | y: regionTop,
|
| | | width: overlapLeft - area.x,
|
| | | height: regionBottom - regionTop
|
| | | });
|
| | | }
|
| | | }
|
| | |
|
| | | // 下方区域(仅在障碍物左右边界之间的区域)
|
| | | if (obstacle.y + obstacle.height < area.y + area.height) {
|
| | | const startX = Math.max(area.x, obstacle.x);
|
| | | const endX = Math.min(area.x + area.width, obstacle.x + obstacle.width);
|
| | | if (endX > startX) {
|
| | | // 右方区域(仅在重叠区域的垂直范围内)
|
| | | if (overlapRight < area.x + area.width) {
|
| | | const regionTop = overlapTop;
|
| | | const regionBottom = overlapBottom;
|
| | | newRemaining.push({
|
| | | x: startX,
|
| | | y: obstacle.y + obstacle.height,
|
| | | width: endX - startX,
|
| | | height: area.y + area.height - (obstacle.y + obstacle.height)
|
| | | x: overlapRight,
|
| | | y: regionTop,
|
| | | width: area.x + area.width - overlapRight,
|
| | | height: regionBottom - regionTop
|
| | | });
|
| | | }
|
| | | }
|
| | | } else {
|
| | | // 没有重叠,保留原区域
|
| | | newRemaining.push(area);
|
| | | }
|
| | | });
|
| | |
|