【转】详谈判断点在多边形内的七种方法

news/2024/5/19 4:51:58/文章来源:https://www.cnblogs.com/lmst-ytt/p/16720595.html

原帖地址: https://blog.csdn.net/WilliamSun0122/article/details/77994526

射线法
时间复杂度:O(n) 适用范围:任意多边形
算法思想:
以被测点Q为端点,向任意方向作射线(一般水平向右作射线),统计该射线与多边形的交点数。
如果为奇数,Q在多边形内;
如果为偶数,Q在多边形外。计数的时候会有一些特殊情况,如图

 

 

 图片已经把特殊情况和算法实现说的很清楚,具体可看代码注释。

hdu1756-射线法代码

角度和判断法
时间复杂度:O(n) 适用范围:任意多边形
感觉这个方法和之后要介绍的转角法类似,个人感觉转角法就是这个方法的优化变形。不推荐这个算法。这个算法对精度的要求很高(会造成很大精度误差),不强调多边形点给出顺序,我用这个算法没过hdu1756(http://acm.hdu.edu.cn/showproblem.php?pid=1756)。

算法思想:
连接被测点与多边形所有顶点所形成的所有角的角度和在精度范围内等于则该点在多边形内,否则在多边形外。

转角法
时间复杂度:O(n) 适用范围:任意多边形
个人感觉是O(n)算法的第二推荐,该算法本来对精度要求较高,之后会有一个改进让其不用考虑精度误差,不过该算法要强调多边形点给出的顺序。
一般博客都以多边形正向即逆时针介绍,我这里也主要介绍逆时针,但hdu1756是顺时针给出,我会在括号中介绍一下顺时针(其实本质是一样的),顺时针具体在代码注释中提一下。不会画图,希望大家看了思想自己画图体会一下。

算法思想:
转角法非常简单,按照多边形顶点逆时针顺序,从P点到顶点Vi分别做连线,其中αi为Vi和Vi+1之间的夹角。其中α角度逆时针为正,顺时针为负,这样所有到顶点做连线之间夹角和为(环绕数)0,这点P在多边形外部,否则在内部。(感觉和角度和判断法本质一样,加了个方向)
(顺时针就是角度顺时针为正,逆时针为负)

 

 

直接环绕数的推导会需要用到反三角函数,这样即会耗时又会造成较大的精度误差,所以这里有一个优化。
从P点向右做射线R,如果边从射线R下方跨到上方,那么穿越+1,如果从上方跨到下方,则是-1。最终和为wn环绕数。如下图所示:
(写博客的时候才发现其实本质不就是射线吗,不过理解后代码会感觉写的比射线简单)

 

 

 这种方法不必去计算射线和边的交点,但需要判断点P和边的左右关系,而且对于方向向上和向下的边的判断规则不同。对于方向向上的边,如果穿过射线,那么P是在有向边的左侧;

方向向下的边如果穿过射线,那么P在有向边的右边(意思是说判断点P与边的关系,而不是相对坐标系内位置)。

 

 

 这里有一点要注意,如下图

 

 

 这里射线经过了BC和CD并穿过C点,但是要计算两次,一次+1一次-1,代码中会有体现。

 

 

 

改进弧长法
时间复杂度:O(n) 适用范围:任意多边形
该算法感觉是转角法的另一种优化,也解决了传统转角法的精度问题,也要求多边形点给出的顺序。

算法思想:
以被测点O为坐标原点,将平面划分为4个象限,对每个多边形顶点P[i],计算其所在的象限,然后顺序访问多边形的各个顶点P[i],分析P[i]和P[i+1],有下列三种情况:
1. P[i+1]在P[i]的下一象限。此时弧长和加;(代码中+1)
2. P[i+1]在P[i]的上一象限。此时弧长和减;(代码中-1)
3. P[i+1]在Pi的相对象限。利用叉积res=OP[i]xOP[i+1]计算OP[i]与OP[i+1]的关系。
若f=0,OP[i]与OP[i+1]共线,点在多边形边上;若f<0,OP[i]在OP[i+1]逆时针方向,弧长和减(代码中-2);若f>0,OP[i]在OP[i+1]顺时针方向,弧长和加(代码中+2)。

 

叉积(点线)判断法
时间复杂度:O(n) 适用范围:凸多边形

对于多边形(正向,即逆时针),如果一个点它的所有有向边的左边,那么这个点一定在多边形内部。利用叉积正好可以判断点与给定边的关系,即点是在边的左边右边还是边上。
这里说一下,(P叉乘Q)P^Q>0说明P在Q的顺时针方向,<0说明P在Q的逆时针方向,=0说明P和Q共线。

 

面积法
时间复杂度:O(n)(但是时间应该会比之前的O(n)的长一点)
适用范围:凸多边形

了解即可,有精度要求,强调多边形点给出的方向(逆时针)。
算法思想:
如果点在多边形内部或者边上,那么点与多边形所有边组成的三角形面积和等于多边形面积。多边形的面积可以用叉积计算即连接坐标原点和各顶点形成向量,所有向量叉积的0.5的和即为多边形面积。不过计算面积是会有一定误差的,需要设置精度的误差范围。

 

二分
时间复杂度:O() 适用范围:凸多边形
强掉多边形给出的方向。

这种方法以hrbust1429为例。 题目链接
这道题的题意是已知构成凸多边形A的n个点的坐标,和点集B的m个点的坐标,求这B的m个点是否都在凸多边形A内(严格内部,就是点不能在多边形边上)。

算法思想:
1. 选择多边形其中一个点为起点,连接其它点作射线。

 

 

 

2. 判断给定的点是否在所有射线包围的区域之内,即判断给定点是否在最左侧射线的左边,或者在最右侧射线的右边。
3. 如果在射线包围的区域之内,选择构成最两侧的射线的点为left和right,则mid = (left+right)/2,连接给顶点和起点作射线,判断该射线在mid点和起点的哪一边,不断循环,如此用二分法最后求出给定点所在的三角形区域,由此确定了除起点外的一条边。

 

4. 判断给定点在这条边的左方还是右方,由此判断给定点是否在三角形区域内,也就是是否在多边形内。

 

 

 最后总结一下O(n)算法的选择:个人感觉最优先考虑射线,其次是转角。

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

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

相关文章

用工具刺探主机通信和用系统ping命令有何区别(新人常犯的错误)

ping是操作系统自带的命令,经常用来刺探对端主机是否在线,通信能否畅通。它的原理是在调用ping命令时驱动TCP/IP协议栈的ICMP模块发送icmp echo request消息,待对方主机的ICMP模块收到后,会自动回复icmp echo response消息。本方收到icmp echo response即可确认对方主机在线…

15天深度复习JavaWeb的详细笔记(十)——Filter、Listener、Ajax

文章目录demo10-Filter、Listener、Ajax1&#xff0c;Filter1.1 Filter概述1.2 Filter快速入门1.2.1 开发步骤1.2.2 代码演示1.3 Filter执行流程1.4 Filter拦截路径配置1.5 过滤器链1.5.1 概述1.5.2 代码演示2&#xff0c;Listener2.1 概述2.2 分类2.3 代码演示3&#xff0c;Aj…

Dev C++中窗口输出中文问题解决

1、window+R+regedit调出注册表 2、点击Dec_Dev-Cpp_ConsolePauser.exe 3、鼠标左键双击“CodePage”,弹出设置页面。选择“十进制”,输入65001 4、右键点击运行窗口的图标,选择属性,取消使用旧版控制台5、重新运行完美!!!

vue后台系统管理项目-角色权限分配管理功能

⭐️⭐️⭐️ 作者&#xff1a;船长在船上 &#x1f6a9;&#x1f6a9;&#x1f6a9; 主页&#xff1a;来访地址船长在船上的博客 &#x1f528;&#x1f528;&#x1f528; 简介&#xff1a;CSDN前端领域优质创作者&#xff0c;资深前端开发工程师&#xff0c;专注前端开发…

Java_面向对象的三大特征之_继承

继承 如何继承一个类&#xff1f; 使用继承有什么好处&#xff1f; super如何使用&#xff1f; 重写的概念使用&#xff1f; 继承的关键字是什么&#xff1f; 抽象的关键字是什么&#xff1f; 抽象类有什么特点&#xff1f; Final关键字都能修饰什么&#xff1f;修饰完…

DolphinScheduler任务调度源码剖析

1.数据表 t_ds_process_definition&#xff1a;工作流定义表 t_ds_process_definition_log t_ds_process_instance&#xff1a;工作流运行实例表 t_ds_task_definition&#xff1a;任务定义表 t_ds_task_definition_log t_ds_process_task_relation&#xff1a;任务关系表 …

Appium入门自动化测试(6)—— Appium 常用方法的自己动手封装

Appium 常用方法的自己动手封装 前言 阅读此文大概需要5分钟&#xff0c;之后需要自己动手实践。 之前我们已经对Appium的一些常用的API有所了解&#xff0c;在实际测试过程中&#xff0c;大多数自动化测试工程师&#xff0c;尤其是UI自动化测试工程师&#xff0c;遇到更多的…

c语言分层理解(枚举和联合体)

文章目录1. 枚举1.1 枚举定义1.2 枚举常量的理解1.3 枚举的优点1.4 枚举大小1.5 枚举变量的使用2.联合体&#xff08;共同体&#xff09;2.1 联合体定义1.2 联合体特点1.2.1 联合体实现判断大小端1.3 联合体的大小1.3.1 实例一1.3.2 实例二1. 枚举 1.1 枚举定义 枚举的意思就是…

第四:Fiddler抓包教程(4)-会话面板和HTTP会话数据操作详解

一.会话列表 (Session list) 概览 1.Fiddler抓取到的每条http请求&#xff08;每一条称为一个session&#xff09;&#xff0c;会话列表 主要是Fiddler所抓取到的每一条http请求都会显示到这里。主要包含了请求的ID编号、状态码、协议、主机名、URL、内容类型、body大小、进程…

基于安卓(Android)的即时实时聊天APP软件

安卓即时聊天软件 实习目的及要求 Android 开发提高&#xff1a; 提供&#xff16;个基础样例代码&#xff0c;发挥想象力和创造力对其中一个进行改进和提高&#xff0c;比如&#xff1a;增加程序的功能&#xff0c;改进程序的人机交互性&#xff0c;以及提高程序运行的性能…

出海非洲新启示?传音控股供应链合作的本土化融合

近日&#xff0c;美媒发表报道称&#xff0c;中国品牌正成为非洲智能手机市场领导者。该报道透露&#xff0c;传音控股的智能机在第二季度市场份额占比为48%&#xff0c;超过三星&#xff0c;进一步夯实非洲智能机市场领导者的地位。 在全球经济疲弱且市场竞争越发激烈的背景下…

CSS中的BFC是什么?

BFC就是符合一些特性的HTML标签 1、什么是BFC? BFC格式化上下文 指一个独立的渲染区域&#xff0c;或者说是一个隔离的独立容器&#xff0c;可以理解为一个独立的封闭空间。无论如何不会影响到它的外面。 2、形成BFC的条件 浮动元素&#xff0c;float除none以外的值&#…

SDN实验一

1、基础版 a) 第1步Mininet运行结果截图b) 第2步的执行结果截图c) 第3步提交修改过的“学号.py”代码、Mininet运行结果 #!/usr/bin/env pythonfrom mininet.net import Mininet from mininet.node import Controller, RemoteController, OVSController from mininet.node impo…

有关anaconda常见指令操作

有关anaconda常见指令操作 查看已安装的包 conda list [PACKAGE]卸载包 conda uninstall PACKAGE更新包 conda update PACKAGE查看虚拟环境及其位置 conda env list创建环境 conda create --name [my_env]激活环境 conda activate my_env退出环境 conda deactivate删除环境 co…

【网络安全】记一次杀猪盘渗透实战

看起来非常假的网站这个网站是没有cdn的用的是thinkphpk框架搭建的。 先打一波poc没有效果&#xff0c; 【一一帮助安全学习&#xff0c;所有资源获取处一一】 ①网络安全学习路线 ②20份渗透测试电子书 ③安全攻防357页笔记 ④50份安全攻防面试指南 ⑤安全红队渗透工具包 ⑥…

不能出门的第10天我焦虑了,为了金三银四决定刷完这千道Java试题

前言: 因为疫情我被困在了家里&#xff0c;我是一个被无聊笼罩的人&#xff0c;呆在家里为国家做贡献&#xff0c;打算年后面试找工作的我决定发奋刷面试题&#xff0c;不打无准备的仗&#xff0c;这么多面试题的收集整理花费了很多的时间和经历&#xff0c;程序员朋友们如果你…

多线程---线程安全

&#x1f389;&#x1f389;&#x1f389;写在前面&#xff1a; 博主主页&#xff1a;&#x1f339;&#x1f339;&#x1f339;戳一戳&#xff0c;欢迎大佬指点&#xff01; 目标梦想&#xff1a;进大厂&#xff0c;立志成为一个牛掰的Java程序猿&#xff0c;虽然现在还是一个…

springboot+基于Java的果蔬产品销售系统 毕业设计-附源码131110

中文摘要 本文首先先引入了在线购物网站系统除了后端内容管理系统的概念外&#xff0c;还介绍了所使用的相关技术&#xff0c;分析了当前的研究现状和发展趋势&#xff0c;研究了与目标系统&#xff0c;系统介绍和二次开发有关的主要技术&#xff1b; 然后重点关注系统的总体体…

Revit中族参照平面的方向及创建自适应楼梯扶手

一、Revit中参照平面的方向问题 在Revit中做族时&#xff0c;经常会用到参照平面来进行定位&#xff0c;但是往往没注意到参照平面是有方向的。下面以拉伸构件的起点与终点来形象表达参照平面的方向。 如图1所示&#xff0c;当从左到右绘制参照平面时&#xff0c;拉伸构件在拉伸…

纯前端实现「羊了个羊」小游戏

纯前端实现「羊了个羊」小游戏🐏QCY 2022年09月16日 16:52 阅读 18681关注 我正在参加「码上掘金挑战赛」详情请看:码上掘金挑战赛来了! 背景 最近简单的「羊了个羊」小游戏火到出圈,据说狂赚几百几千万。这么弱智的玩意,即便是前端,我上我也行! 最终成果游戏本体如…