【C#】在一个给定的宽、高范围内,获取到该多边形内部的所有坐标集合?

问题点

使用C#语言在一个给定的宽、高范围内,获取到该多边形内部的所有坐标集合?

这个多边形可能存在交叉及互相重叠部分

图像的宽、高可以定义为:2000*2000

多边形坐标集合:Point\[\] polygon_points = new Point\[\] { new Point(992, 1461), new Point(1616, 925), new Point(1706, 1816), new Point(1155, 948), new Point(1986, 1216), new Point(996, 1956), new Point(811, 1031) };

解决方案一:针对整体的图像宽高扫描(可能耗时)

要在 C# 中实现从一个多边形中获取其在给定宽度和高度范围内的所有整数坐标点,你可以使用一种称为"扫描线算法"(Scanline Algorithm)的方法。这种方法通过水平扫描多边形的每一条边,来确定哪些像素应该被填充。但是,直接用纯数学方法实现可能会比较复杂,特别是对于复杂的多边形。

下面是一个简化版的示例代码,它使用了 System.Drawing 命名空间中的 GraphicsPath 和 Region 类来帮助我们找到多边形内部的点。请注意,这个示例假设你在一个 Windows Forms 应用程序中工作,因为 System.Drawing 主要用于图形处理。

cs 复制代码
using System;
using System.Drawing;
using System.Collections.Generic;

class PolygonPointsFinder
{
    public static List<Point> GetPolygonInteriorPoints(Point[] polygon_points, int width, int height)
    {
        var interiorPoints = new List<Point>();
        
        using (var graphicsPath = new GraphicsPath())
        {
            graphicsPath.AddPolygon(polygon_points);
            
            using (var region = new Region(graphicsPath))
            {
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        if (region.IsVisible(x, y))
                        {
                            interiorPoints.Add(new Point(x, y));
                        }
                    }
                }
            }
        }

        return interiorPoints;
    }
}

class Program
{
    static void Main()
    {
        Point[] polygon_points = new Point[]
        {
            new Point(992, 1461),
            new Point(1616, 925),
            new Point(1706, 1816),
            new Point(1155, 948),
            new Point(1986, 1216),
            new Point(996, 1956),
            new Point(811, 1031)
        };

        int width = 2000; // 定义宽度
        int height = 2000; // 定义高度

        var points = PolygonPointsFinder.GetPolygonInteriorPoints(polygon_points, width, height);

        // 打印所有内部点
        foreach (var point in points)
        {
            Console.WriteLine($"({point.X}, {point.Y})");
        }
    }
}

这段代码首先定义了一个 GetPolygonInteriorPoints 方法,它接收一个多边形的顶点和一个指定的宽度与高度。它创建一个 GraphicsPath 对象并添加多边形路径,然后创建一个 Region 对象来表示这个路径的区域。接下来,它遍历整个区域并检查每个点是否在区域内。如果在区域内,则将该点添加到结果列表中。

最后,Main 方法中调用了 GetPolygonInteriorPoints 并打印出所有内部点。由于多边形可能非常大,实际运行时可能需要较长的时间,尤其是当多边形的边界非常接近或超出指定的宽度和高度时。

解决方案二:针对多边形的最小包含矩形扫描

同方法一,在获取坐标时,先把多边形形成的路径计算出来,进而再次循环

cs 复制代码
using System;
using System.Drawing;
using System.Collections.Generic;

class PolygonPointsFinder
{
        public static List<Point> GetPolygonInteriorPoints(Point[] polygon_points)
        {
            var interiorPoints = new List<Point>();
            using (var graphicsPath = new GraphicsPath())
            {
                graphicsPath.AddPolygon(polygon_points);
                RectangleF boundsF = graphicsPath.GetBounds();
                Rectangle bounds = new Rectangle(
                    (int)Math.Floor(boundsF.X),
                    (int)Math.Floor(boundsF.Y),
                    (int)Math.Ceiling(boundsF.Width),
                    (int)Math.Ceiling(boundsF.Height)
                );
                using (var region = new Region(graphicsPath))
                {
                    for (int y = bounds.Top; y < bounds.Bottom; y++)
                    {
                        for (int x = bounds.Left; x < bounds.Right; x++)
                        {
                            if (region.IsVisible(x, y))
                            {
                                interiorPoints.Add(new Point(x, y));
                            }
                        }
                    }
                }
            }
            return interiorPoints;
        }
}

class Program
{
    static void Main()
    {
        Point[] polygon_points = new Point[]
        {
            new Point(992, 1461),
            new Point(1616, 925),
            new Point(1706, 1816),
            new Point(1155, 948),
            new Point(1986, 1216),
            new Point(996, 1956),
            new Point(811, 1031)
        };

        int width = 2000; // 定义宽度
        int height = 2000; // 定义高度

        var points = PolygonPointsFinder.GetPolygonInteriorPoints(polygon_points);

        // 打印所有内部点
        foreach (var point in points)
        {
            Console.WriteLine($"({point.X}, {point.Y})");
        }
    }
}

注意点

图像的边界处是否需要处理,看情况根据自身情况考虑

相关推荐
泛凡(Linyongui)10 小时前
基于 CW32L010 的智能厨卫调温旋钮方案--低成本 EC21 编码旋钮全解析
单片机·嵌入式硬件·c#
暴走约伯11 小时前
【VFX工具链源码拆解 02】告别机械劳动(上):一键统改百个子粒子颜色与批量重命名
3d·unity·c#·材质
信息安全失业大专人员13 小时前
每日了解一个智能体-WorkBuddy
开发语言·ai·c#·智能体
呆呆敲代码的小Y13 小时前
【实战精选面试题】C# 面试题详细解答,按难易程度排序
android·java·游戏·c#·游戏开发·unity面试题·c#面试题
淡海水14 小时前
09-01-内存-Unity资源生命周期全景
unity·c#·游戏引擎·.netcore·gc
Solange__17 小时前
物流园区怎么用AI生成3D调度预演?从道路底图、车辆转弯到网页评审
图像处理·人工智能·游戏·3d·ai·自然语言处理·关卡设计
椒颜皮皮虾྅17 小时前
让 C# 读懂整张图:DeploySharp 驱动 PaddleOCR v4/v5/v6,打通 OCR 全流程
开发语言·人工智能·深度学习·学习·c#·ocr·cuda
昂好的day17 小时前
C# 同步异步与多线程:Thread / Task / 线程池一次讲透(上篇)
开发语言·windows·c#
zwc321043205518 小时前
Day 5:threshold与inRange阈值分割
c++·图像处理·人工智能·opencv·算法·计算机视觉
吃一碗粉只付一碗钱1 天前
12-给SPA友好的401和403响应
c#·状态模式