From 1175f5fbe8fd832943880bfc37c0e2a451a0688a Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期四, 25 十二月 2025 19:34:38 +0800
Subject: [PATCH] 删除了几个类优化了路径生成的逻辑

---
 src/lujing/AoxinglujingHaveObstacel.java |  245 +++++++++++++++++++-----------------------------
 1 files changed, 97 insertions(+), 148 deletions(-)

diff --git a/src/lujing/AoxinglujingHaveObstacel.java b/src/lujing/AoxinglujingHaveObstacel.java
index 12e585e..5e2f046 100644
--- a/src/lujing/AoxinglujingHaveObstacel.java
+++ b/src/lujing/AoxinglujingHaveObstacel.java
@@ -5,8 +5,8 @@
 import java.util.List;
 
 /**
- * 鍑稿舰鑽夊湴璺緞瑙勫垝 (閬块殰浼樺寲鐗�)
- * 浼樺寲锛氬鍔犱簡闅滅鐗╁尯闂撮澶勭悊銆佽矾寰勮繛鎺ュ氨杩戝師鍒欍�佷互鍙婃洿绋冲仴鐨勫杈瑰舰澶栨墿
+ * 鍑稿舰鑽夊湴璺緞瑙勫垝 (閬块殰淇鐗�)
+ * 淇閲嶇偣锛氬己鍖栬法琛屽強閬块殰鍚庣殑璺緞杩炶疮鎬э紝纭繚姣忎竴娈靛垏鍓查兘鏈夋樉寮忕殑绉诲姩璺緞杩炴帴銆�
  */
 public class AoxinglujingHaveObstacel {
 
@@ -35,7 +35,6 @@
     public static class PolygonObstacle extends Obstacle {
         public List<Point> points;
         public PolygonObstacle(List<Point> points) { this.points = points; }
-        
         @Override
         public boolean isInside(Point p) {
             boolean result = false;
@@ -47,7 +46,6 @@
             }
             return result;
         }
-
         @Override
         public List<Double> getIntersectionsX(double y, double angle) {
             List<Point> rotated = rotatePolygon(this.points, -angle);
@@ -66,12 +64,8 @@
         public Point center;
         public double radius;
         public CircleObstacle(Point center, double radius) { this.center = center; this.radius = radius; }
-        
         @Override
-        public boolean isInside(Point p) {
-            return Math.hypot(p.x - center.x, p.y - center.y) <= radius + EPSILON;
-        }
-
+        public boolean isInside(Point p) { return Math.hypot(p.x - center.x, p.y - center.y) <= radius + EPSILON; }
         @Override
         public List<Double> getIntersectionsX(double y, double angle) {
             List<Double> xInts = new ArrayList<>();
@@ -79,8 +73,7 @@
             double dy = Math.abs(y - rCenter.y);
             if (dy < radius) {
                 double dx = Math.sqrt(radius * radius - dy * dy);
-                xInts.add(rCenter.x - dx);
-                xInts.add(rCenter.x + dx);
+                xInts.add(rCenter.x - dx); xInts.add(rCenter.x + dx);
             }
             return xInts;
         }
@@ -91,13 +84,11 @@
         double width = Double.parseDouble(widthStr);
         double margin = Double.parseDouble(marginStr);
         List<Obstacle> obstacles = parseObstacles(obstacleStr, margin);
-
         return planPathCore(boundary, obstacles, width, margin);
     }
 
     private static List<PathSegment> planPathCore(List<Point> boundary, List<Obstacle> obstacles, double width, double margin) {
         if (boundary.size() < 3) return new ArrayList<>();
-
         ensureCCW(boundary);
         List<Point> workArea = shrinkPolygon(boundary, margin);
         if (workArea.size() < 3) return new ArrayList<>();
@@ -107,109 +98,94 @@
         List<Point> alignedWorkArea = alignBoundaryToStart(workArea, firstScanStart);
 
         List<PathSegment> finalPath = new ArrayList<>();
-
-        // 1. 鍥磋竟璺緞
+        // 1. 娣诲姞鍥磋竟璺緞
         for (int i = 0; i < alignedWorkArea.size(); i++) {
             finalPath.add(new PathSegment(alignedWorkArea.get(i), alignedWorkArea.get((i + 1) % alignedWorkArea.size()), true));
         }
 
-        // 2. 鍐呴儴濉厖
+        // 2. 鐢熸垚鍐呴儴寮撳瓧褰� (寮哄寲杩炴帴閫昏緫)
         Point currentPos = alignedWorkArea.get(0);
-        List<PathSegment> zigZagLines = generateOptimizedZigZag(workArea, obstacles, bestAngle, width, currentPos);
-        finalPath.addAll(zigZagLines);
+        List<PathSegment> zigZag = generateFixedZigZag(workArea, obstacles, bestAngle, width, currentPos);
+        finalPath.addAll(zigZag);
 
         return finalPath;
     }
 
-    private static List<PathSegment> generateOptimizedZigZag(List<Point> polygon, List<Obstacle> obstacles, double angle, double width, Point startPoint) {
+    private static List<PathSegment> generateFixedZigZag(List<Point> polygon, List<Obstacle> obstacles, double angle, double width, Point startPoint) {
         List<PathSegment> result = new ArrayList<>();
         List<Point> rotatedPoly = rotatePolygon(polygon, -angle);
-        
         double minY = Double.MAX_VALUE, maxY = -Double.MAX_VALUE;
-        for (Point p : rotatedPoly) {
-            minY = Math.min(minY, p.y); maxY = Math.max(maxY, p.y);
-        }
+        for (Point p : rotatedPoly) { minY = Math.min(minY, p.y); maxY = Math.max(maxY, p.y); }
 
         Point currentPos = startPoint;
         boolean leftToRight = true;
 
-        for (double y = minY + width; y < maxY - width / 2; y += width) {
-            List<Double> intersections = getXIntersections(rotatedPoly, y);
-            if (intersections.size() < 2) continue;
-            Collections.sort(intersections);
-            
-            double xBoundaryMin = intersections.get(0);
-            double xBoundaryMax = intersections.get(intersections.size() - 1);
+        for (double y = minY + width; y < maxY - width/2; y += width) {
+            List<Double> polyInts = getXIntersections(rotatedPoly, y);
+            if (polyInts.size() < 2) continue;
+            Collections.sort(polyInts);
+            double xMin = polyInts.get(0), xMax = polyInts.get(polyInts.size() - 1);
 
-            // 鏀堕泦褰撳墠琛屾墍鏈夐殰纰嶇墿浜ょ偣骞惰繘琛岃鍓�
-            List<Double> splitPoints = new ArrayList<>();
-            splitPoints.add(xBoundaryMin);
+            // 鏀堕泦鎵�鏈夊垎鍓茬偣锛堣竟鐣� + 闅滅鐗╀氦鐐癸級
+            List<Double> splits = new ArrayList<>();
+            splits.add(xMin); splits.add(xMax);
             for (Obstacle obs : obstacles) {
-                List<Double> obsX = obs.getIntersectionsX(y, angle);
-                for (double ox : obsX) {
-                    if (ox > xBoundaryMin && ox < xBoundaryMax) splitPoints.add(ox);
+                for (double ox : obs.getIntersectionsX(y, angle)) {
+                    if (ox > xMin + EPSILON && ox < xMax - EPSILON) splits.add(ox);
                 }
             }
-            Collections.sort(splitPoints);
+            Collections.sort(splits);
 
-            // 鏋勫缓鏈夋晥娈�
-            List<LineRange> validRanges = new ArrayList<>();
-            for (int i = 0; i < splitPoints.size() - 1; i++) {
-                double midX = (splitPoints.get(i) + splitPoints.get(i + 1)) / 2.0;
-                Point midPoint = rotatePoint(new Point(midX, y), angle);
-                
-                boolean insideAnyObstacle = false;
-                for (Obstacle obs : obstacles) {
-                    if (obs.isInside(midPoint)) {
-                        insideAnyObstacle = true;
-                        break;
-                    }
-                }
-                if (!insideAnyObstacle) {
-                    validRanges.add(new LineRange(splitPoints.get(i), splitPoints.get(i+1)));
+            // 鏋勫缓鏈鍊欓�夋
+            List<Double[]> rowSegments = new ArrayList<>();
+            for (int i = 0; i < splits.size() - 1; i++) {
+                double s = splits.get(i), e = splits.get(i+1);
+                Point mid = rotatePoint(new Point((s + e) / 2.0, y), angle);
+                if (!isPointInAnyObstacle(mid, obstacles)) {
+                    rowSegments.add(new Double[]{s, e});
                 }
             }
 
-            // 鏍规嵁褰撳墠鏈濆悜鎺掑簭鏈夋晥娈�
+            // 鏍规嵁褰撳墠S鍨嬫柟鍚戞帓搴�
             if (!leftToRight) {
-                Collections.reverse(validRanges);
-                for (LineRange range : validRanges) {
-                    double temp = range.start;
-                    range.start = range.end;
-                    range.end = temp;
-                }
+                Collections.reverse(rowSegments);
+                for (Double[] seg : rowSegments) { double t = seg[0]; seg[0] = seg[1]; seg[1] = t; }
             }
 
-            // 杩炴帴璺緞
-            for (LineRange range : validRanges) {
-                Point pStart = rotatePoint(new Point(range.start, y), angle);
-                Point pEnd = rotatePoint(new Point(range.end, y), angle);
+            // 鎵ц杩炴帴锛氬己鍒舵鏌� currentPos 鍒版瘡涓�娈佃捣鐐圭殑璺濈
+            for (Double[] seg : rowSegments) {
+                Point p1 = rotatePoint(new Point(seg[0], y), angle);
+                Point p2 = rotatePoint(new Point(seg[1], y), angle);
 
-                if (Math.hypot(currentPos.x - pStart.x, currentPos.y - pStart.y) > 0.01) {
-                    result.add(new PathSegment(currentPos, pStart, false));
+                // 鏍稿績淇锛氭棤璁哄杩戯紝鍙涓嶆槸鍚屼竴鐐癸紝灏卞缓绔嬭櫄绾胯繛鎺ワ紝纭繚璺緞娴佽浆
+                if (dist(currentPos, p1) > 0.001) {
+                    result.add(new PathSegment(currentPos, p1, false));
                 }
-                result.add(new PathSegment(pStart, pEnd, true));
-                currentPos = pEnd;
+                result.add(new PathSegment(p1, p2, true));
+                currentPos = p2;
             }
             leftToRight = !leftToRight;
         }
         return result;
     }
 
-    private static class LineRange {
-        double start, end;
-        LineRange(double s, double e) { this.start = s; this.end = e; }
+    private static boolean isPointInAnyObstacle(Point p, List<Obstacle> obstacles) {
+        for (Obstacle obs : obstacles) if (obs.isInside(p)) return true;
+        return false;
     }
 
-    // --- 闅滅鐗╄В鏋愪笌澶氳竟褰㈠鎵� ---
+    private static double dist(Point p1, Point p2) {
+        return Math.hypot(p1.x - p2.x, p1.y - p2.y);
+    }
+
+    // --- 杈呭姪宸ュ叿 (瑙f瀽涓庡彉鎹�) ---
     private static List<Obstacle> parseObstacles(String obsStr, double margin) {
         List<Obstacle> list = new ArrayList<>();
-        if (obsStr == null || obsStr.trim().isEmpty()) return list;
-
+        if (obsStr == null || obsStr.isEmpty()) return list;
         for (String part : obsStr.split("\\$")) {
             List<Point> pts = parseCoords(part);
             if (pts.size() == 2) {
-                double r = Math.hypot(pts.get(0).x - pts.get(1).x, pts.get(0).y - pts.get(1).y);
+                double r = dist(pts.get(0), pts.get(1));
                 list.add(new CircleObstacle(pts.get(0), r + margin));
             } else if (pts.size() > 2) {
                 ensureCCW(pts);
@@ -220,39 +196,26 @@
     }
 
     private static List<Point> expandPolygon(List<Point> poly, double margin) {
-        List<Point> result = new ArrayList<>();
+        List<Point> res = new ArrayList<>();
         int n = poly.size();
         for (int i = 0; i < n; i++) {
-            Point pPrev = poly.get((i - 1 + n) % n);
-            Point pCurr = poly.get(i);
-            Point pNext = poly.get((i + 1) % n);
-
-            double d1x = pCurr.x - pPrev.x, d1y = pCurr.y - pPrev.y;
-            double l1 = Math.hypot(d1x, d1y);
-            double d2x = pNext.x - pCurr.x, d2y = pNext.y - pCurr.y;
-            double l2 = Math.hypot(d2x, d2y);
-
-            // 璁$畻澶栨硶绾�
+            Point p1 = poly.get((i - 1 + n) % n), p2 = poly.get(i), p3 = poly.get((i + 1) % n);
+            double d1x = p2.x - p1.x, d1y = p2.y - p1.y;
+            double d2x = p3.x - p2.x, d2y = p3.y - p2.y;
+            double l1 = Math.hypot(d1x, d1y), l2 = Math.hypot(d2x, d2y);
             double n1x = d1y / l1, n1y = -d1x / l1;
             double n2x = d2y / l2, n2y = -d2x / l2;
-
             double bx = n1x + n2x, by = n1y + n2y;
             double bLen = Math.hypot(bx, by);
             if (bLen < EPSILON) { bx = n1x; by = n1y; } else { bx /= bLen; by /= bLen; }
-
-            double cosHalf = n1x * bx + n1y * by;
-            double d = margin / Math.max(cosHalf, 0.1); 
-            // 闄愬埗鏈�澶у鎵╋紝闃叉灏栬鐣稿彉
-            d = Math.min(d, margin * 3); 
-            result.add(new Point(pCurr.x + bx * d, pCurr.y + by * d));
+            double d = margin / Math.max(n1x * bx + n1y * by, 0.1);
+            res.add(new Point(p2.x + bx * Math.min(d, margin * 2), p2.y + by * Math.min(d, margin * 2)));
         }
-        return result;
+        return res;
     }
 
-    // --- 鍩虹宸ュ叿绫绘柟娉� ---
     private static List<Point> parseCoords(String s) {
         List<Point> list = new ArrayList<>();
-        if(s == null || s.isEmpty()) return list;
         for (String p : s.split(";")) {
             String[] xy = p.split(",");
             if (xy.length >= 2) list.add(new Point(Double.parseDouble(xy[0]), Double.parseDouble(xy[1])));
@@ -269,55 +232,42 @@
         if (s > 0) Collections.reverse(poly);
     }
 
-    private static List<Point> shrinkPolygon(List<Point> polygon, double margin) {
-        List<Point> result = new ArrayList<>();
-        int n = polygon.size();
+    private static List<Point> shrinkPolygon(List<Point> poly, double margin) {
+        List<Point> res = new ArrayList<>();
+        int n = poly.size();
         for (int i = 0; i < n; i++) {
-            Point pPrev = polygon.get((i - 1 + n) % n);
-            Point pCurr = polygon.get(i);
-            Point pNext = polygon.get((i + 1) % n);
-            double d1x = pCurr.x - pPrev.x, d1y = pCurr.y - pPrev.y;
-            double l1 = Math.hypot(d1x, d1y);
-            double d2x = pNext.x - pCurr.x, d2y = pNext.y - pCurr.y;
-            double l2 = Math.hypot(d2x, d2y);
+            Point p1 = poly.get((i - 1 + n) % n), p2 = poly.get(i), p3 = poly.get((i + 1) % n);
+            double d1x = p2.x - p1.x, d1y = p2.y - p1.y;
+            double d2x = p3.x - p2.x, d2y = p3.y - p2.y;
+            double l1 = Math.hypot(d1x, d1y), l2 = Math.hypot(d2x, d2y);
             double n1x = -d1y / l1, n1y = d1x / l1;
             double n2x = -d2y / l2, n2y = d2x / l2;
             double bx = n1x + n2x, by = n1y + n2y;
             double bLen = Math.hypot(bx, by);
             if (bLen < EPSILON) { bx = n1x; by = n1y; } else { bx /= bLen; by /= bLen; }
-            double cosHalf = n1x * bx + n1y * by;
-            double d = margin / Math.max(cosHalf, 0.1);
-            result.add(new Point(pCurr.x + bx * d, pCurr.y + by * d));
+            double d = margin / Math.max(n1x * bx + n1y * by, 0.1);
+            res.add(new Point(p2.x + bx * d, p2.y + by * d));
         }
-        return result;
+        return res;
     }
 
-    private static double findOptimalScanAngle(List<Point> polygon) {
+    private static double findOptimalScanAngle(List<Point> poly) {
         double minH = Double.MAX_VALUE, bestA = 0;
-        for (int i = 0; i < polygon.size(); i++) {
-            Point p1 = polygon.get(i), p2 = polygon.get((i + 1) % polygon.size());
-            double angle = Math.atan2(p2.y - p1.y, p2.x - p1.x);
-            double h = calculatePolygonHeightAtAngle(polygon, angle);
-            if (h < minH) { minH = h; bestA = angle; }
+        for (int i = 0; i < poly.size(); i++) {
+            Point p1 = poly.get(i), p2 = poly.get((i + 1) % poly.size());
+            double a = Math.atan2(p2.y - p1.y, p2.x - p1.x);
+            double minY = Double.MAX_VALUE, maxY = -Double.MAX_VALUE;
+            double s = Math.sin(-a), c = Math.cos(-a);
+            for (Point p : poly) { double ry = p.x * s + p.y * c; minY = Math.min(minY, ry); maxY = Math.max(maxY, ry); }
+            if (maxY - minY < minH) { minH = maxY - minY; bestA = a; }
         }
         return bestA;
     }
 
-    private static double calculatePolygonHeightAtAngle(List<Point> poly, double angle) {
-        double minY = Double.MAX_VALUE, maxY = -Double.MAX_VALUE;
-        double sin = Math.sin(-angle), cos = Math.cos(-angle);
-        for (Point p : poly) {
-            double ry = p.x * sin + p.y * cos;
-            minY = Math.min(minY, ry); maxY = Math.max(maxY, ry);
-        }
-        return maxY - minY;
-    }
-
     private static List<Double> getXIntersections(List<Point> rotatedPoly, double y) {
         List<Double> xInts = new ArrayList<>();
-        int n = rotatedPoly.size();
-        for (int i = 0; i < n; i++) {
-            Point p1 = rotatedPoly.get(i), p2 = rotatedPoly.get((i + 1) % n);
+        for (int i = 0; i < rotatedPoly.size(); i++) {
+            Point p1 = rotatedPoly.get(i), p2 = rotatedPoly.get((i + 1) % rotatedPoly.size());
             if ((p1.y <= y && p2.y > y) || (p2.y <= y && p1.y > y)) {
                 xInts.add(p1.x + (y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y));
             }
@@ -325,36 +275,35 @@
         return xInts;
     }
 
-    private static Point getFirstScanStartPoint(List<Point> polygon, double angle, double width) {
-        List<Point> rotated = rotatePolygon(polygon, -angle);
+    private static Point getFirstScanStartPoint(List<Point> poly, double angle, double width) {
+        List<Point> rot = rotatePolygon(poly, -angle);
         double minY = Double.MAX_VALUE;
-        for (Point p : rotated) minY = Math.min(minY, p.y);
-        double startY = minY + width + EPSILON;
-        List<Double> xInts = getXIntersections(rotated, startY);
-        if (xInts.isEmpty()) return polygon.get(0);
-        Collections.sort(xInts);
-        return rotatePoint(new Point(xInts.get(0), startY), angle);
+        for (Point p : rot) minY = Math.min(minY, p.y);
+        double sy = minY + width + EPSILON;
+        List<Double> x = getXIntersections(rot, sy);
+        Collections.sort(x);
+        return rotatePoint(new Point(x.isEmpty() ? 0 : x.get(0), sy), angle);
     }
 
-    private static List<Point> alignBoundaryToStart(List<Point> polygon, Point target) {
-        int bestIdx = 0; double minDist = Double.MAX_VALUE;
-        for (int i = 0; i < polygon.size(); i++) {
-            double d = Math.hypot(polygon.get(i).x - target.x, polygon.get(i).y - target.y);
-            if (d < minDist) { minDist = d; bestIdx = i; }
+    private static List<Point> alignBoundaryToStart(List<Point> poly, Point target) {
+        int idx = 0; double minD = Double.MAX_VALUE;
+        for (int i = 0; i < poly.size(); i++) {
+            double d = dist(poly.get(i), target);
+            if (d < minD) { minD = d; idx = i; }
         }
-        List<Point> aligned = new ArrayList<>();
-        for (int i = 0; i < polygon.size(); i++) aligned.add(polygon.get((bestIdx + i) % polygon.size()));
-        return aligned;
+        List<Point> res = new ArrayList<>();
+        for (int i = 0; i < poly.size(); i++) res.add(poly.get((idx + i) % poly.size()));
+        return res;
     }
 
-    private static Point rotatePoint(Point p, double angle) {
-        double c = Math.cos(angle), s = Math.sin(angle);
+    private static Point rotatePoint(Point p, double a) {
+        double c = Math.cos(a), s = Math.sin(a);
         return new Point(p.x * c - p.y * s, p.x * s + p.y * c);
     }
 
-    private static List<Point> rotatePolygon(List<Point> poly, double angle) {
+    private static List<Point> rotatePolygon(List<Point> poly, double a) {
         List<Point> res = new ArrayList<>();
-        for (Point p : poly) res.add(rotatePoint(p, angle));
+        for (Point p : poly) res.add(rotatePoint(p, a));
         return res;
     }
 }
\ No newline at end of file

--
Gitblit v1.10.0