UWP:如何在旋转后获得新的形状尺寸?

时间:2017-11-16 03:11:59

标签: uwp geometry windows-10-universal

如何在UWP中旋转后测量其宽度和高度?它可以是任何形状,例如多边形或椭圆形。 enter image description here

2 个答案:

答案 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