当前位置:
首页 > Python基础教程 >
-
C#教程之判断某一点是否在几何图形内部
公司项目,要实现用户在矩形的红外图像上圈一块区域,计算该区域内部的平均温度、最大、最小温度,圈的区域有可能是矩形、椭圆、或者任意由多条线段构成的多边形,实现这个需求可以转换为求一个点是否在该几何图形内部,下面总结一下各种几何图形的判断方法。
1.矩形
判断点是否在矩形内,只要确定点的坐标在矩形四个顶点限定范围内即可
如上图,满足x<=x2&&x>x1&&y>y1&&y<y即可
2.椭圆
判断点是否在椭圆内,可以根据椭圆表达式求得
如上图,如果a>b,即焦点在x轴上,则满足(x*x/a/a+y*y/b/b < 1)的点在椭圆内,如果a<b,即焦点在y轴上,则满足(y*y/a/a+x*x/b/b<1)的点在椭圆内
3.由多个点构成的不规则图形
对于不规则图形,可以通过射线法判断,即计算射线与多边形各边的交点,如果是偶数,则点在多边形外,否则在多边形内
算法代码如下:
public bool Contains(Point test) { int i; int j; bool result = false; for (i = 0, j = _pointList.Count - 1; i < _pointList.Count; j = i++) { if ((_pointList[i].Y > test.Y) != (_pointList[j].Y > test.Y) && (test.X < (_pointList[j].X - _pointList[i].X) * (test.Y - _pointList[i].Y) / (_pointList[j].Y - _pointList[i].Y) + _pointList[i].X)) { result = !result; } } return result; }
要计算射线与线段的交叉,可以观察下图:
- t点与线段(v1-v2)要发生相交,t.y必须在线段的两个顶点的y值之间,即 t.y<v2.y&&t.y>v1.y
- 满足上面这个条件以后,只需要判断该点在线段的左侧还是右侧,如果在线段左侧,则该射线与线段相交,要判断t在左侧还是右侧,需要先求得水平线与线段的交点c的x坐标:c.x=(t.y-v1.y)*(v2.x-v1.x)/(v2.y-v1.y)+v1.x
由上两条,可以推得,t点与线段相交的条件为: t.y<v2.y && t.y>v1.y && c.x<((t.y-v1.y)*(v2.x-v1.x)/(v2.y-v1.y)+v1.x)
接下来考虑一些特殊情况:
- v1.y==v2.y,即射线与线段重合,该情况不满足第一个条件,因而对结果没有影响
- 射线在顶点上相交,有如下几种情况:
A顶点为交叉计数提供奇数(1),B、C为交叉计数提供偶数(分别是0、2),正好符合算法条件,A是多边形真正的交叉,B、C不是
算法测试结果如下:
测试程序地址:https://github.com/xienb/SpatialRelationTest
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式