Files
XplorePlane/XP.ImageProcessing.RoiControl/Models/PointToLineGroup.cs
T
2026-04-24 10:53:51 +08:00

97 lines
3.5 KiB
C#

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Shapes;
namespace XP.ImageProcessing.RoiControl.Models
{
/// <summary>一次点线距测量的所有视觉元素(直线两端点 + 测量点 + 垂线 + 标签)</summary>
public class PointToLineGroup
{
public Ellipse DotL1 { get; set; } // 直线端点1
public Ellipse DotL2 { get; set; } // 直线端点2
public Ellipse DotP { get; set; } // 测量点
public Line MainLine { get; set; } // 原始线段(实线)
public Line ExtLine { get; set; } // 延长线(虚线)
public Line PerpLine { get; set; } // 垂线(测量点→垂足)
public Ellipse FootDot { get; set; } // 垂足
public TextBlock Label { get; set; }
public Point L1 { get; set; }
public Point L2 { get; set; }
public Point P { get; set; }
public double Distance
{
get
{
double abx = L2.X - L1.X, aby = L2.Y - L1.Y;
double abLen = Math.Sqrt(abx * abx + aby * aby);
if (abLen < 0.001) return 0;
return Math.Abs(abx * (L1.Y - P.Y) - aby * (L1.X - P.X)) / abLen;
}
}
public Point FootPoint
{
get
{
double abx = L2.X - L1.X, aby = L2.Y - L1.Y;
double abLen2 = abx * abx + aby * aby;
if (abLen2 < 0.001) return L1;
double t = ((P.X - L1.X) * abx + (P.Y - L1.Y) * aby) / abLen2;
return new Point(L1.X + t * abx, L1.Y + t * aby);
}
}
public void UpdateVisuals(string distanceText)
{
double abx = L2.X - L1.X, aby = L2.Y - L1.Y;
double abLen2 = abx * abx + aby * aby;
double t = abLen2 < 0.001 ? 0 : ((P.X - L1.X) * abx + (P.Y - L1.Y) * aby) / abLen2;
var foot = FootPoint;
// 主直线:始终画原始线段
MainLine.X1 = L1.X; MainLine.Y1 = L1.Y;
MainLine.X2 = L2.X; MainLine.Y2 = L2.Y;
MainLine.Visibility = Visibility.Visible;
// 延长线:垂足在线段外时画虚线延伸
if (t < 0)
{
ExtLine.X1 = foot.X; ExtLine.Y1 = foot.Y;
ExtLine.X2 = L1.X; ExtLine.Y2 = L1.Y;
ExtLine.Visibility = Visibility.Visible;
}
else if (t > 1)
{
ExtLine.X1 = L2.X; ExtLine.Y1 = L2.Y;
ExtLine.X2 = foot.X; ExtLine.Y2 = foot.Y;
ExtLine.Visibility = Visibility.Visible;
}
else
{
ExtLine.Visibility = Visibility.Collapsed;
}
// 垂线
PerpLine.X1 = P.X; PerpLine.Y1 = P.Y;
PerpLine.X2 = foot.X; PerpLine.Y2 = foot.Y;
PerpLine.Visibility = Visibility.Visible;
// 垂足
Canvas.SetLeft(FootDot, foot.X - FootDot.Width / 2);
Canvas.SetTop(FootDot, foot.Y - FootDot.Height / 2);
FootDot.Visibility = Visibility.Visible;
// 标签
Label.Text = distanceText ?? $"{Distance:F2} px";
Canvas.SetLeft(Label, (P.X + foot.X) / 2 + 8);
Canvas.SetTop(Label, (P.Y + foot.Y) / 2 - 18);
Label.Visibility = Visibility.Visible;
}
public void UpdateVisuals() => UpdateVisuals(null);
}
}