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