826220679@qq.com
7 小时以前 cbfd1df513c473dd5550d78740c92fc1677b6e9b
src/lujing/MowingPathGenerationPage.java
@@ -140,8 +140,21 @@
        contentPanel.add(createTextAreaSection(obstacleTitle, obstacleArea));
        
        // 割草宽度
        widthField = createInfoTextField(widthValue != null ? widthValue : "", true);
        contentPanel.add(createTextFieldSection("割草宽度 (cm)", widthField));
        String displayWidth = "";
        if (widthValue != null && !widthValue.trim().isEmpty() && !"-1".equals(widthValue.trim())) {
            try {
                double val = Double.parseDouble(widthValue.trim());
                // 简单的启发式转换:如果值大于5,假设是厘米,转换为米
                if (val > 5) {
                    val = val / 100.0;
                }
                displayWidth = String.format(Locale.US, "%.2f", val);
            } catch (NumberFormatException e) {
                displayWidth = widthValue;
            }
        }
        widthField = createInfoTextField(displayWidth, true);
        contentPanel.add(createTextFieldSection("割草宽度 (m)", widthField));
        
        // 割草安全距离(只读显示)
        // 优先从Dikuai对象获取,如果Dikuai中没有,再从Device获取
@@ -223,9 +236,9 @@
        String sanitizedWidth = sanitizeWidthString(widthField.getText());
        if (sanitizedWidth != null) {
            try {
                double widthCm = Double.parseDouble(sanitizedWidth);
                widthField.setText(formatWidthForStorage(widthCm));
                sanitizedWidth = formatWidthForStorage(widthCm);
                double widthMeters = Double.parseDouble(sanitizedWidth);
                widthField.setText(formatWidthForStorage(widthMeters));
                sanitizedWidth = formatWidthForStorage(widthMeters);
            } catch (NumberFormatException ex) {
                widthField.setText(sanitizedWidth);
            }
@@ -407,25 +420,25 @@
        String rawWidthInput = widthField.getText() != null ? widthField.getText().trim() : "";
        String widthSanitized = sanitizeWidthString(widthField.getText());
        if (widthSanitized == null) {
                String message = rawWidthInput.isEmpty() ? "请先设置割草宽度(cm)" : "割草宽度格式不正确";
                String message = rawWidthInput.isEmpty() ? "请先设置割草宽度(m)" : "割草宽度格式不正确";
            JOptionPane.showMessageDialog(this, message, "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }
        
        double widthCm;
        double widthMeters;
        try {
            widthCm = Double.parseDouble(widthSanitized);
            widthMeters = Double.parseDouble(widthSanitized);
        } catch (NumberFormatException ex) {
            JOptionPane.showMessageDialog(this, "割草宽度格式不正确", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }
        
        if (widthCm <= 0) {
        if (widthMeters <= 0) {
            JOptionPane.showMessageDialog(this, "割草宽度必须大于0", "提示", JOptionPane.WARNING_MESSAGE);
            return;
        }
        
        String widthNormalized = formatWidthForStorage(widthCm);
        String widthNormalized = formatWidthForStorage(widthMeters);
        widthField.setText(widthNormalized);
        
        String pathNormalized = normalizeCoordinateInput(pathArea.getText());
@@ -518,15 +531,15 @@
        String widthStr = sanitizeWidthString(widthCmInput);
        if (widthStr == null) {
            if (showMessages) {
                String message = rawWidth.isEmpty() ? "请先设置割草宽度(cm)" : "割草宽度格式不正确";
                String message = rawWidth.isEmpty() ? "请先设置割草宽度(m)" : "割草宽度格式不正确";
                JOptionPane.showMessageDialog(parentComponent, message, "提示", JOptionPane.WARNING_MESSAGE);
            }
            return null;
        }
        
        double widthCm;
        double widthVal;
        try {
            widthCm = Double.parseDouble(widthStr);
            widthVal = Double.parseDouble(widthStr);
        } catch (NumberFormatException ex) {
            if (showMessages) {
                JOptionPane.showMessageDialog(parentComponent, "割草宽度格式不正确", 
@@ -535,7 +548,7 @@
            return null;
        }
        
        if (widthCm <= 0) {
        if (widthVal <= 0) {
            if (showMessages) {
                JOptionPane.showMessageDialog(parentComponent, "割草宽度必须大于0", 
                    "提示", JOptionPane.WARNING_MESSAGE);
@@ -543,7 +556,7 @@
            return null;
        }
        
        double widthMeters = widthCm / 100.0d;
        double widthMeters = widthVal;
        String plannerWidth = BigDecimal.valueOf(widthMeters)
            .setScale(3, RoundingMode.HALF_UP)
            .stripTrailingZeros()
@@ -596,12 +609,14 @@
                // 无障碍物的情况
                if (grassType == 1) {
                    // 凸形地块,无障碍物 -> 调用 AoxinglujingNoObstacle
                    System.out.println("调用算法: 凸形无障碍物, 类名: AoxinglujingNoObstacle");
                    List<AoxinglujingNoObstacle.PathSegment> segments = 
                        AoxinglujingNoObstacle.planPath(boundary, plannerWidth, safetyMarginStr);
                    generated = formatAoxingPathSegments(segments);
                } else if (grassType == 2) {
                    // 异形地块,无障碍物 -> 调用 YixinglujingNoObstacle
                    // 调用 YixinglujingNoObstacle.planPath 获取路径段列表
                    System.out.println("调用算法: 异形无障碍物, 类名: YixinglujingNoObstacle");
                    List<YixinglujingNoObstacle.PathSegment> segments = 
                        YixinglujingNoObstacle.planPath(boundary, plannerWidth, safetyMarginStr);
                    // 格式化路径段列表为字符串
@@ -612,6 +627,7 @@
                        JOptionPane.showMessageDialog(parentComponent, "无法判断地块类型,尝试按凸形地块处理", 
                            "提示", JOptionPane.WARNING_MESSAGE);
                    }
                    System.out.println("调用算法: 无法判断类型(默认凸形无障碍物), 类名: AoxinglujingNoObstacle");
                    List<AoxinglujingNoObstacle.PathSegment> segments = 
                        AoxinglujingNoObstacle.planPath(boundary, plannerWidth, safetyMarginStr);
                    generated = formatAoxingPathSegments(segments);
@@ -621,12 +637,14 @@
                if (grassType == 1) {
                    // 凸形地块,有障碍物 -> 调用 AoxinglujingHaveObstacel
                    // 传入参数:boundary(A), obstacles(B), plannerWidth(C), safetyMarginStr(D)
                    System.out.println("调用算法: 凸形有障碍物, 类名: AoxinglujingHaveObstacel");
                    List<AoxinglujingHaveObstacel.PathSegment> segments = 
                        AoxinglujingHaveObstacel.planPath(boundary, obstacles, plannerWidth, safetyMarginStr);
                    generated = formatAoxingHaveObstaclePathSegments(segments);
                } else if (grassType == 2) {
                    // 异形地块,有障碍物 -> 调用 YixinglujingHaveObstacel
                    // 传入参数:boundary(A), obstacles(B), plannerWidth(C), safetyMarginStr(D)
                    System.out.println("调用算法: 异形有障碍物, 类名: YixinglujingHaveObstacel");
                    List<YixinglujingHaveObstacel.PathSegment> segments = 
                        YixinglujingHaveObstacel.planPath(boundary, obstacles, plannerWidth, safetyMarginStr);
                    generated = formatYixingHaveObstaclePathSegments(segments);
@@ -636,6 +654,7 @@
                        JOptionPane.showMessageDialog(parentComponent, "无法判断地块类型,尝试按凸形地块处理", 
                            "提示", JOptionPane.WARNING_MESSAGE);
                    }
                    System.out.println("调用算法: 无法判断类型(默认凸形有障碍物), 类名: AoxinglujingHaveObstacel");
                    List<AoxinglujingHaveObstacel.PathSegment> segments = 
                        AoxinglujingHaveObstacel.planPath(boundary, obstacles, plannerWidth, safetyMarginStr);
                    generated = formatAoxingHaveObstaclePathSegments(segments);
@@ -1081,11 +1100,8 @@
        return cleaned.isEmpty() ? null : cleaned;
    }
    
    private String formatWidthForStorage(double widthCm) {
        return BigDecimal.valueOf(widthCm)
            .setScale(2, RoundingMode.HALF_UP)
            .stripTrailingZeros()
            .toPlainString();
    private String formatWidthForStorage(double widthVal) {
        return String.format(Locale.US, "%.2f", widthVal);
    }
    
    private String formatMowingPatternForDialog(String patternValue) {