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);
|
}
|
}
|