diff --git a/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs b/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs
index d4e9b53..e6a3d9f 100644
--- a/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs
+++ b/XP.ImageProcessing.RoiControl/Controls/PolygonRoiCanvas.xaml.cs
@@ -578,11 +578,87 @@ namespace XP.ImageProcessing.RoiControl.Controls
var g = new Models.MeasureGroup { P1 = p1, P2 = p2 };
g.Line = new Line { Stroke = Brushes.Lime, StrokeThickness = 1, IsHitTestVisible = false };
g.Label = new TextBlock { Foreground = Brushes.Yellow, FontSize = 13, FontWeight = FontWeights.Bold, IsHitTestVisible = false };
+
+ // 使用垂直线段代替圆点
+ g.PerpLine1 = new Line { Stroke = Brushes.Yellow, StrokeThickness = 1, IsHitTestVisible = true, Cursor = Cursors.Hand };
+ g.PerpLine2 = new Line { Stroke = Brushes.Yellow, StrokeThickness = 1, IsHitTestVisible = true, Cursor = Cursors.Hand };
+
+ // 保留圆点以兼容拖拽逻辑(但设为不可见)
g.Dot1 = CreateMDot(Brushes.Red);
g.Dot2 = CreateMDot(Brushes.Blue);
- foreach (UIElement el in new UIElement[] { g.Line, g.Label, g.Dot1, g.Dot2 })
+ g.Dot1.Visibility = Visibility.Collapsed;
+ g.Dot2.Visibility = Visibility.Collapsed;
+
+ foreach (UIElement el in new UIElement[] { g.Line, g.Label, g.PerpLine1, g.PerpLine2, g.Dot1, g.Dot2 })
_measureOverlay.Children.Add(el);
+
+ // 设置圆点位置(用于拖拽计算)
SetDotPos(g.Dot1, p1); SetDotPos(g.Dot2, p2);
+
+ // 垂直线段1的拖拽处理 - 直接设置拖拽状态
+ g.PerpLine1.MouseLeftButtonDown += (s, e) =>
+ {
+ _mDraggingOwner = g;
+ _mDraggingRole = "Dot1";
+ _mDraggingDot = g.Dot1;
+ g.PerpLine1.CaptureMouse();
+ e.Handled = true;
+ };
+ g.PerpLine1.MouseMove += (s, e) =>
+ {
+ if (_mDraggingOwner != g || _mDraggingRole != "Dot1" || _measureOverlay == null) return;
+ if (e.LeftButton != MouseButtonState.Pressed) return;
+ var pos = e.GetPosition(_measureOverlay);
+ SetDotPos(g.Dot1, pos);
+ g.P1 = pos;
+ g.UpdateLine();
+ g.UpdateLabel(FormatDistance(g.Distance));
+ RaiseMeasureCompleted(g.P1, g.P2, g.Distance, MeasureCount, "PointDistance");
+ };
+ g.PerpLine1.MouseLeftButtonUp += (s, e) =>
+ {
+ if (_mDraggingOwner == g && _mDraggingRole == "Dot1")
+ {
+ _mDraggingOwner = null;
+ _mDraggingRole = null;
+ _mDraggingDot = null;
+ g.PerpLine1.ReleaseMouseCapture();
+ }
+ e.Handled = true;
+ };
+
+ // 垂直线段2的拖拽处理
+ g.PerpLine2.MouseLeftButtonDown += (s, e) =>
+ {
+ _mDraggingOwner = g;
+ _mDraggingRole = "Dot2";
+ _mDraggingDot = g.Dot2;
+ g.PerpLine2.CaptureMouse();
+ e.Handled = true;
+ };
+ g.PerpLine2.MouseMove += (s, e) =>
+ {
+ if (_mDraggingOwner != g || _mDraggingRole != "Dot2" || _measureOverlay == null) return;
+ if (e.LeftButton != MouseButtonState.Pressed) return;
+ var pos = e.GetPosition(_measureOverlay);
+ SetDotPos(g.Dot2, pos);
+ g.P2 = pos;
+ g.UpdateLine();
+ g.UpdateLabel(FormatDistance(g.Distance));
+ RaiseMeasureCompleted(g.P1, g.P2, g.Distance, MeasureCount, "PointDistance");
+ };
+ g.PerpLine2.MouseLeftButtonUp += (s, e) =>
+ {
+ if (_mDraggingOwner == g && _mDraggingRole == "Dot2")
+ {
+ _mDraggingOwner = null;
+ _mDraggingRole = null;
+ _mDraggingDot = null;
+ g.PerpLine2.ReleaseMouseCapture();
+ }
+ e.Handled = true;
+ };
+
g.UpdateLine(); g.UpdateLabel(FormatDistance(g.Distance));
return g;
}
diff --git a/XP.ImageProcessing.RoiControl/Models/MeasureGroup.cs b/XP.ImageProcessing.RoiControl/Models/MeasureGroup.cs
index 32ba2aa..0c93043 100644
--- a/XP.ImageProcessing.RoiControl/Models/MeasureGroup.cs
+++ b/XP.ImageProcessing.RoiControl/Models/MeasureGroup.cs
@@ -9,12 +9,21 @@ namespace XP.ImageProcessing.RoiControl.Models
/// 一次点点距测量的所有视觉元素
public class MeasureGroup
{
+ // 保留原有圆点属性以兼容其他代码
public Ellipse Dot1 { get; set; }
public Ellipse Dot2 { get; set; }
+
+ // 新增:垂直线段(替代圆点的视觉表现)
+ public Line PerpLine1 { get; set; }
+ public Line PerpLine2 { get; set; }
+
public Line Line { get; set; }
public TextBlock Label { get; set; }
public Point P1 { get; set; }
public Point P2 { get; set; }
+
+ /// 垂直线段长度(像素)
+ public double PerpLineLength { get; set; } = 10.0;
public double Distance
{
@@ -30,6 +39,46 @@ namespace XP.ImageProcessing.RoiControl.Models
Line.X1 = P1.X; Line.Y1 = P1.Y;
Line.X2 = P2.X; Line.Y2 = P2.Y;
Line.Visibility = Visibility.Visible;
+
+ // 更新垂直线段位置
+ UpdatePerpLines();
+ }
+
+ /// 更新两条垂直线段的位置
+ public void UpdatePerpLines()
+ {
+ if (PerpLine1 == null || PerpLine2 == null) return;
+
+ // 计算两点连线的方向向量
+ double dx = P2.X - P1.X;
+ double dy = P2.Y - P1.Y;
+ double len = Math.Sqrt(dx * dx + dy * dy);
+
+ if (len < 0.001) return; // 避免除零
+
+ // 归一化方向向量
+ double ux = dx / len;
+ double uy = dy / len;
+
+ // 垂直方向向量 (-uy, ux)
+ double vx = -uy;
+ double vy = ux;
+
+ // P1处的垂直线段
+ double halfLen1 = PerpLineLength / 2;
+ PerpLine1.X1 = P1.X + vx * halfLen1;
+ PerpLine1.Y1 = P1.Y + vy * halfLen1;
+ PerpLine1.X2 = P1.X - vx * halfLen1;
+ PerpLine1.Y2 = P1.Y - vy * halfLen1;
+ PerpLine1.Visibility = Visibility.Visible;
+
+ // P2处的垂直线段
+ double halfLen2 = PerpLineLength / 2;
+ PerpLine2.X1 = P2.X + vx * halfLen2;
+ PerpLine2.Y1 = P2.Y + vy * halfLen2;
+ PerpLine2.X2 = P2.X - vx * halfLen2;
+ PerpLine2.Y2 = P2.Y - vy * halfLen2;
+ PerpLine2.Visibility = Visibility.Visible;
}
public void UpdateLabel(string distanceText = null)