张世豪
4 天以前 87d7cf316e983b0398b270de03a8092412af8487
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
package bianjie;
 
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.List;
 
/**
 * 手动绘制边界绘制器
 * 用于处理手动绘制边界模式的所有功能
 */
public class shudongdraw {
    
    // 手动绘制边界模式状态
    private boolean manualBoundaryDrawingMode = false;
    
    // 手动绘制的边界点列表
    private final List<Point2D.Double> manualBoundaryPoints = new ArrayList<>();
    
    // 鼠标实时位置(世界坐标)
    private Point2D.Double manualBoundaryMousePosition = null;
    
    // 颜色定义
    private static final Color MANUAL_BOUNDARY_COLOR = new Color(255, 0, 0); // 红色
    private static final Color MANUAL_BOUNDARY_FILL_COLOR = new Color(255, 0, 0, 50); // 半透明红色填充
    private static final Color MOUSE_POSITION_COLOR = new Color(255, 0, 0, 128); // 半透明红色(鼠标位置)
    
    /**
     * 设置手动绘制边界模式
     */
    public void setManualBoundaryDrawingMode(boolean active) {
        manualBoundaryDrawingMode = active;
        if (!active) {
            manualBoundaryPoints.clear();
            manualBoundaryMousePosition = null;
        }
    }
    
    /**
     * 检查手动绘制边界模式是否激活
     */
    public boolean isManualBoundaryDrawingMode() {
        return manualBoundaryDrawingMode;
    }
    
    /**
     * 处理鼠标点击,添加边界点
     */
    public boolean handleClick(Point2D.Double worldPoint) {
        if (!manualBoundaryDrawingMode) {
            return false;
        }
        manualBoundaryPoints.add(worldPoint);
        return true;
    }
    
    /**
     * 更新鼠标位置
     */
    public void updateMousePosition(Point2D.Double worldPoint) {
        if (manualBoundaryDrawingMode) {
            manualBoundaryMousePosition = worldPoint;
        } else {
            manualBoundaryMousePosition = null;
        }
    }
    
    /**
     * 清除鼠标位置
     */
    public void clearMousePosition() {
        manualBoundaryMousePosition = null;
    }
    
    /**
     * 获取手动绘制的边界点列表
     */
    public List<Point2D.Double> getManualBoundaryPoints() {
        return new ArrayList<>(manualBoundaryPoints);
    }
    
    /**
     * 清空手动绘制的边界点
     */
    public void clearManualBoundaryPoints() {
        manualBoundaryPoints.clear();
    }
    
    /**
     * 绘制手动绘制的边界
     */
    public void drawBoundary(Graphics2D g2d, double scale) {
        if (!manualBoundaryDrawingMode || manualBoundaryPoints.isEmpty()) {
            return;
        }
        
        List<Point2D.Double> points = manualBoundaryPoints;
        if (points == null || points.isEmpty()) {
            return;
        }
        
        // 保存原始状态
        Color originalColor = g2d.getColor();
        BasicStroke originalStroke = (BasicStroke) g2d.getStroke();
        
        // 如果点数>=3,绘制填充区域
        if (points.size() >= 3) {
            Path2D.Double fillPath = new Path2D.Double();
            fillPath.moveTo(points.get(0).x, points.get(0).y);
            for (int i = 1; i < points.size(); i++) {
                fillPath.lineTo(points.get(i).x, points.get(i).y);
            }
            fillPath.closePath(); // 自动连接起点和终点
            
            g2d.setColor(MANUAL_BOUNDARY_FILL_COLOR);
            g2d.fill(fillPath);
        }
        
        // 计算线条宽度(用于绘制点和边界线)
        float strokeWidth = (float) (3 / Math.max(0.5, scale));
        
        // 绘制边界线(至少需要2个点)
        if (points.size() >= 2) {
            g2d.setStroke(new BasicStroke(strokeWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
            g2d.setColor(MANUAL_BOUNDARY_COLOR);
            
            Path2D.Double borderPath = new Path2D.Double();
            borderPath.moveTo(points.get(0).x, points.get(0).y);
            for (int i = 1; i < points.size(); i++) {
                borderPath.lineTo(points.get(i).x, points.get(i).y);
            }
            // 自动连接起点和终点
            if (points.size() >= 3) {
                borderPath.closePath();
            }
            g2d.draw(borderPath);
        }
        
        // 绘制点标记 - 实心圆圈,圆圈直径是线条宽度的2倍
        // 即使只有一个点也要绘制
        if (points.size() >= 1) {
            // 将线条宽度转换为世界坐标的直径,直径是线条宽度的2倍
            double pointDiameter = (strokeWidth * 2) / scale;
            g2d.setColor(MANUAL_BOUNDARY_COLOR);
            for (Point2D.Double point : points) {
                Ellipse2D.Double marker = new Ellipse2D.Double(
                    point.x - pointDiameter / 2,
                    point.y - pointDiameter / 2,
                    pointDiameter,
                    pointDiameter
                );
                g2d.fill(marker); // 实心圆圈
            }
        }
        
        // 恢复原始状态
        g2d.setColor(originalColor);
        g2d.setStroke(originalStroke);
    }
    
    /**
     * 绘制鼠标实时位置(手动绘制边界模式时)
     */
    public void drawMousePosition(Graphics2D g2d, double scale) {
        if (!manualBoundaryDrawingMode || manualBoundaryMousePosition == null) {
            return;
        }
        
        Point2D.Double mousePos = manualBoundaryMousePosition;
        if (mousePos == null || !Double.isFinite(mousePos.x) || !Double.isFinite(mousePos.y)) {
            return;
        }
        
        // 保存原始状态
        Color originalColor = g2d.getColor();
        BasicStroke originalStroke = (BasicStroke) g2d.getStroke();
        
        // 计算线条宽度
        float strokeWidth = (float) (3 / Math.max(0.5, scale));
        // 鼠标位置圆圈直径是线条宽度的2倍
        double mouseCircleDiameter = (strokeWidth * 2) / scale;
        
        // 绘制鼠标位置的圆圈(使用半透明颜色)
        g2d.setColor(MOUSE_POSITION_COLOR);
        
        Ellipse2D.Double mouseCircle = new Ellipse2D.Double(
            mousePos.x - mouseCircleDiameter / 2,
            mousePos.y - mouseCircleDiameter / 2,
            mouseCircleDiameter,
            mouseCircleDiameter
        );
        g2d.fill(mouseCircle);
        
        // 恢复原始状态
        g2d.setColor(originalColor);
        g2d.setStroke(originalStroke);
    }
}