From 91e1d5b820bd39b6d6c97349facda304ec317606 Mon Sep 17 00:00:00 2001
From: 于杰 <1210123631@qq.com>
Date: 星期三, 13 八月 2025 09:29:58 +0800
Subject: [PATCH] 完善余料计算代码,修复余料部分重叠计算的问题
---
north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue | 227 ++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 147 insertions(+), 80 deletions(-)
diff --git a/north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue b/north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue
index c0ba000..03bd17c 100644
--- a/north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue
+++ b/north-glass-erp/northglass-erp/src/views/pp/glassOptimize/page/OptimizationRect.vue
@@ -648,11 +648,11 @@
adjustGrayRectangles(layoutIndex);
};
-const mergeAdjacentGrayRects = (glassDetails,totalWidth,totalHeight) => {
+const mergeAdjacentGrayRects = (glassDetails, totalWidth, totalHeight) => {
const grayRects = glassDetails.filter(r => r.isRemain);
- const grayRects2 = glassDetails.filter(r => r.isRemain);
- let merged = [];
+ const nonGrayRects = glassDetails.filter(r => !r.isRemain);
+ // 鎸夊潗鏍囨帓搴忥紝浼樺厛鎸墄鍧愭爣锛屽叾娆℃寜y鍧愭爣
grayRects.sort((a, b) => {
if (a.x !== b.x) return a.x - b.x;
return a.y - b.y;
@@ -660,30 +660,31 @@
if (grayRects.length === 0) return;
- merged.push({ ...grayRects[0] });
+ const merged = [];
+ // 浠庣涓�涓煩褰㈠紑濮�
+ let current = { ...grayRects[0] };
+
+ // 閬嶅巻鎵�鏈変綑鏂欑煩褰㈣繘琛屽悎骞�
for (let i = 1; i < grayRects.length; i++) {
- const last = merged[merged.length-1];
- const current = grayRects[i];
+ const next = grayRects[i];
-
- if (current.x === last.x + last.width &&
- current.y === last.y &&
- current.height === last.height) {
- last.width += current.width;
- last.x = Math.round(last.x);
- last.y = Math.round(last.y);
- last.width = Math.round(last.width);
- last.height = Math.round(last.height);
- } else if (current.y === last.y + last.height &&
- current.x === last.x &&
- current.width === last.width) {
- last.height += current.height;
- last.x = Math.round(last.x);
- last.y = Math.round(last.y);
- last.width = Math.round(last.width);
- last.height = Math.round(last.height);
- } else {
+ // 妫�鏌ユ槸鍚﹀彲浠ユ按骞冲悎骞讹紙鍚屼竴琛岋紝楂樺害鐩稿悓锛岀浉閭伙級
+ if (current.y === next.y &&
+ current.height === next.height &&
+ current.x + current.width === next.x) {
+ // 姘村钩鍚堝苟
+ current.width += next.width;
+ }
+ // 妫�鏌ユ槸鍚﹀彲浠ュ瀭鐩村悎骞讹紙鍚屼竴鍒楋紝瀹藉害鐩稿悓锛岀浉閭伙級
+ else if (current.x === next.x &&
+ current.width === next.width &&
+ current.y + current.height === next.y) {
+ // 鍨傜洿鍚堝苟
+ current.height += next.height;
+ }
+ else {
+ // 鏃犳硶鍚堝苟锛屼繚瀛樺綋鍓嶇煩褰紝寮�濮嬫柊鐨勫悎骞�
merged.push({
x: Math.round(current.x),
y: Math.round(current.y),
@@ -691,54 +692,100 @@
height: Math.round(current.height),
isRemain: true
});
+ current = { ...next };
}
}
-
- const nonGray = glassDetails.filter(r => !r.isRemain);
- //鍒犻櫎鍘熸暟缁勬嫾鎺ユ柊鐨勫皬鐗囪窡浣欐枡
- glassDetails.splice(0, glassDetails.length, ...nonGray, ...merged);
+ // 閲嶆柊鏋勫缓鏁扮粍锛氶潪浣欐枡 + 鍚堝苟鍚庣殑浣欐枡
+ glassDetails.splice(0, glassDetails.length, ...nonGrayRects, ...merged);
};
+
+// 纭繚杩斿洖鐨勫尯鍩熶笉閲嶅彔
+const calculateRemainingAreas = (totalWidth, totalHeight, obstacles) => {
+ // 浠庢暣涓師鐗囧紑濮�
+ let remaining = [{ x: 0, y: 0, width: totalWidth, height: totalHeight }];
+
+ // 閫愪釜澶勭悊闅滅鐗╋紙宸叉斁缃殑鐜荤拑鐗囷級
+ obstacles.forEach(obstacle => {
+ remaining = cutRemainingAreas(remaining, obstacle, totalWidth, totalHeight);
+ });
+
+ // 瀵圭粨鏋滆繘琛屾帓搴忥紝纭繚涓�鑷存��
+ remaining.sort((a, b) => {
+ if (a.x !== b.x) return a.x - b.x;
+ return a.y - b.y;
+ });
+
+ return remaining;
+};
+
// 璋冩暣鍚庨噸鏂拌绠楃伆鑹蹭綑鏂�
const adjustGrayRectangles = (layoutIndex) => {
const layout = layouts.value[layoutIndex];
const glassDetails = layout.glassDetails;
- //灏忕墖鐨勬暟鎹�
+
+ // 1. 绛涢�夊嚭闈炰綑鏂欑殑鐜荤拑鐗囷紙鍗冲疄闄呰鍒囧壊鐨勭幓鐠冪墖锛�
const nonGrayRects = glassDetails.filter(glassDetail => !glassDetail.isRemain);
- //鎵�鏈夌殑灏忕墖浣欐枡鍧愭爣璺熷昂瀵�
+ // 2. 璁$畻鍓╀綑鍙敤鍖哄煙
let remainingAreas = calculateRemainingAreas(layout.width, layout.height, nonGrayRects);
- const uniqueArr = Array.from(
- new Set(remainingAreas.map(item => JSON.stringify(item)))
- ).map(item => JSON.parse(item));
- //浣欐枡鐨勬暟鎹�
+
+ // 3. 鍘婚噸澶勭悊 - 鏇翠弗鏍肩殑鍘婚噸閫昏緫
+ const uniqueArr = removeDuplicateAreas(remainingAreas);
+
+ // 4. 鑾峰彇褰撳墠宸插瓨鍦ㄧ殑浣欐枡鐭╁舰锛堥渶瑕佷繚鐣欏紩鐢ㄤ互渚挎洿鏂帮級
const currentGrayRects = glassDetails.filter(r => r.isRemain);
- //寰幆浣欐枡鏁版嵁璺熷叏閮ㄧ殑瀵规瘮
- currentGrayRects.forEach((_, index) => {
- if (index >= remainingAreas.length) {
- glassDetails.splice(index, 1);
- }
+
+ // 5. 娓呴櫎鎵�鏈夌幇鏈夌殑浣欐枡鐭╁舰
+ // 鍏堟敹闆嗛潪浣欐枡鐭╁舰
+ const nonRemainRects = glassDetails.filter(r => !r.isRemain);
+
+ // 6. 閲嶆柊鏋勫缓鐜荤拑璇︽儏鏁扮粍
+ // 淇濈暀闈炰綑鏂欑煩褰�
+ const newGlassDetails = [...nonRemainRects];
+
+ // 娣诲姞鏂扮殑浣欐枡鐭╁舰
+ uniqueArr.forEach((area) => {
+ newGlassDetails.push({
+ x: Math.round(area.x),
+ y: Math.round(area.y),
+ width: Math.round(area.width),
+ height: Math.round(area.height),
+ isRemain: true
+ });
});
- uniqueArr.forEach((area, index) => {
- if (index < currentGrayRects.length) {
- currentGrayRects[index].x = Math.round(area.x);
- currentGrayRects[index].y = Math.round(area.y);
- currentGrayRects[index].width = Math.round(area.width);
- currentGrayRects[index].height = Math.round(area.height);
- } else {
- glassDetails.push({
- x: Math.round(area.x),
- y: Math.round(area.y),
- width: Math.round(area.width),
- height: Math.round(area.height),
- isRemain: true
- });
- }
- });
+ // 7. 鏇存柊甯冨眬鐨勭幓鐠冭鎯�
+ layout.glassDetails = newGlassDetails;
- mergeAdjacentGrayRects(glassDetails,layout.width, layout.height);
+ // 8. 鍚堝苟鐩搁偦鐨勪綑鏂欑煩褰�
+ mergeAdjacentGrayRects(layout.glassDetails, layout.width, layout.height);
};
+
+
+const removeDuplicateAreas = (areas) => {
+ const result = [];
+
+ areas.forEach(area => {
+ // 妫�鏌ユ槸鍚︿笌宸插瓨鍦ㄧ殑鍖哄煙閲嶅彔鎴栫浉绛�
+ const isDuplicate = result.some(existingArea => {
+ return (
+ existingArea.x === area.x &&
+ existingArea.y === area.y &&
+ existingArea.width === area.width &&
+ existingArea.height === area.height
+ );
+ });
+
+ if (!isDuplicate) {
+ result.push(area);
+ }
+ });
+
+ return result;
+};
+
+
//鏃嬭浆鏂规硶
const rotateRect = (layoutIndex, rectIndex) => {
@@ -882,19 +929,24 @@
};
//閲嶆柊璁$畻浣欐枡鍧愭爣浠ュ強灏哄1
-const calculateRemainingAreas = (totalWidth, totalHeight, obstacles) => {
- let remaining = [{ x: 0, y: 0, width: totalWidth, height: totalHeight }];
- obstacles.forEach(glassDetail => {
- remaining = cutRemainingAreas(remaining, glassDetail,totalWidth,totalHeight);
- });
- return remaining;
-};
+// const calculateRemainingAreas = (totalWidth, totalHeight, obstacles) => {
+// let remaining = [{ x: 0, y: 0, width: totalWidth, height: totalHeight }];
+// obstacles.forEach(glassDetail => {
+// remaining = cutRemainingAreas(remaining, glassDetail,totalWidth,totalHeight);
+// });
+// return remaining;
+// };
//閲嶆柊璁$畻浣欐枡鍧愭爣浠ュ強灏哄2
-const cutRemainingAreas = (remainingAreas, obstacle,totalWidth,totalHeight) => {
+const cutRemainingAreas = (remainingAreas, obstacle, totalWidth, totalHeight) => {
const newRemaining = [];
+
remainingAreas.forEach(area => {
+ // 濡傛灉闅滅鐗╀笌褰撳墠鍖哄煙鏈夐噸鍙�
if (checkOverlap(area, obstacle)) {
+ // 鍒囧垎褰撳墠鍖哄煙涓烘渶澶�4涓柊鍖哄煙
+
+ // 宸︿晶鍖哄煙
if (obstacle.x > area.x) {
newRemaining.push({
x: area.x,
@@ -903,35 +955,50 @@
height: area.height
});
}
+
+ // 鍙充晶鍖哄煙
if (obstacle.x + obstacle.width < area.x + area.width) {
newRemaining.push({
x: obstacle.x + obstacle.width,
y: area.y,
- width: area.width - (obstacle.x + obstacle.width - area.x),
+ width: area.x + area.width - (obstacle.x + obstacle.width),
height: area.height
});
}
- if (obstacle.y > area.y) {
- newRemaining.push({
- x: area.x,
- y: area.y,
- width: area.width,
- height: obstacle.y - area.y
- });
- }
- if (obstacle.y + obstacle.height < area.y + area.height ) {
- newRemaining.push({
- x: area.x,
- y: obstacle.y + obstacle.height,
- width: area.width,
- height: area.height - (obstacle.y + obstacle.height - area.y)
- });
+ // 涓婃柟鍖哄煙锛堜粎鍦ㄩ殰纰嶇墿宸﹀彸杈圭晫涔嬮棿鐨勫尯鍩燂級
+ 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) {
+ newRemaining.push({
+ x: startX,
+ y: area.y,
+ width: endX - startX,
+ height: obstacle.y - area.y
+ });
+ }
+ }
+
+ // 涓嬫柟鍖哄煙锛堜粎鍦ㄩ殰纰嶇墿宸﹀彸杈圭晫涔嬮棿鐨勫尯鍩燂級
+ 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) {
+ newRemaining.push({
+ x: startX,
+ y: obstacle.y + obstacle.height,
+ width: endX - startX,
+ height: area.y + area.height - (obstacle.y + obstacle.height)
+ });
+ }
}
} else {
+ // 娌℃湁閲嶅彔锛屼繚鐣欏師鍖哄煙
newRemaining.push(area);
}
});
+
return newRemaining;
};
--
Gitblit v1.8.0