package zhuye; import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; import java.awt.Shape; import java.awt.Stroke; import java.awt.geom.Ellipse2D; import java.awt.geom.Path2D; import java.awt.geom.Point2D; import java.util.List; /** * Utility renderer for handheld boundary previews. */ public final class adddikuaiyulan { private static final Color HANDHELD_BOUNDARY_FILL = new Color(51, 153, 255, 60); private static final Color HANDHELD_BOUNDARY_BORDER = new Color(0, 100, 0, 220); private static final Color HANDHELD_BOUNDARY_POINT = new Color(0, 100, 0); private static final double BASE_WORLD_MARKER_SIZE = 0.27d; // halve the base diameter for subtler markers private static final double MIN_PIXEL_DIAMETER = 3.0d; private static final double MAX_PIXEL_DIAMETER = 9.0d; private static volatile double cachedMarkerPixelDiameter = -1.0d; private adddikuaiyulan() { } public static void drawPreview(Graphics2D g2d, List previewPoints, double scale, boolean previewActive, double diameterScale) { if (!previewActive) { cachedMarkerPixelDiameter = -1.0d; } if (g2d == null || !previewActive || previewPoints == null || previewPoints.isEmpty()) { return; } // 过滤有效点 List validPoints = new java.util.ArrayList<>(); for (Point2D.Double point : previewPoints) { if (point != null && Double.isFinite(point.x) && Double.isFinite(point.y)) { validPoints.add(point); } } if (validPoints.isEmpty()) { return; } Stroke originalStroke = g2d.getStroke(); Color originalColor = g2d.getColor(); // 创建填充路径(如果点数>=3,需要闭合以填充) Path2D.Double fillPath = new Path2D.Double(); if (validPoints.size() >= 3) { fillPath.moveTo(validPoints.get(0).x, validPoints.get(0).y); for (int i = 1; i < validPoints.size(); i++) { fillPath.lineTo(validPoints.get(i).x, validPoints.get(i).y); } fillPath.closePath(); g2d.setColor(HANDHELD_BOUNDARY_FILL); g2d.fill(fillPath); } float outlineWidth = 0.1f; if (validPoints.size() >= 3) { // 点数>=3时,需要分别绘制实线和虚线 // 绘制实线部分:从起点依次连接到各个点(不闭合,不包括起点到终点的直接连线) Path2D.Double solidPath = new Path2D.Double(); solidPath.moveTo(validPoints.get(0).x, validPoints.get(0).y); // 从第二个点开始,依次连接到最后一个点(形成不闭合的路径) for (int i = 1; i < validPoints.size(); i++) { solidPath.lineTo(validPoints.get(i).x, validPoints.get(i).y); } g2d.setStroke(new BasicStroke(outlineWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); g2d.setColor(HANDHELD_BOUNDARY_BORDER); g2d.draw(solidPath); // 用虚线绘制起点到终点的连线(闭合线段) Point2D.Double startPoint = validPoints.get(0); Point2D.Double endPoint = validPoints.get(validPoints.size() - 1); // 创建虚线样式(根据缩放调整虚线模式) double effectiveScale = Math.max(0.01d, scale); float dashLength = (float) (0.05 / effectiveScale); // 虚线长度随缩放调整 float[] dashPattern = new float[]{dashLength, dashLength}; // 虚线模式:实线、空白 BasicStroke dashedStroke = new BasicStroke( outlineWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1.0f, dashPattern, 0.0f ); g2d.setStroke(dashedStroke); g2d.setColor(HANDHELD_BOUNDARY_BORDER); // 使用Path2D绘制起点到终点的虚线,以便支持浮点坐标 Path2D.Double dashedLine = new Path2D.Double(); dashedLine.moveTo(startPoint.x, startPoint.y); dashedLine.lineTo(endPoint.x, endPoint.y); g2d.draw(dashedLine); } else if (validPoints.size() == 2) { // 如果只有2个点,直接绘制实线 Path2D.Double simplePath = new Path2D.Double(); simplePath.moveTo(validPoints.get(0).x, validPoints.get(0).y); simplePath.lineTo(validPoints.get(1).x, validPoints.get(1).y); g2d.setStroke(new BasicStroke(outlineWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); g2d.setColor(HANDHELD_BOUNDARY_BORDER); g2d.draw(simplePath); } if (cachedMarkerPixelDiameter <= 0.0d) { double previousPixelDiameter = Math.abs(BASE_WORLD_MARKER_SIZE * scale); if (previousPixelDiameter <= 0.0d) { previousPixelDiameter = MIN_PIXEL_DIAMETER; } cachedMarkerPixelDiameter = Math.max(MIN_PIXEL_DIAMETER, Math.min(MAX_PIXEL_DIAMETER, previousPixelDiameter)); } double effectiveScale = Math.max(0.01d, scale); double markerSize = cachedMarkerPixelDiameter / effectiveScale; double normalizedScale = Double.isFinite(diameterScale) && diameterScale > 0.0d ? diameterScale : 1.0d; markerSize *= normalizedScale; double markerRadius = markerSize / 2.0d; for (Point2D.Double point : previewPoints) { if (point == null || !Double.isFinite(point.x) || !Double.isFinite(point.y)) { continue; } Shape marker = new Ellipse2D.Double(point.x - markerRadius, point.y - markerRadius, markerSize, markerSize); g2d.setColor(HANDHELD_BOUNDARY_POINT); g2d.fill(marker); } g2d.setStroke(originalStroke); g2d.setColor(originalColor); } }