From 32524195d474b74e48916867b2a6c2f022a40d98 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期二, 09 十二月 2025 19:36:32 +0800
Subject: [PATCH] 20251209
---
src/zhuye/MapRenderer.java | 126 +++++++++++++++++++++++++++++++++++++++--
1 files changed, 118 insertions(+), 8 deletions(-)
diff --git a/src/zhuye/MapRenderer.java b/src/zhuye/MapRenderer.java
index 5f5dd06..4562a15 100644
--- a/src/zhuye/MapRenderer.java
+++ b/src/zhuye/MapRenderer.java
@@ -50,6 +50,7 @@
private static final double CIRCLE_SAMPLE_SIZE = 0.54d;
private static final double BOUNDARY_POINT_MERGE_THRESHOLD = 0.05;
private static final double BOUNDARY_CONTAINS_TOLERANCE = 0.05;
+ private static final double PREVIEW_BOUNDARY_MARKER_SCALE = 0.25d;
// 缁勪欢寮曠敤
private JPanel visualizationPanel;
@@ -64,6 +65,8 @@
private String currentObstacleLandNumber;
private String boundaryName;
private boolean boundaryPointsVisible;
+ private double boundaryPointSizeScale = 1.0d;
+ private boolean previewSizingEnabled;
private String currentBoundaryLandNumber;
private boolean dragInProgress;
private final Gecaoji mower;
@@ -74,6 +77,7 @@
private final List<Point2D.Double> realtimeMowingTrack = new ArrayList<>();
private final Deque<tuowei.TrailSample> idleMowerTrail = new ArrayDeque<>();
private final List<Point2D.Double> handheldBoundaryPreview = new ArrayList<>();
+ private double boundaryPreviewMarkerScale = 1.0d;
private boolean realtimeTrackRecording;
private String realtimeTrackLandNumber;
private double mowerEffectiveWidthMeters;
@@ -264,19 +268,21 @@
drawCircleCaptureOverlay(g2d, circleCaptureOverlay, scale);
}
- adddikuaiyulan.drawPreview(g2d, handheldBoundaryPreview, scale, handheldBoundaryPreviewActive);
+ adddikuaiyulan.drawPreview(g2d, handheldBoundaryPreview, scale, handheldBoundaryPreviewActive, boundaryPreviewMarkerScale);
if (hasPlannedPath) {
drawCurrentPlannedPath(g2d);
}
if (boundaryPointsVisible && hasBoundary) {
+ double markerScale = boundaryPointSizeScale * (previewSizingEnabled ? PREVIEW_BOUNDARY_MARKER_SCALE : 1.0d);
pointandnumber.drawBoundaryPoints(
g2d,
currentBoundary,
scale,
BOUNDARY_POINT_MERGE_THRESHOLD,
- BOUNDARY_POINT_COLOR
+ BOUNDARY_POINT_COLOR,
+ markerScale
);
}
@@ -648,6 +654,10 @@
visualizationPanel.repaint();
}
+ public void clearIdleTrail() {
+ clearIdleMowerTrail();
+ }
+
public void setIdleTrailDurationSeconds(int seconds) {
int sanitized = seconds;
if (sanitized < 5 || sanitized > 600) {
@@ -865,7 +875,8 @@
}
private void drawCurrentPlannedPath(Graphics2D g2d) {
- lujingdraw.drawPlannedPath(g2d, currentPlannedPath, scale);
+ double arrowScale = previewSizingEnabled ? 0.5d : 1.0d;
+ lujingdraw.drawPlannedPath(g2d, currentPlannedPath, scale, arrowScale);
}
private void drawCircleSampleMarkers(Graphics2D g2d, List<double[]> markers, double scale) {
@@ -1054,7 +1065,11 @@
private double computeSelectionThresholdPixels() {
double scaleFactor = Math.max(0.5, scale);
- double markerDiameterWorld = Math.max(1.0, (10.0 / scaleFactor) * 0.2);
+ double diameterScale = boundaryPointSizeScale * (previewSizingEnabled ? PREVIEW_BOUNDARY_MARKER_SCALE : 1.0d);
+ if (!Double.isFinite(diameterScale) || diameterScale <= 0.0d) {
+ diameterScale = 1.0d;
+ }
+ double markerDiameterWorld = Math.max(1.0, (10.0 / scaleFactor) * 0.2 * diameterScale);
double markerDiameterPixels = markerDiameterWorld * scale;
return Math.max(8.0, markerDiameterPixels * 1.5);
}
@@ -1830,6 +1845,65 @@
visualizationPanel.repaint();
}
+ public void setBoundaryPointSizeScale(double sizeScale) {
+ double normalized = (Double.isFinite(sizeScale) && sizeScale > 0.0d) ? sizeScale : 1.0d;
+ if (Math.abs(boundaryPointSizeScale - normalized) < 1e-6) {
+ return;
+ }
+ boundaryPointSizeScale = normalized;
+ if (visualizationPanel == null) {
+ return;
+ }
+ if (SwingUtilities.isEventDispatchThread()) {
+ visualizationPanel.repaint();
+ } else {
+ SwingUtilities.invokeLater(visualizationPanel::repaint);
+ }
+ }
+
+ public void setPathPreviewSizingEnabled(boolean enabled) {
+ previewSizingEnabled = enabled;
+ if (visualizationPanel == null) {
+ return;
+ }
+ if (SwingUtilities.isEventDispatchThread()) {
+ visualizationPanel.repaint();
+ } else {
+ SwingUtilities.invokeLater(visualizationPanel::repaint);
+ }
+ }
+
+ public void setBoundaryPreviewMarkerScale(double markerScale) {
+ double normalized = Double.isFinite(markerScale) && markerScale > 0.0d ? markerScale : 1.0d;
+ if (Math.abs(boundaryPreviewMarkerScale - normalized) < 1e-6) {
+ return;
+ }
+ boundaryPreviewMarkerScale = normalized;
+ if (visualizationPanel == null) {
+ return;
+ }
+ if (SwingUtilities.isEventDispatchThread()) {
+ visualizationPanel.repaint();
+ } else {
+ SwingUtilities.invokeLater(visualizationPanel::repaint);
+ }
+ }
+
+ public boolean setHandheldMowerIconActive(boolean handheldActive) {
+ if (mower == null) {
+ return false;
+ }
+ boolean changed = mower.useHandheldIcon(handheldActive);
+ if (changed && visualizationPanel != null) {
+ if (SwingUtilities.isEventDispatchThread()) {
+ visualizationPanel.repaint();
+ } else {
+ SwingUtilities.invokeLater(visualizationPanel::repaint);
+ }
+ }
+ return changed;
+ }
+
public void beginHandheldBoundaryPreview() {
handheldBoundaryPreviewActive = true;
handheldBoundaryPreview.clear();
@@ -1859,6 +1933,7 @@
public void clearHandheldBoundaryPreview() {
handheldBoundaryPreviewActive = false;
handheldBoundaryPreview.clear();
+ boundaryPreviewMarkerScale = 1.0d;
visualizationPanel.repaint();
}
@@ -1914,8 +1989,10 @@
return;
}
- double width = Math.max(bounds.width, 1);
- double height = Math.max(bounds.height, 1);
+ Rectangle2D.Double targetBounds = includeMowerInBounds(bounds);
+
+ double width = Math.max(targetBounds.width, 1);
+ double height = Math.max(targetBounds.height, 1);
double targetWidth = width * 1.2;
double targetHeight = height * 1.2;
@@ -1927,8 +2004,41 @@
newScale = Math.max(0.05, Math.min(newScale, 50.0));
this.scale = newScale;
- this.translateX = -bounds.getCenterX();
- this.translateY = -bounds.getCenterY();
+ this.translateX = -targetBounds.getCenterX();
+ this.translateY = -targetBounds.getCenterY();
+ }
+
+ // Keep the mower marker inside the viewport whenever the camera refits to scene bounds.
+ private Rectangle2D.Double includeMowerInBounds(Rectangle2D.Double bounds) {
+ Rectangle2D.Double expanded = new Rectangle2D.Double(
+ bounds.x,
+ bounds.y,
+ Math.max(0.0, bounds.width),
+ Math.max(0.0, bounds.height)
+ );
+
+ if (mower == null || !mower.hasValidPosition()) {
+ return expanded;
+ }
+
+ Point2D.Double mowerPosition = mower.getPosition();
+ if (mowerPosition == null
+ || !Double.isFinite(mowerPosition.x)
+ || !Double.isFinite(mowerPosition.y)) {
+ return expanded;
+ }
+
+ double minX = Math.min(expanded.x, mowerPosition.x);
+ double minY = Math.min(expanded.y, mowerPosition.y);
+ double maxX = Math.max(expanded.x + expanded.width, mowerPosition.x);
+ double maxY = Math.max(expanded.y + expanded.height, mowerPosition.y);
+
+ expanded.x = minX;
+ expanded.y = minY;
+ expanded.width = Math.max(0.0, maxX - minX);
+ expanded.height = Math.max(0.0, maxY - minY);
+
+ return expanded;
}
public void dispose() {
--
Gitblit v1.10.0