【算法学习】射线法判断点在多边形内外(C#)以及确定内外两点连线与边界的交点

1.前言:

在GIS开发中,经常会遇到确定一个坐标点是否在一块区域的内部这一问题。
如果这个问题不是一个单纯的数学问题,例如:在判断DEM、二维图像像素点、3D点云点等含有自身特征信息的这些点是否在一个区域范围内部的时候,可以结合其高程信息、RGB信息、深度信息来辅助处理,相比与单纯从数学角度来看更简单、快速。

举几个我认为正确的例子:SLAM中前端角点的选取,利用的是OpenCV来提取;DEM提取边界,根据周围高程的有无;PS中扣出某物边界,利用的是RGB差异性;点云提取可以利用深度信息(本质也是RGB)来做。

但是,如果我现在只拥有点的坐标,该问题就变成一个数学问题了。

2.射线法:

在这里插入图片描述

该算法基本思路是从待定点朝任意方向射出一条射线(通常是水平向右),判断该射线与多边形边的交点个数。一般来说,交点个数为偶数(包括0),点在外部;交点个数为奇数,点在内部。
因为点和图形的位置是固定不动的,所以射线的朝向,对于最终的交点个数,也就是位置结果是没有影响的。

2.1 算法介绍

在分析前要先明白几个问题:

  • 如果没有特殊需求,待求点在图形的边界(线段、交点)上,默认是属于图形内部的。
  • 默认待求点的射线沿着x轴方向水平射出(水平向)。
  • 射线经过边界交点情况很常见,为了防止上一个线段的末顶点和下一个线段的首顶点(这两个是一个点)被算作两次,所以只看线段的y更小的一端,即参数方程的值域符号:[y1,y2)
    假如逆时针遍历各边,看下图示例:
    在这里插入图片描述

(1)从简单情况开始分析:
最简单的情况当属一个规整的四边形,射线与四边形的交点个数存在的情况有:0,1,2。
如果,不考虑穿过顶点,不考虑点的射线与边平行(重合),就单纯考虑穿的全部是边,遇到这种情况:
先建立遍历边的参数方程,找到射线与参数方程的交点,再判断交点X交和待定点的位置关系。
在这里插入图片描述
如果P在X交左侧,有一个交点则计数+1;
如果P和X交是一个点,则说明P在边界线段上,直接返回true;
如果在X交右侧,没有交点。

注意:这里的上下yi和yj的取值,要包含下界,不包含上界,否则会被计算两次,而且这样可以有效忽略水平边界而待求点在左侧的问题。
当然,反过来也可以,都选择更大的y值。

(2)我认为的几种特殊情况,这几种特殊情况有特点:就是无法找到线段去做参数方程或者实际交点无数个。这几种特殊情况需要单独处理。

  • 待求点就是边界交点:通过坐标判断,直接返回是否在边界内。
  • 待求点在水平边界线上:通过坐标判断,直接返回是否在边界内。
  • 待求点在水平边界线左侧:配合前后该水平边界先后线段参数方程的值域,这种情况可以直接忽略!(忽略不是没有考虑)

2.2 C#代码实现

using System;
using System.Collections.Generic;public class Point
{public double X { get; set; }public double Y { get; set; }public Point(double x, double y){X = x;Y = y;}
}
public class Polygon
{private List<Point> vertices;public Polygon(List<Point> points){vertices = points;}public bool IsPointInside(Point testPoint){int intersectionCount = 0;int vertexCount = vertices.Count;for (int i = 0, j = vertexCount - 1; i < vertexCount; j = i++){Point vi = vertices[i];Point vj = vertices[j];// 检查测试点是否在顶点上if ((vi.X == testPoint.X && vi.Y == testPoint.Y) ||(vj.X == testPoint.X && vj.Y == testPoint.Y)){return true;}// 检查测试点是否在水平边上if (vi.Y == vj.Y && vi.Y == testPoint.Y){if (testPoint.X > Math.Min(vi.X, vj.X) && testPoint.X < Math.Max(vi.X, vj.X)){return true;}}// 检查testpoint.y是否在两个端点的中间//if ((vi.Y > testPoint.Y) != (vj.Y > testPoint.Y)) // 这行代码更简单,但是有点小小的不直观if ((vi.Y <= testPoint.Y && vj.Y > testPoint.Y) || (vj.Y <= testPoint.Y && vi.Y > testPoint.Y)){double intersectionX = (vj.X - vi.X) * (testPoint.Y - vi.Y) / (vj.Y - vi.Y) + vi.X;// 处理边界情况if (testPoint.X == intersectionX){return true;}if (testPoint.X < intersectionX){intersectionCount++;}}}// 如果交点数为奇数,则点在多边形内部return intersectionCount % 2 != 0;}
}
internal class Program
{static void Main(string[] args){List<Point> vertices = new List<Point>{new Point(0,0),new Point(1,0),new Point(2,-1),new Point(3,0),new Point(5,0),new Point(5,1),new Point(4,1),new Point(4,2),new Point(3,3),new Point(3,4),new Point(2,4),new Point(2,3),new Point(1,3),new Point(1,4),new Point(0,4),new Point(0,2),new Point(-1,1),};Polygon polygon = new Polygon(vertices);List<Point> testPoint = new List<Point>();for (int i = -1; i < 6; i++){for (int j = -1; j < 7; j++){testPoint.Add(new Point(i, j));}}foreach (var p in testPoint){Console.WriteLine($"p点坐标:({p.X}, {p.Y}),是否在图形内部:{polygon.IsPointInside(p)}");}Console.ReadKey();}
}

在这里插入图片描述
用for循环写了一个从(-1,-1)到(5,6)覆盖的测试点,最后结果:

p点坐标:(-1, -1,是否在图形内部:False|p点坐标:(-1, 0,是否在图形内部:False
p点坐标:(-1, 1,是否在图形内部:True|p点坐标:(-1, 2,是否在图形内部:False
p点坐标:(-1, 3,是否在图形内部:False|p点坐标:(-1, 4,是否在图形内部:False
p点坐标:(-1, 5,是否在图形内部:False|p点坐标:(-1, 6,是否在图形内部:False
p点坐标:(0, -1,是否在图形内部:False|p点坐标:(0, 0,是否在图形内部:True
p点坐标:(0, 1,是否在图形内部:True|p点坐标:(0, 2,是否在图形内部:True
p点坐标:(0, 3,是否在图形内部:True|p点坐标:(0, 4,是否在图形内部:True
p点坐标:(0, 5,是否在图形内部:False|p点坐标:(0, 6,是否在图形内部:False
p点坐标:(1, -1,是否在图形内部:False|p点坐标:(1, 0,是否在图形内部:True
p点坐标:(1, 1,是否在图形内部:True|p点坐标:(1, 2,是否在图形内部:True
p点坐标:(1, 3,是否在图形内部:True|p点坐标:(1, 4,是否在图形内部:True
p点坐标:(1, 5,是否在图形内部:False|p点坐标:(1, 6,是否在图形内部:False
p点坐标:(2, -1,是否在图形内部:True|p点坐标:(2, 0,是否在图形内部:True
p点坐标:(2, 1,是否在图形内部:True|p点坐标:(2, 2,是否在图形内部:True
p点坐标:(2, 3,是否在图形内部:True|p点坐标:(2, 4,是否在图形内部:True
p点坐标:(2, 5,是否在图形内部:False|p点坐标:(2, 6,是否在图形内部:False
p点坐标:(3, -1,是否在图形内部:False|p点坐标:(3, 0,是否在图形内部:True
p点坐标:(3, 1,是否在图形内部:True|p点坐标:(3, 2,是否在图形内部:True
p点坐标:(3, 3,是否在图形内部:True|p点坐标:(3, 4,是否在图形内部:True
p点坐标:(3, 5,是否在图形内部:False|p点坐标:(3, 6,是否在图形内部:False
p点坐标:(4, -1,是否在图形内部:False|p点坐标:(4, 0,是否在图形内部:True
p点坐标:(4, 1,是否在图形内部:True|p点坐标:(4, 2,是否在图形内部:True
p点坐标:(4, 3,是否在图形内部:False|p点坐标:(4, 4,是否在图形内部:False
p点坐标:(4, 5,是否在图形内部:False|p点坐标:(4, 6,是否在图形内部:False
p点坐标:(5, -1,是否在图形内部:False|p点坐标:(5, 0,是否在图形内部:True
p点坐标:(5, 1,是否在图形内部:True|p点坐标:(5, 2,是否在图形内部:False
p点坐标:(5, 3,是否在图形内部:False|p点坐标:(5, 4,是否在图形内部:False
p点坐标:(5, 5,是否在图形内部:False|p点坐标:(5, 6,是否在图形内部:False

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/38136.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于uniapp(vue3)H5附件上传组件,可限制文件大小

代码&#xff1a; <template><view class"upload-file"><text>最多上传5份附件&#xff0c;需小于50M</text><view class"" click"selectFile">上传</view></view><view class"list" v…

CCAA:认证通用基础 10(审核的概念、审核有关的术语、审核的特征、审核原则)

10.审核的概念、审核有关的术语、审核的特征、审核原则 10.1审核的基本概念 第一章 审核基础知识 第一节 概述 1.什么是审核 审核是认证过程中最基本的活动&#xff0c;是审核方案的重要组成部分&#xff0c;其实施效果直接影响到审核方案的意图和审核目标的达成。 在认证…

外贸企业选择什么网络?

随着全球化的深入发展&#xff0c;越来越多的国内企业将市场拓展到海外。为了确保外贸业务的顺利进行&#xff0c;企业需要建立一个稳定、安全且高速的网络。那么&#xff0c;外贸企业应该选择哪种网络呢&#xff1f;本文将为您详细介绍。 外贸企业应选择什么网络&#xff1f; …

VehicleSPY的安装与使用

VehicleSPY介绍 Vehicle Spy 是美国英特佩斯公司的一款集成了诊断、节点/ECU仿真、数据获取、自动测试和车内通信网络监控等功能的工具&#xff0c;Vehicle Spy软件支持的应用场景很多&#xff0c;无法一一列举&#xff0c;以下是一些常见的应用&#xff1a; 总线监控&#x…

stthjpv:一款针对JWT Payload的安全保护工具

关于stthjpv stthjpv是一款针对JWT Payload的安全保护工具&#xff0c;这款工具集多种技术和思想于一身&#xff0c;可以通过不断改变相关参数值来防止Payload被解码&#xff0c;以帮助广大研究人员更好地保护JWT Payload的安全性。 除此之外&#xff0c;该工具还能够确保JWT …

如何定制化 ListView 界面

&#x1f604;作者简介&#xff1a; 小曾同学.com,一个致力于测试开发的博主⛽️&#xff0c;主要职责&#xff1a;测试开发、CI/CD 如果文章知识点有错误的地方&#xff0c;还请大家指正&#xff0c;让我们一起学习&#xff0c;一起进步。 &#x1f60a; 座右铭&#xff1a;不…

代码查重软件-自力更生

为了减轻工作量&#xff0c;自研了简单实用的代码查重工具&#xff0c;可以对若干文件之间进行查重。通过调试&#xff0c;相似度大于80%的没有一个是冤枉的。好用。去掉雷同的&#xff0c;其他的代码再慢慢看。

Java UU跑腿同城跑腿小程序源码快递代取帮买帮送源码小程序+H5+公众号跑腿系统

&#x1f680;【同城生活小助手】&#x1f680; &#x1f3c3;‍♂️【同城跑腿&#xff0c;即刻送达的便利生活】&#x1f3c3;‍♀️ 在快节奏的都市生活中&#xff0c;时间成了最宝贵的资源。UU跑腿小程序&#xff0c;作为同城生活的得力助手&#xff0c;让你轻松解决生活…

​如何部署私有化地图服务器(Windows版)

用户希望我们能详细讲讲&#xff0c;如何通过《水经注地图服务》进行私有化部署做一个地图服务器。 现在就来为大家作一个较为详细的分享&#xff0c;希望能在私有化部署地图服务器的工作中&#xff0c;助你一臂之力&#xff01; 《水经注地图服务》下载与安装 打开以下官方…

从深度学习到音乐创作:AI如何重新定义音乐行业

&#x1f4d1;引言 近一个月来&#xff0c;随着几款音乐大模型的轮番上线&#xff0c;AI在音乐产业的角色迅速扩大。这些模型不仅将音乐创作的门槛降至前所未有的低点&#xff0c;还引发了一场关于AI是否会彻底颠覆音乐行业的激烈讨论。从初期的兴奋到现在的理性审视&#xff0…

IO模型与多路复用

前言 在Linux中有一句经典台词&#xff1a;“Linux一切皆文件”。IO操作是与文件进行交流的唯一方式&#xff0c;也就是说这是与Linux系统交流的唯一手段。就如同人与人之间的交流&#xff0c;如果我们连交流的方式都不甚了解&#xff0c;交流的效率就会变得低下。操作系统也是…

机械设备制造企业MES系统解决方案介绍

机械设备制造行业涵盖了各类工业设备、工程机械、农业机械等多个领域&#xff0c;对生产精度、质量控制和效率提出了较高要求。为了提升生产效率、保证产品质量并满足客户需求&#xff0c;越来越多的机械设备制造企业引入了MES系统。本文将详细介绍MES系统在机械设备制造行业的…

CPPTest设计分析

目录 1 概述2 设计3 扩展Output3.1 扩展实例 1 概述 CppTest是一个可移植、功能强大但简单的单元测试框架&#xff0c;用于处理C中的自动化测试。重点在于可用性和可扩展性。支持多种输出格式&#xff0c;并且可以轻松添加新的输出格式。 CppTest下载地址Sourceforge Github地…

Java StringBuffer类和StringBuilder类

在使用 StringBuffer 类时&#xff0c;每次都会对 StringBuffer 对象本身进行操作&#xff0c;而不是生成新的对象&#xff0c;所以如果需要对字符串进行修改推荐使用 StringBuffer。 StringBuilder 类在 Java 5 中被提出&#xff0c;它和 StringBuffer 之间的最大不同在于 St…

DataWhale-吃瓜教程学习笔记 (六)

学习视频**&#xff1a;第4章-决策树_哔哩哔哩_bilibili 西瓜书对应章节&#xff1a; 第五章 5.1&#xff1b;5.2&#xff1b;5.3 文章目录 MP 神经元- 感知机模型 &#xff08;分类模型&#xff09;-- 损失函数定义--- 感知机学习算法 - 随机梯度下降法 - 神经网络需要解决的问…

WPF引入控件模板

控件模板基础 需求 需求&#xff1a;客户对目前的控件样式不满意&#xff0c;需要修改样式。 每一个控件都有Template属性&#xff0c;可以定制样式。 我下面以Button为例子&#xff1a; <Button Content"Button" Height"30" Width"100"…

docker mysql cpu100% cpu打满排查 mysql cpu爆了 mysql cpu 100%问题排查

1. docker 启动了一个mysql 实例&#xff0c;近期忽然发现cpu100% 如下图所示 命令&#xff1a; top 2.进入容器内排查&#xff1a; docker exec mysql&#xff08;此处可以是docker ps -a 查找出来的image_id&#xff09; -it /bin/bash cd /var/log cat mysqld.log 容器内m…

2024年Stable Diffusion下载+安装+使用教程(超详细版本)收藏这一篇就够了!

本篇咱们要聊的是如何用“整合包”来搞定StabIe Diffusion WebUI的本地安装和使用&#xff0c;别担心&#xff0c;你不需要成为计算机大神&#xff0c;新手也能轻松上手。不过得提醒一下&#xff0c;你的硬盘得留出100G~200G的空间来&#xff0c;才能玩得转。 整合包放这里&am…

网站被浏览器提示“不安全”的解决办法

在互联网时代&#xff0c;网站的安全性直接关系到用户体验和品牌形象。当用户访问网站时&#xff0c;如果浏览器出现“您与此网站之间建立的连接不安全”的警告&#xff0c;这不仅会吓跑潜在客户&#xff0c;还可能对网站的SEO排名造成等负面影响。 浏览器发出的“不安全”警告…

无人机基础知识(模式篇)

姿态模式&#xff1a;姿态模式通常是在GPS模式无法使用的情况下进行操作的模式。通过操作杆对无人机进行操控&#xff0c;姿态模式下无人机只能提供自稳&#xff0c;不提供定点悬停&#xff0c;受外界影响很大&#xff1b; GPS模式&#xff1a;GPS模式通俗一点就是依靠GPS将无…