88 lines
3.1 KiB
C#
88 lines
3.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Media;
|
|
using System.Windows.Shapes;
|
|
|
|
namespace XP.ImageProcessing.RoiControl.Models
|
|
{
|
|
/// <summary>BGA 空隙测量中的一个圆(气泡或焊球)</summary>
|
|
public class BgaCircle
|
|
{
|
|
public Ellipse Shape { get; set; } // 圆形轮廓
|
|
public Ellipse CenterDot { get; set; } // 中心拖拽点
|
|
public Ellipse EdgeDot { get; set; } // 边缘拖拽点(调半径)
|
|
public Point Center { get; set; }
|
|
public double Radius { get; set; }
|
|
public bool IsBall { get; set; } // true=焊球, false=气泡
|
|
|
|
public double Area => Math.PI * Radius * Radius;
|
|
|
|
public void UpdateVisuals()
|
|
{
|
|
double d = Radius * 2;
|
|
Shape.Width = d; Shape.Height = d;
|
|
Canvas.SetLeft(Shape, Center.X - Radius);
|
|
Canvas.SetTop(Shape, Center.Y - Radius);
|
|
|
|
Canvas.SetLeft(CenterDot, Center.X - CenterDot.Width / 2);
|
|
Canvas.SetTop(CenterDot, Center.Y - CenterDot.Height / 2);
|
|
|
|
var edgePt = new Point(Center.X + Radius, Center.Y);
|
|
Canvas.SetLeft(EdgeDot, edgePt.X - EdgeDot.Width / 2);
|
|
Canvas.SetTop(EdgeDot, edgePt.Y - EdgeDot.Height / 2);
|
|
}
|
|
}
|
|
|
|
/// <summary>一次 BGA 空隙测量组(1个焊球 + N个气泡 + 标签)</summary>
|
|
public class BgaVoidGroup
|
|
{
|
|
public BgaCircle Ball { get; set; }
|
|
public List<BgaCircle> Voids { get; } = new();
|
|
public TextBlock Label { get; set; }
|
|
public int Index { get; set; }
|
|
public double VoidLimit { get; set; } = 25.0;
|
|
|
|
public double VoidRate
|
|
{
|
|
get
|
|
{
|
|
if (Ball == null || Ball.Area < 1) return 0;
|
|
double totalVoid = 0;
|
|
foreach (var v in Voids) totalVoid += v.Area;
|
|
return Math.Clamp(totalVoid / Ball.Area * 100.0, 0, 100);
|
|
}
|
|
}
|
|
|
|
public string Classification => VoidRate <= VoidLimit ? "PASS" : "FAIL";
|
|
|
|
public void UpdateLabel()
|
|
{
|
|
if (Label == null || Ball == null) return;
|
|
double rate = VoidRate;
|
|
string cls = Classification;
|
|
Label.Text = (Index > 0 ? $"#{Index} " : "") +
|
|
$"Void: {rate:F1}% | Limit: {VoidLimit:F1}% | {cls}";
|
|
Label.Foreground = cls == "PASS" ? Brushes.Lime : Brushes.Red;
|
|
|
|
Canvas.SetLeft(Label, Ball.Center.X + Ball.Radius + 10);
|
|
Canvas.SetTop(Label, Ball.Center.Y - 10);
|
|
Label.Visibility = Visibility.Visible;
|
|
}
|
|
|
|
/// <summary>获取所有 UI 元素</summary>
|
|
public List<UIElement> AllElements
|
|
{
|
|
get
|
|
{
|
|
var list = new List<UIElement>();
|
|
if (Ball != null) { list.Add(Ball.Shape); list.Add(Ball.CenterDot); list.Add(Ball.EdgeDot); }
|
|
foreach (var v in Voids) { list.Add(v.Shape); list.Add(v.CenterDot); list.Add(v.EdgeDot); }
|
|
if (Label != null) list.Add(Label);
|
|
return list;
|
|
}
|
|
}
|
|
}
|
|
}
|