张世豪
2025-12-01 d709e6dad60398fd599900cf781d0dd1e8c37c1c
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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
package zhangaiwu;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.List;
import java.util.ArrayList;
 
/**
 * 障碍物绘制类 - 负责绘制地块中的障碍物
 */
public class Obstacledraw {
    
    // 颜色定义
    private static final Color CIRCLE_FILL_COLOR = new Color(255, 182, 193, 120); // 圆形填充色 - 浅粉红
    private static final Color CIRCLE_BORDER_COLOR = new Color(199, 21, 133);    // 圆形边框色 - 深粉红
    private static final Color POLYGON_FILL_COLOR = new Color(173, 216, 230, 120); // 多边形填充色 - 浅蓝
    private static final Color POLYGON_BORDER_COLOR = new Color(25, 25, 112);    // 多边形边框色 - 深蓝
    private static final Color OBSTACLE_LABEL_COLOR = Color.BLACK;
    private static final Color OBSTACLE_POINT_COLOR = Color.RED;
    
    // 尺寸定义
    private static final double OBSTACLE_POINT_SIZE = 0.1; // 障碍物控制点大小(米)
    private static final float DEFAULT_BORDER_WIDTH = 1.0f;
    private static final float SELECTED_BORDER_WIDTH = 2.5f;
    
    /**
     * 绘制地块的所有障碍物
     * 
     * @param g2d 图形上下文
     * @param obstacles 障碍物列表
     * @param scale 缩放比例
     * @param selectedObstacleName 选中的障碍物名称(可为null)
     */
    public static void drawObstacles(Graphics2D g2d, List<Obstacledge.Obstacle> obstacles, 
                                     double scale, String selectedObstacleName) {
        if (obstacles == null || obstacles.isEmpty()) {
            return;
        }
        
        // 保存原始变换
        AffineTransform originalTransform = g2d.getTransform();
        
        // 应用反锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        
        // 绘制每个障碍物
        for (Obstacledge.Obstacle obstacle : obstacles) {
            if (obstacle == null || !obstacle.isValid()) {
                continue;
            }
            
            // 检查是否被选中
            boolean isSelected = selectedObstacleName != null && 
                                selectedObstacleName.equals(obstacle.getObstacleName());
            
            // 根据形状绘制
            switch (obstacle.getShape()) {
                case CIRCLE:
                    drawCircleObstacle(g2d, obstacle, scale, isSelected);
                    break;
                case POLYGON:
                    drawPolygonObstacle(g2d, obstacle, scale, isSelected);
                    break;
            }
            
            // 绘制障碍物标签
            drawObstacleLabel(g2d, obstacle, scale);
        }
        
        // 恢复原始变换
        g2d.setTransform(originalTransform);
    }
    
    /**
     * 绘制圆形障碍物
     */
    private static void drawCircleObstacle(Graphics2D g2d, Obstacledge.Obstacle obstacle, 
                                           double scale, boolean isSelected) {
        List<Obstacledge.XYCoordinate> xyCoords = obstacle.getXyCoordinates();
        if (xyCoords.size() < 2) {
            return;
        }
        
        // 获取圆心和圆上一点
        Obstacledge.XYCoordinate center = xyCoords.get(0);
        Obstacledge.XYCoordinate pointOnCircle = xyCoords.get(1);
        
        // 计算半径
        double dx = pointOnCircle.getX() - center.getX();
        double dy = pointOnCircle.getY() - center.getY();
        double radius = Math.sqrt(dx * dx + dy * dy);
        
        if (radius <= 0) {
            return;
        }
        
        // 计算绘制位置
        double x = center.getX() - radius;
        double y = center.getY() - radius;
        double diameter = radius * 2;
        
        // 绘制圆形
        Ellipse2D.Double circle = new Ellipse2D.Double(x, y, diameter, diameter);
        
        // 设置填充颜色
        g2d.setColor(CIRCLE_FILL_COLOR);
        g2d.fill(circle);
        
        // 设置边框颜色和宽度
        if (isSelected) {
            g2d.setColor(CIRCLE_BORDER_COLOR.darker());
            g2d.setStroke(new BasicStroke(SELECTED_BORDER_WIDTH / (float)scale));
        } else {
            g2d.setColor(CIRCLE_BORDER_COLOR);
            g2d.setStroke(new BasicStroke(DEFAULT_BORDER_WIDTH / (float)scale));
        }
        g2d.draw(circle);
        
        // 绘制圆心和控制点
        drawControlPoints(g2d, obstacle, scale, isSelected);
    }
    
    /**
     * 绘制多边形障碍物
     */
    private static void drawPolygonObstacle(Graphics2D g2d, Obstacledge.Obstacle obstacle, 
                                            double scale, boolean isSelected) {
        List<Obstacledge.XYCoordinate> xyCoords = obstacle.getXyCoordinates();
        if (xyCoords.size() < 3) {
            return;
        }
        
        // 创建多边形路径
        Path2D.Double polygon = new Path2D.Double();
        
        // 移动到第一个点
        Obstacledge.XYCoordinate firstCoord = xyCoords.get(0);
        polygon.moveTo(firstCoord.getX(), firstCoord.getY());
        
        // 添加其他点
        for (int i = 1; i < xyCoords.size(); i++) {
            Obstacledge.XYCoordinate coord = xyCoords.get(i);
            polygon.lineTo(coord.getX(), coord.getY());
        }
        
        // 闭合多边形
        polygon.closePath();
        
        // 设置填充颜色
        g2d.setColor(POLYGON_FILL_COLOR);
        g2d.fill(polygon);
        
        // 设置边框颜色和宽度
        if (isSelected) {
            g2d.setColor(POLYGON_BORDER_COLOR.darker());
            g2d.setStroke(new BasicStroke(SELECTED_BORDER_WIDTH / (float)scale));
        } else {
            g2d.setColor(POLYGON_BORDER_COLOR);
            g2d.setStroke(new BasicStroke(DEFAULT_BORDER_WIDTH / (float)scale));
        }
        g2d.draw(polygon);
        
        // 绘制控制点
        drawControlPoints(g2d, obstacle, scale, isSelected);
    }
    
    /**
     * 绘制障碍物控制点
     */
    private static void drawControlPoints(Graphics2D g2d, Obstacledge.Obstacle obstacle, 
                                          double scale, boolean isSelected) {
        List<Obstacledge.XYCoordinate> xyCoords = obstacle.getXyCoordinates();
        if (xyCoords.isEmpty()) {
            return;
        }
        
        // 设置控制点颜色和大小
        g2d.setColor(OBSTACLE_POINT_COLOR);
        double pointSize = OBSTACLE_POINT_SIZE;
        
        // 如果是选中的障碍物,绘制所有控制点
        if (isSelected) {
            for (Obstacledge.XYCoordinate coord : xyCoords) {
                double x = coord.getX() - pointSize / 2;
                double y = coord.getY() - pointSize / 2;
                Ellipse2D.Double point = new Ellipse2D.Double(x, y, pointSize, pointSize);
                g2d.fill(point);
            }
        } 
        // 否则,只绘制第一个控制点(圆形障碍物为圆心,多边形障碍物为第一个顶点)
        else {
            Obstacledge.XYCoordinate firstCoord = xyCoords.get(0);
            double x = firstCoord.getX() - pointSize / 2;
            double y = firstCoord.getY() - pointSize / 2;
            Ellipse2D.Double point = new Ellipse2D.Double(x, y, pointSize, pointSize);
            g2d.fill(point);
        }
    }
    
    /**
     * 绘制障碍物标签
     */
    private static void drawObstacleLabel(Graphics2D g2d, Obstacledge.Obstacle obstacle, 
                                          double scale) {
        List<Obstacledge.XYCoordinate> xyCoords = obstacle.getXyCoordinates();
        if (xyCoords.isEmpty()) {
            return;
        }
        
        // 计算标签位置(中心点)
        double centerX = 0;
        double centerY = 0;
        
        for (Obstacledge.XYCoordinate coord : xyCoords) {
            centerX += coord.getX();
            centerY += coord.getY();
        }
        
        centerX /= xyCoords.size();
        centerY /= xyCoords.size();
        
        // 获取障碍物名称和形状
        String obstacleName = obstacle.getObstacleName();
        String shapeDesc = obstacle.getShape().getDescription();
        
        // 设置字体和颜色
        g2d.setColor(OBSTACLE_LABEL_COLOR);
        
        // 根据缩放比例调整字体大小
        int fontSize = (int)(10 / scale);
        fontSize = Math.max(8, Math.min(fontSize, 14)); // 限制字体大小范围
        
        g2d.setFont(new Font("微软雅黑", Font.PLAIN, fontSize));
        
        // 绘制标签
        String label = String.format("%s(%s)", obstacleName, shapeDesc);
        FontMetrics metrics = g2d.getFontMetrics();
        int textWidth = metrics.stringWidth(label);
        int textHeight = metrics.getHeight();
        
        // 在中心点绘制标签
        int textX = (int)(centerX - textWidth / 2.0);
        int textY = (int)(centerY + textHeight / 4.0); // 稍微向下偏移
        
        g2d.drawString(label, textX, textY);
    }
    
    /**
     * 检查点是否在障碍物内
     * 
     * @param worldPoint 世界坐标点
     * @param obstacle 障碍物
     * @return 如果点在障碍物内返回true,否则返回false
     */
    public static boolean isPointInObstacle(Point2D.Double worldPoint, Obstacledge.Obstacle obstacle) {
        if (worldPoint == null || obstacle == null || !obstacle.isValid()) {
            return false;
        }
        
        List<Obstacledge.XYCoordinate> xyCoords = obstacle.getXyCoordinates();
        if (xyCoords.isEmpty()) {
            return false;
        }
        
        // 根据障碍物形状进行判断
        switch (obstacle.getShape()) {
            case CIRCLE:
                return isPointInCircleObstacle(worldPoint, xyCoords);
            case POLYGON:
                return isPointInPolygonObstacle(worldPoint, xyCoords);
            default:
                return false;
        }
    }
    
    /**
     * 检查点是否在圆形障碍物内
     */
    private static boolean isPointInCircleObstacle(Point2D.Double worldPoint, 
                                                   List<Obstacledge.XYCoordinate> xyCoords) {
        if (xyCoords.size() < 2) {
            return false;
        }
        
        // 圆心
        Obstacledge.XYCoordinate center = xyCoords.get(0);
        
        // 圆上一点
        Obstacledge.XYCoordinate pointOnCircle = xyCoords.get(1);
        
        // 计算半径
        double dx = pointOnCircle.getX() - center.getX();
        double dy = pointOnCircle.getY() - center.getY();
        double radius = Math.sqrt(dx * dx + dy * dy);
        
        // 计算点到圆心的距离
        double pointDx = worldPoint.x - center.getX();
        double pointDy = worldPoint.y - center.getY();
        double distance = Math.sqrt(pointDx * pointDx + pointDy * pointDy);
        
        return distance <= radius;
    }
    
    /**
     * 检查点是否在多边形障碍物内
     */
    private static boolean isPointInPolygonObstacle(Point2D.Double worldPoint, 
                                                    List<Obstacledge.XYCoordinate> xyCoords) {
        if (xyCoords.size() < 3) {
            return false;
        }
        
        // 使用射线法判断点是否在多边形内
        boolean inside = false;
        int n = xyCoords.size();
        
        for (int i = 0, j = n - 1; i < n; j = i++) {
            double xi = xyCoords.get(i).getX();
            double yi = xyCoords.get(i).getY();
            double xj = xyCoords.get(j).getX();
            double yj = xyCoords.get(j).getY();
            
            boolean intersect = ((yi > worldPoint.y) != (yj > worldPoint.y)) &&
                               (worldPoint.x < (xj - xi) * (worldPoint.y - yi) / (yj - yi) + xi);
            
            if (intersect) {
                inside = !inside;
            }
        }
        
        return inside;
    }
    
    /**
     * 检查点是否在障碍物的控制点上
     * 
     * @param worldPoint 世界坐标点
     * @param obstacle 障碍物
     * @param scale 缩放比例
     * @return 控制点索引(从0开始),如果不在控制点上返回-1
     */
    public static int getControlPointIndex(Point2D.Double worldPoint, 
                                           Obstacledge.Obstacle obstacle, 
                                           double scale) {
        if (worldPoint == null || obstacle == null || !obstacle.isValid()) {
            return -1;
        }
        
        List<Obstacledge.XYCoordinate> xyCoords = obstacle.getXyCoordinates();
        if (xyCoords.isEmpty()) {
            return -1;
        }
        
        // 根据障碍物形状计算选择阈值
        double selectionThreshold = OBSTACLE_POINT_SIZE * 2 / scale;
        
        // 检查每个控制点
        for (int i = 0; i < xyCoords.size(); i++) {
            Obstacledge.XYCoordinate coord = xyCoords.get(i);
            
            double dx = worldPoint.x - coord.getX();
            double dy = worldPoint.y - coord.getY();
            double distance = Math.sqrt(dx * dx + dy * dy);
            
            if (distance <= selectionThreshold) {
                return i;
            }
        }
        
        return -1;
    }
    
    /**
     * 获取障碍物的边界框
     * 
     * @param obstacle 障碍物
     * @return 边界框(minX, minY, maxX, maxY),如果无效返回null
     */
    public static double[] getObstacleBounds(Obstacledge.Obstacle obstacle) {
        if (obstacle == null || !obstacle.isValid()) {
            return null;
        }
        
        List<Obstacledge.XYCoordinate> xyCoords = obstacle.getXyCoordinates();
        if (xyCoords.isEmpty()) {
            return null;
        }
        
        double minX = Double.MAX_VALUE;
        double minY = Double.MAX_VALUE;
        double maxX = -Double.MAX_VALUE;
        double maxY = -Double.MAX_VALUE;
        
        // 根据障碍物形状计算边界
        switch (obstacle.getShape()) {
            case CIRCLE:
                return getCircleObstacleBounds(xyCoords);
            case POLYGON:
                return getPolygonObstacleBounds(xyCoords);
            default:
                return null;
        }
    }
    
    /**
     * 获取圆形障碍物的边界框
     */
    private static double[] getCircleObstacleBounds(List<Obstacledge.XYCoordinate> xyCoords) {
        if (xyCoords.size() < 2) {
            return null;
        }
        
        // 圆心
        Obstacledge.XYCoordinate center = xyCoords.get(0);
        
        // 圆上一点
        Obstacledge.XYCoordinate pointOnCircle = xyCoords.get(1);
        
        // 计算半径
        double dx = pointOnCircle.getX() - center.getX();
        double dy = pointOnCircle.getY() - center.getY();
        double radius = Math.sqrt(dx * dx + dy * dy);
        
        // 计算边界
        double minX = center.getX() - radius;
        double minY = center.getY() - radius;
        double maxX = center.getX() + radius;
        double maxY = center.getY() + radius;
        
        return new double[]{minX, minY, maxX, maxY};
    }
    
    /**
     * 获取多边形障碍物的边界框
     */
    private static double[] getPolygonObstacleBounds(List<Obstacledge.XYCoordinate> xyCoords) {
        if (xyCoords.size() < 3) {
            return null;
        }
        
        double minX = Double.MAX_VALUE;
        double minY = Double.MAX_VALUE;
        double maxX = -Double.MAX_VALUE;
        double maxY = -Double.MAX_VALUE;
        
        for (Obstacledge.XYCoordinate coord : xyCoords) {
            minX = Math.min(minX, coord.getX());
            minY = Math.min(minY, coord.getY());
            maxX = Math.max(maxX, coord.getX());
            maxY = Math.max(maxY, coord.getY());
        }
        
        return new double[]{minX, minY, maxX, maxY};
    }
    
    /**
     * 将障碍物列表转换为绘图用的点列表
     * 
     * @param obstacles 障碍物列表
     * @return 所有障碍物控制点的列表
     */
    public static List<Point2D.Double> getObstaclePoints(List<Obstacledge.Obstacle> obstacles) {
        List<Point2D.Double> points = new ArrayList<>();
        
        if (obstacles == null || obstacles.isEmpty()) {
            return points;
        }
        
        for (Obstacledge.Obstacle obstacle : obstacles) {
            if (obstacle == null || !obstacle.isValid()) {
                continue;
            }
            
            List<Obstacledge.XYCoordinate> xyCoords = obstacle.getXyCoordinates();
            for (Obstacledge.XYCoordinate coord : xyCoords) {
                points.add(new Point2D.Double(coord.getX(), coord.getY()));
            }
        }
        
        return points;
    }
    
    /**
     * 计算所有障碍物的总边界框
     * 
     * @param obstacles 障碍物列表
     * @return 边界框(minX, minY, maxX, maxY),如果没有障碍物返回null
     */
    public static double[] getAllObstaclesBounds(List<Obstacledge.Obstacle> obstacles) {
        if (obstacles == null || obstacles.isEmpty()) {
            return null;
        }
        
        double minX = Double.MAX_VALUE;
        double minY = Double.MAX_VALUE;
        double maxX = -Double.MAX_VALUE;
        double maxY = -Double.MAX_VALUE;
        boolean hasBounds = false;
        
        for (Obstacledge.Obstacle obstacle : obstacles) {
            double[] bounds = getObstacleBounds(obstacle);
            if (bounds != null) {
                minX = Math.min(minX, bounds[0]);
                minY = Math.min(minY, bounds[1]);
                maxX = Math.max(maxX, bounds[2]);
                maxY = Math.max(maxY, bounds[3]);
                hasBounds = true;
            }
        }
        
        if (!hasBounds) {
            return null;
        }
        
        return new double[]{minX, minY, maxX, maxY};
    }
    
    /**
     * 绘制障碍物编辑模式下的辅助线
     * 
     * @param g2d 图形上下文
     * @param obstacle 障碍物
     * @param scale 缩放比例
     * @param isDragging 是否正在拖拽
     * @param dragPointIndex 拖拽的控制点索引
     */
    public static void drawEditingGuide(Graphics2D g2d, Obstacledge.Obstacle obstacle, 
                                        double scale, boolean isDragging, int dragPointIndex) {
        if (obstacle == null || !obstacle.isValid()) {
            return;
        }
        
        List<Obstacledge.XYCoordinate> xyCoords = obstacle.getXyCoordinates();
        if (xyCoords.isEmpty()) {
            return;
        }
        
        // 设置辅助线样式
        g2d.setColor(new Color(0, 100, 0, 150)); // 半透明的深绿色
        g2d.setStroke(new BasicStroke(1.0f / (float)scale, 
                                      BasicStroke.CAP_ROUND, 
                                      BasicStroke.JOIN_ROUND, 
                                      1.0f, 
                                      new float[]{5.0f / (float)scale, 5.0f / (float)scale}, 
                                      0.0f));
        
        // 根据障碍物形状绘制辅助线
        switch (obstacle.getShape()) {
            case CIRCLE:
                drawCircleEditingGuide(g2d, xyCoords, isDragging, dragPointIndex);
                break;
            case POLYGON:
                drawPolygonEditingGuide(g2d, xyCoords, isDragging, dragPointIndex);
                break;
        }
    }
    
    /**
     * 绘制圆形障碍物编辑模式下的辅助线
     */
    private static void drawCircleEditingGuide(Graphics2D g2d, 
                                               List<Obstacledge.XYCoordinate> xyCoords,
                                               boolean isDragging, int dragPointIndex) {
        if (xyCoords.size() < 2) {
            return;
        }
        
        Obstacledge.XYCoordinate center = xyCoords.get(0);
        Obstacledge.XYCoordinate pointOnCircle = xyCoords.get(1);
        
        // 绘制半径线
        g2d.drawLine((int)center.getX(), (int)center.getY(), 
                     (int)pointOnCircle.getX(), (int)pointOnCircle.getY());
        
        // 绘制中心十字线
        int crossSize = 5;
        g2d.drawLine((int)center.getX() - crossSize, (int)center.getY(), 
                     (int)center.getX() + crossSize, (int)center.getY());
        g2d.drawLine((int)center.getX(), (int)center.getY() - crossSize, 
                     (int)center.getX(), (int)center.getY() + crossSize);
        
        // 如果正在拖拽控制点,绘制拖拽线
        if (isDragging && dragPointIndex >= 0 && dragPointIndex < xyCoords.size()) {
            g2d.setColor(Color.RED);
            g2d.setStroke(new BasicStroke(2.0f));
            
            Obstacledge.XYCoordinate draggedPoint = xyCoords.get(dragPointIndex);
            
            // 绘制从控制点到鼠标的连线
            // 这里需要外部传入鼠标位置,暂时不实现
        }
    }
    
    /**
     * 绘制多边形障碍物编辑模式下的辅助线
     */
    private static void drawPolygonEditingGuide(Graphics2D g2d, 
                                                List<Obstacledge.XYCoordinate> xyCoords,
                                                boolean isDragging, int dragPointIndex) {
        if (xyCoords.size() < 3) {
            return;
        }
        
        // 绘制顶点之间的辅助线
        int n = xyCoords.size();
        for (int i = 0; i < n; i++) {
            Obstacledge.XYCoordinate current = xyCoords.get(i);
            Obstacledge.XYCoordinate next = xyCoords.get((i + 1) % n);
            
            g2d.drawLine((int)current.getX(), (int)current.getY(), 
                         (int)next.getX(), (int)next.getY());
            
            // 绘制每个顶点的十字线
            int crossSize = 3;
            g2d.drawLine((int)current.getX() - crossSize, (int)current.getY(), 
                         (int)current.getX() + crossSize, (int)current.getY());
            g2d.drawLine((int)current.getX(), (int)current.getY() - crossSize, 
                         (int)current.getX(), (int)current.getY() + crossSize);
        }
        
        // 如果正在拖拽控制点,绘制拖拽线
        if (isDragging && dragPointIndex >= 0 && dragPointIndex < xyCoords.size()) {
            g2d.setColor(Color.RED);
            g2d.setStroke(new BasicStroke(2.0f));
            
            Obstacledge.XYCoordinate draggedPoint = xyCoords.get(dragPointIndex);
            
            // 绘制从控制点到鼠标的连线
            // 这里需要外部传入鼠标位置,暂时不实现
        }
    }
}