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
{
/// BGA 空隙测量中的一个圆(气泡或焊球)
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);
}
}
/// 一次 BGA 空隙测量组(1个焊球 + N个气泡 + 标签)
public class BgaVoidGroup
{
public BgaCircle Ball { get; set; }
public List 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;
}
/// 获取所有 UI 元素
public List AllElements
{
get
{
var list = new List();
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;
}
}
}
}