张世豪
12 小时以前 ed6936545d20cc490145d2936cee4387be2afd53
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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<Point2D.Double> previewPoints,
                                   double scale,
                                   boolean previewActive,
                                   double diameterScale) {
        if (!previewActive) {
            cachedMarkerPixelDiameter = -1.0d;
        }
 
        if (g2d == null || !previewActive || previewPoints == null || previewPoints.isEmpty()) {
            return;
        }
 
        // 过滤有效点
        List<Point2D.Double> 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);
    }
}