WPF绘图---Canvas中Polygon屏幕居中显示

问题描述

在一个Canvas中绘制了多个Polygon,由于坐标可能超出界面显示范围,需要将绘制的Polygon居中显示,并且缩放至界面大小,效果如下:

xaml代码
xml 复制代码
<Border
    x:Name="border"
    Background="#fff"
    ClipToBounds="True">
    <Canvas
        x:Name="canvas"
        Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource AncestorType=Border}}"
        Height="{Binding Path=ActualHeight, RelativeSource={RelativeSource AncestorType=Border}}">
        <Canvas.RenderTransform>
            <TransformGroup />
        </Canvas.RenderTransform>
    </Canvas>
</Border>
实现代码
csharp 复制代码
private void CenterAndScalePolygons()
{
    if (canvas == null || canvas.Children.Count == 0)
    {
        return;
    }
    // 获取所有 Polygon 的边界框
    Rect boundingBox = GetBoundingBox(canvas.Children.OfType<Polygon>());

    // 计算需要进行的缩放和平移操作
    double scaleX = border.ActualWidth / boundingBox.Width;
    double scaleY = border.ActualHeight / boundingBox.Height;

    // 使用较小的缩放比例,保持图形完全在 Canvas 内显示
    double scale = Math.Min(scaleX, scaleY);

    double offsetX = border.ActualWidth / 2 - (boundingBox.Left + boundingBox.Right) / 2 * scale;
    double offsetY = border.ActualHeight / 2 - (boundingBox.Top + boundingBox.Bottom) / 2 * scale;

    // 遍历 Polygon 进行缩放和平移
    foreach (var polygon in canvas.Children.OfType<Polygon>())
    {
        ScaleTransform scaleTransform = new ScaleTransform(scale, scale);
        TranslateTransform translateTransform = new TranslateTransform(offsetX, offsetY);

        TransformGroup transformGroup = new TransformGroup();
        transformGroup.Children.Add(scaleTransform);
        transformGroup.Children.Add(translateTransform);

        polygon.RenderTransform = transformGroup;
        // 调整 Polygon 边框线宽
        polygon.StrokeThickness = 1 / scale;
    }
}

private Rect GetBoundingBox(IEnumerable<Polygon> polygons)
{
    double minX = double.MaxValue;
    double minY = double.MaxValue;
    double maxX = double.MinValue;
    double maxY = double.MinValue;

    foreach (Polygon polygon in polygons)
    {
        foreach (Point point in polygon.Points)
        {
            minX = Math.Min(minX, point.X);
            minY = Math.Min(minY, point.Y);
            maxX = Math.Max(maxX, point.X);
            maxY = Math.Max(maxY, point.Y);
        }
    }

    return new Rect(minX, minY, maxX - minX, maxY - minY);
}
相关推荐
枫叶林FYL10 小时前
项目九:异步高性能爬虫与数据采集中枢 —— 基于 Crawl<sub>4</sub>AI 与 Playwright 的现代化数据采集平台 项目总览
爬虫·python·深度学习·wpf
她说彩礼65万15 小时前
WPF 多值转换器
wpf
无心水19 小时前
【分布式利器:金融级】金融级分布式架构开源框架全景解读
人工智能·分布式·金融·架构·开源·wpf·金融级框架
她说彩礼65万19 小时前
WPF 转换器
wpf
WPF工业上位机1 天前
匠心研智造,同心赴新程-WPF硬件通讯之串口&Socket
wpf
爱炸薯条的小朋友2 天前
C#由窗体原子表溢出造成的软件闪退,根本原因补充
开发语言·c#·wpf
晚风一隅2 天前
阿里云盘古存储系统:EB级分布式存储的架构革命与技术突破
wpf
步步为营DotNet3 天前
深挖.NET 11:.NET Aspire 在云原生应用状态管理的创新与实践
云原生·.net·wpf
He BianGu3 天前
【项目】WPF VisionMaster 4.0 项目介绍和开发文档
c#·wpf·流程图·开发文档·机器视觉·visionmaster
He BianGu3 天前
【笔记】在WPF中PriorityBinding的详细介绍
笔记·wpf