判断点是否在多边形内,谁有好的算法

Q_282898034 2007-12-13 01:04:05
假设有某点 int[] point = {25 , 36};
判断其是否在 N 个点组成的多边形内。
球最高效算法,正好在边上的极端情况可以不用考虑
要求详细注释
...全文
1599 23 打赏 收藏 转发到动态 举报
写回复
用AI写文章
23 条回复
切换为时间正序
请发表友善的回复…
发表回复
Q_282898034 2007-12-15
  • 打赏
  • 举报
回复
谁写编码?100分全送上,楼上大大余外加分
极地_雪狼 2007-12-15
  • 打赏
  • 举报
回复
1、先判断点是否在四个极限边界内(多边形最左的定点,最上的定点,最右的定点,和最下的定点)
2、如果在,则依据贯穿此点的横坐标的直线作为轴线,找出两侧距离此轴线最近的两个定点。(还要判断本定点是凹点还是凸点)。
3、根据两点一线的原理,判断该点位于多边形内还是外
wb197 2007-12-15
  • 打赏
  • 举报
回复
根据计算机图形学中的描述,的确应该采用奇偶规则来解决这个问题,从任何位置P到对象坐标范围以外远距离画一直线(射线),并统计沿该射线与各边的交点数目。假如与这条射线相交的多边形边数为奇数,则P是内部点,否则P是外部点。
我所想象的方法验证下来是不可行的,无法解决有相交边的情况。
根据经典方案来解决吧,答案已经很明确了,就剩下编码了……
提醒一下,经过位置P的最简单的直线可以是与x轴平行,或者与y轴平行,这样就能好算一些了
Q_282898034 2007-12-15
  • 打赏
  • 举报
回复
再顶
Q_282898034 2007-12-14
  • 打赏
  • 举报
回复
谢谢17楼代码,不过我想学学这个算法,不希望用region.IsVisible来解,没说明白,不好意思
Q_282898034 2007-12-14
  • 打赏
  • 举报
回复
偶发现把大多边形切割成小多边形或者三角形都不实际,那个点乘我也没搞明白,高人总是说一半留一半。
我觉得还是楼上说射线法的有道理,不论是多么不规则的多边形,某点朝任意方向做一无限长的射线,判断该射线与所经过的多边形的边相交的次数,就可以判断该点是否在多边形内,偶数和零在外,奇数在内。
有没有源码?看样子也不是很复杂
nisnow 2007-12-14
  • 打赏
  • 举报
回复
Graphics g = e.Graphics;
Pen solidPen = new Pen(Color.Black, 4);
Pen dshPen = new Pen(Color.Blue);
dshPen.DashStyle = DashStyle.Solid;
Point[] points2 ={ new Point(10, 10), new Point(80, 20), new Point(130, 160), new Point(60, 160), new Point(5, 80) };
g.DrawPolygon(solidPen, points2);

GraphicsPath path = new GraphicsPath();
path.AddPolygon(points2);
path.CloseFigure();
Region region = new Region(path);
SolidBrush solidbrush = new SolidBrush(Color.Black);
g.FillRegion(solidbrush, region);
Point point = new Point(1, 1);
if (region.IsVisible(point, e.Graphics))
MessageBox.Show ("在区域内");
chenguang79 2007-12-14
  • 打赏
  • 举报
回复
大家说的方法都看不明白啊。看来还得回去学啊
dmhaifeng 2007-12-14
  • 打赏
  • 举报
回复
N个点组成的多边形内,构建一个Region
region.IsVisible(point);//返回bool
Q_282898034 2007-12-14
  • 打赏
  • 举报
回复
自己顶
wb197 2007-12-13
  • 打赏
  • 举报
回复
矢量乘法包括 “点乘” 与 “叉乘” ……

回去看大学数学吧……
Q_282898034 2007-12-13
  • 打赏
  • 举报
回复
高人,啥是点乘?
wb197 2007-12-13
  • 打赏
  • 举报
回复
哦,遗漏了一个要点,如果你建立的point数组是首尾相连的,那还是一个O(n)的判断就可以了,对每条边都进行一次点乘计算,判断结果的正负号即可。
wb197 2007-12-13
  • 打赏
  • 举报
回复
引用:多边形可以有多块组成,就像 photoshop 选区那样,多边形的边可以互相交叉,形成多个块。

高效的判定首先都是基于凸多边形的,包括扫描线、填充等。
先想办法把N点组成的多边形转化为多个凸多边形恐怕是不可避免的。

检测一个点是否在一个凸多边形内就非常简单了,O(n)的算法就可以,对凸多边形的每条边做一次点乘计算(你不会没有用矢量来进行计算吧),判断结果的正负号即可。

而转化成多个凸多边形的工作就要复杂得多了,其过程类似于建立二维BSP树。





AppFramework 2007-12-13
  • 打赏
  • 举报
回复
不用自己写吧:
Region.IsVisible (Point) 测试指定 Point 结构是否包含在此 Region 中。
由 .NET Compact Framework 支持。

zbjg 2007-12-13
  • 打赏
  • 举报
回复
切割为三角形可能并不容易,估计你忽略了凹多边形的情况。
另外我前边的算法需要更正一下
那就是只需要任意找一个多边形外的点与当前点组成线段就可以,然后再与每条边求交点。
最终交点个数的奇偶就说明问题。

理论上说,这类判断必然与每条边有关联,所以效率上应当还是可以的。
Q_282898034 2007-12-13
  • 打赏
  • 举报
回复
我觉得也许把大多边形划分成若干小三角形组成的集合,也许更为可行
zbjg 2007-12-13
  • 打赏
  • 举报
回复
这个问题比较有趣,我思考了一下,给你个思路。
1.对任意一点,你都可以以它为中心划个十字,然后在十字的四个方向分别找四个必然在多边形外的点。
2.由这个点和外面的四个点可以组成四条线段,分别对四条线段进行下面的判断。
3.分别用多边形的每条边与线段进行判断,如果交点为偶数个说明点在多边形外,否则继续判断。
4.当然还有些特殊情况,但都比较容易处理。(如线段重合)

两条线段是否相交应该不是难事吧。

另外,这是个经典的问题,在图形学的书或资料中可能有更加合理的算法。
真相重于对错 2007-12-13
  • 打赏
  • 举报
回复
Region.IsVisible (Point)
jupiter911 2007-12-13
  • 打赏
  • 举报
回复
Region.IsVisible()方法,你可以在MSDN上查到它
加载更多回复(3)

110,536

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧