From 2144172c7b961d4112850692ed77b46f1ae5d373 Mon Sep 17 00:00:00 2001
From: 张世豪 <979909237@qq.com>
Date: 星期五, 05 十二月 2025 19:34:53 +0800
Subject: [PATCH] 20251205
---
src/gecaoji/Gecaoji.java | 43 ++++++++++++++++++++++++++++++++++++++++---
1 files changed, 40 insertions(+), 3 deletions(-)
diff --git a/src/gecaoji/Gecaoji.java b/src/gecaoji/Gecaoji.java
index b5e142e..177832f 100644
--- a/src/gecaoji/Gecaoji.java
+++ b/src/gecaoji/Gecaoji.java
@@ -12,6 +12,7 @@
/** Mower rendering helper. */
public class Gecaoji {
private static final double ICON_PIXEL_SIZE = 48.0;
+ private static final double ICON_SCALE_FACTOR = 0.8;
private static final double MIN_SCALE = 1e-6;
private static final Color FALLBACK_FILL = new Color(0, 150, 0);
@@ -19,6 +20,7 @@
private final Ellipse2D.Double fallbackShape = new Ellipse2D.Double();
private Point2D.Double position = new Point2D.Double();
private boolean positionValid;
+ private double headingDegrees;
public Gecaoji() {
mowerIcon = loadIcon();
@@ -27,7 +29,7 @@
private Image loadIcon() {
try {
- ImageIcon icon = new ImageIcon("image/mow.png");
+ ImageIcon icon = new ImageIcon("image/gecaoji.png");
if (icon.getIconWidth() <= 0 || icon.getIconHeight() <= 0) {
return null;
}
@@ -47,6 +49,7 @@
double x = parseCoordinate(device.getRealtimeX());
double y = parseCoordinate(device.getRealtimeY());
+ double heading = parseHeading(device.getHeading());
if (Double.isNaN(x) || Double.isNaN(y)) {
positionValid = false;
return;
@@ -56,6 +59,7 @@
position.x = x;
position.y = y;
positionValid = true;
+ headingDegrees = heading;
}
private void ensurePosition() {
@@ -79,12 +83,32 @@
}
}
+ private double parseHeading(String value) {
+ if (value == null) {
+ return 0.0;
+ }
+ String trimmed = value.trim();
+ if (trimmed.isEmpty() || "-1".equals(trimmed)) {
+ return 0.0;
+ }
+ try {
+ double parsed = Double.parseDouble(trimmed);
+ if (!Double.isFinite(parsed)) {
+ return 0.0;
+ }
+ double normalized = parsed % 360.0;
+ return normalized < 0 ? normalized + 360.0 : normalized;
+ } catch (NumberFormatException ex) {
+ return 0.0;
+ }
+ }
+
public void draw(Graphics2D g2d, double scale) {
if (!positionValid) {
return;
}
- double worldSize = ICON_PIXEL_SIZE / Math.max(scale, MIN_SCALE);
+ double worldSize = (ICON_PIXEL_SIZE * ICON_SCALE_FACTOR) / Math.max(scale, MIN_SCALE);
if (mowerIcon != null && mowerIcon.getWidth(null) > 0 && mowerIcon.getHeight(null) > 0) {
drawIcon(g2d, worldSize);
} else {
@@ -97,10 +121,14 @@
double iconHeight = mowerIcon.getHeight(null);
double maxSide = Math.max(iconWidth, iconHeight);
double scaleFactor = worldSize / Math.max(maxSide, MIN_SCALE);
+ double rotationRadians = Math.toRadians(-headingDegrees);
AffineTransform original = g2d.getTransform();
AffineTransform transformed = new AffineTransform(original);
transformed.translate(position.x, position.y);
+ if (rotationRadians != 0.0) {
+ transformed.rotate(rotationRadians);
+ }
transformed.scale(scaleFactor, scaleFactor);
transformed.translate(-iconWidth / 2.0, -iconHeight / 2.0);
g2d.setTransform(transformed);
@@ -118,6 +146,15 @@
g2d.fill(fallbackShape);
g2d.setColor(Color.WHITE);
g2d.draw(fallbackShape);
+ double rotationRadians = Math.toRadians(-headingDegrees);
+ double lineLength = radius;
+ double dx = lineLength * Math.sin(rotationRadians);
+ double dy = lineLength * Math.cos(rotationRadians);
+ g2d.drawLine(
+ (int) Math.round(position.x),
+ (int) Math.round(position.y),
+ (int) Math.round(position.x + dx),
+ (int) Math.round(position.y + dy));
g2d.setColor(original);
}
@@ -137,7 +174,7 @@
if (!positionValid) {
return Double.NaN;
}
- double worldSize = ICON_PIXEL_SIZE / Math.max(scale, MIN_SCALE);
+ double worldSize = (ICON_PIXEL_SIZE * ICON_SCALE_FACTOR) / Math.max(scale, MIN_SCALE);
return worldSize / 2.0;
}
}
--
Gitblit v1.10.0