答案 0 :(得分:2)
不幸的是,我找不到从XAML可视化树计算边界框的方法。我通常使用Win2D进行这些类型的操作。看看CanvasGeometry及其计算边界框的能力。
如果您无法访问Win2D,或者您只需要快速解决此问题,这里有一个帮助类,可以处理任何形状,椭圆,路径等:
警告:这是一个使用强力命中测试的糟糕实现。我添加了一个计时器来证明它有多慢。
public static class BoundsHelper
{
/// <summary>Computes the axis-aligned minimum bounding box of the given <paramref name="element"/>.</summary>
/// <param name="element">The element to test.</param>
/// <param name="tolerance">The precision tolerance expressed in pixels. The lower the value the higher the precision, but the slower the operation.</param>
public static Rect ComputeBounds(FrameworkElement element, float tolerance = .5f)
{
var sw = Stopwatch.StartNew();
var transform = element.TransformToVisual(null);
var bounds = new Rect(0, 0, element.ActualWidth, element.ActualHeight);
bounds = transform.TransformBounds(bounds);
var minX = TestX(element, bounds, tolerance);
var minY = TestY(element, bounds, tolerance);
var maxX = TestX(element, bounds, -tolerance);
var maxY = TestY(element, bounds, -tolerance);
sw.Stop();
Debug.WriteLine($"{sw.Elapsed.TotalMilliseconds} ms to compute bounds with tolerance = {tolerance}");
return new Rect(new Point(minX, minY), new Point(maxX, maxY));
}
private static double TestX(UIElement element, Rect bounds, float tolerance)
{
bounds = tolerance > 0
? new Rect(bounds.Left, bounds.Top, tolerance, bounds.Height)
: new Rect(bounds.Right + tolerance, bounds.Top, -tolerance, bounds.Height);
while (!VisualTreeHelper.FindElementsInHostCoordinates(bounds, element).Any())
{
bounds.X += tolerance;
}
return bounds.X;
}
private static double TestY(UIElement element, Rect bounds, float tolerance)
{
bounds = tolerance > 0
? new Rect(bounds.Left, bounds.Top, bounds.Width, tolerance)
: new Rect(bounds.Left, bounds.Bottom + tolerance, bounds.Width, -tolerance);
while (!VisualTreeHelper.FindElementsInHostCoordinates(bounds, element).Any())
{
bounds.Y += tolerance;
}
return bounds.Y;
}
}
答案 1 :(得分:0)
只计算极值点的坐标。
对于多边形
left = min(p[i].x)
right = max(p[i].x)
top = min(p[i].y)
bottom = max(p[i].y)
对于椭圆或其他分析曲线,分析得到极值坐标
solve X'(t) = 0 for t=tz
(there are some subtle moments for min/max finding through derivatives)
find min and max from X(tz) and curve ends and so on