| | |
| | | return planPathCore(originalPolygon, width, margin); |
| | | } |
| | | |
| | | /** |
| | | * 核心路径规划逻辑 |
| | | * |
| | | * @param originalPolygon 原始多边形顶点列表 |
| | | * @param width 割草宽度 |
| | | * @param margin 安全边距 |
| | | * @return 规划好的路径段列表 |
| | | */ |
| | | private static List<PathSegment> planPathCore(List<Point> originalPolygon, double width, double margin) { |
| | | if (originalPolygon.size() < 3) return new ArrayList<>(); |
| | | |
| | |
| | | |
| | | /** |
| | | * 寻找弓字形的第一条线的起点 |
| | | * |
| | | * @param polygon 多边形顶点列表 |
| | | * @param angle 扫描角度 |
| | | * @param width 割草宽度 |
| | | * @return 扫描起点的坐标 |
| | | */ |
| | | private static Point getFirstScanStartPoint(List<Point> polygon, double angle, double width) { |
| | | List<Point> rotated = rotatePolygon(polygon, -angle); |
| | |
| | | |
| | | /** |
| | | * 重组多边形顶点,使得索引0的点最靠近填充起点 |
| | | * |
| | | * @param polygon 多边形顶点列表 |
| | | * @param target 目标点(填充起点) |
| | | * @return 重组后的多边形顶点列表 |
| | | */ |
| | | private static List<Point> alignBoundaryToStart(List<Point> polygon, Point target) { |
| | | int bestIdx = 0; |
| | |
| | | return aligned; |
| | | } |
| | | |
| | | /** |
| | | * 生成弓字形扫描路径 |
| | | * |
| | | * @param polygon 多边形顶点列表 |
| | | * @param angle 扫描角度 |
| | | * @param width 割草宽度 |
| | | * @param startPoint 起始点 |
| | | * @return 弓字形路径段列表 |
| | | */ |
| | | private static List<PathSegment> generateZigZagPath(List<Point> polygon, double angle, double width, Point startPoint) { |
| | | List<PathSegment> result = new ArrayList<>(); |
| | | List<Point> rotated = rotatePolygon(polygon, -angle); |
| | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 获取扫描线与多边形的交点X坐标列表 |
| | | * |
| | | * @param rotatedPoly 旋转后的多边形 |
| | | * @param y 扫描线的Y坐标 |
| | | * @return 交点X坐标列表 |
| | | */ |
| | | private static List<Double> getXIntersections(List<Point> rotatedPoly, double y) { |
| | | List<Double> xIntersections = new ArrayList<>(); |
| | | int n = rotatedPoly.size(); |
| | |
| | | |
| | | // --- 几何基础工具 --- |
| | | |
| | | /** |
| | | * 多边形内缩(计算安全工作区域) |
| | | * |
| | | * @param polygon 原始多边形 |
| | | * @param margin 内缩距离 |
| | | * @return 内缩后的多边形 |
| | | */ |
| | | private static List<Point> shrinkPolygon(List<Point> polygon, double margin) { |
| | | List<Point> result = new ArrayList<>(); |
| | | int n = polygon.size(); |
| | |
| | | return result; |
| | | } |
| | | |
| | | /** |
| | | * 寻找最优扫描角度(使扫描线数量最少) |
| | | * |
| | | * @param polygon 多边形 |
| | | * @return 最优角度(弧度) |
| | | */ |
| | | private static double findOptimalScanAngle(List<Point> polygon) { |
| | | double minH = Double.MAX_VALUE; |
| | | double bestA = 0; |
| | |
| | | return bestA; |
| | | } |
| | | |
| | | /** |
| | | * 计算多边形在特定角度下的高度(投影长度) |
| | | * |
| | | * @param poly 多边形 |
| | | * @param angle 角度 |
| | | * @return 高度 |
| | | */ |
| | | 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); |
| | |
| | | return maxY - minY; |
| | | } |
| | | |
| | | /** |
| | | * 旋转点 |
| | | * |
| | | * @param p 点 |
| | | * @param angle 旋转角度 |
| | | * @return 旋转后的点 |
| | | */ |
| | | private static Point rotatePoint(Point p, double angle) { |
| | | double c = Math.cos(angle), s = Math.sin(angle); |
| | | return new Point(p.x * c - p.y * s, p.x * s + p.y * c); |
| | | } |
| | | |
| | | /** |
| | | * 旋转多边形 |
| | | * |
| | | * @param poly 多边形 |
| | | * @param angle 旋转角度 |
| | | * @return 旋转后的多边形 |
| | | */ |
| | | private static List<Point> rotatePolygon(List<Point> poly, double angle) { |
| | | List<Point> res = new ArrayList<>(); |
| | | for (Point p : poly) res.add(rotatePoint(p, angle)); |
| | | return res; |
| | | } |
| | | |
| | | /** |
| | | * 确保多边形顶点为逆时针顺序 |
| | | * |
| | | * @param poly 多边形 |
| | | */ |
| | | private static void ensureCCW(List<Point> poly) { |
| | | double s = 0; |
| | | for (int i = 0; i < poly.size(); i++) { |
| | |
| | | if (s > 0) Collections.reverse(poly); |
| | | } |
| | | |
| | | /** |
| | | * 解析坐标字符串 |
| | | * |
| | | * @param s 坐标字符串 (格式: "x1,y1;x2,y2;...") |
| | | * @return 点列表 |
| | | */ |
| | | private static List<Point> parseCoords(String s) { |
| | | List<Point> list = new ArrayList<>(); |
| | | for (String p : s.split(";")) { |