一种求凸多边形内部似最大圆的算法

文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

1.    背景

任意多边形内部一定有一个最大圆,但是如果我们将条件设定为“任意多边形”、“最大圆”,该算法将十分复杂。比如获取多边形内任意点进行膨胀、通过碰撞检测来进行判定,算法复杂且效率低下。

回到实际项目本身,需求为判断点是否落在规划的电子围栏内。观察电子围栏,多数是凸多边形。而我们之所以要求内部圆,是因为单纯通过外包矩形可以过滤掉的点十分有限,并且即使点落在外包矩形内后,依然不能肯定点是否落在多边形内,还是要做一次点和多边形关系的判断。考虑到实际情况中点落在多边形内是大概率事件,这将导致点面关系的判断十分频繁。而如果我们内部构造出一个圆,这个圆足够大,则可以先进行点是否在圆内的简单判断。如果这个圆可以占多边形50%的空间,则可以避免百分之五十的点和多边形的判断。那么这个圆需要是最大么,考虑到算法代价,似最大便足够。

总结这个需求,我将其简化为,求凸多边形内部的似最大圆。

2.算法设计

求出多边形的重心为圆心,获取重心到各边垂直距离中的最短距离为半径。

2.1获取重心

重心的获取有两个方法:

a.各顶点的平均值。

b.考虑面积加权,将多边形切分为各三角形,通过平面薄板重心公式把积分变成累加和:

2.2获取半径

以重心为原点,与各个边相连,将多边形划分为多个三角形,求出该顶点到三角形对边的垂直距离。

a.利用海伦公式算出三角形的面积。

b.利用三角形面积和边的长度,算出原点到对边的垂直距离。

c.遍历此运算,得出“高”中的最短高(距离)。

3.补充多边形凹凸关系判断

由于该算法主要针对凸多边形,所以需要对多边形进行凹凸判断。判断思路为角度合算法。

4.实现

                         -----欢迎转载,但保留版权,请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/

      如果您觉得本文确实帮助了您,可以微信扫一扫,进行小额的打赏和鼓励,谢谢 ^_^

                                         

时间: 2024-10-10 20:25:13

一种求凸多边形内部似最大圆的算法的相关文章

poj 1584 A Round Peg in a Ground Hole 判断多边形是否为凸多边形 + 圆心是否在凸多边形内 + 圆是否在凸多边形内部

题目来源: http://poj.org/problem?id=1584 题意: 给一个多边形, 一个圆心以及半径. 首先判断是否为凸多边形. 如果是凸多边形, 再判断,圆是否在凸多边形内部. 分析: 1) 先判断是否为凸多边形 ,题目给出的顶点是有序的, 即顺时针或是 逆时针.用叉积方向判断. 2) 判断圆在多边形内, 首先判断 圆心是否在多边形内部, 是的话,然后再 判断 圆心到多边形 所有边的 距离d >= r , 即可. 代码如下: const int Max_N = 1005; con

(hdu step 7.1.3)Lifting the Stone(求凸多边形的重心)

题目: Lifting the Stone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 168 Accepted Submission(s): 98   Problem Description There are many secret openings in the floor which are covered by a big he

Redis入门到高可用(四)—— Redis的五种数据结构的内部编码

Redis的五种数据结构的内部编码 原文地址:https://www.cnblogs.com/thiaoqueen/p/9054083.html

typedef声明变量也是一种求值过程

前言: 什么叫做:声明变量是求值过程?请看下面的声明, int i; 很简单,声明了个整型变量i,再看如下声明, int *p; 也很简单,立刻反应出来它是指向整型的指针,但是具体如何推倒出来的呢?其实在C语言中,变量的声明就是一种求值过程,把*p这部分声明看成表达式,对这个表达式的求值的结果是int类型,这样就可以倒推出p是指针整型的指针了,因为只有对指向整型的指针进行解引用操作才是整型类型!还有很多复杂的声明,都可以使用这种方法求其具体的类型. 下面让我们来验证typedef定义的新类型和普

一种节省空间的交换变量的基本算法

一种节省空间的交换变量的基本算法,一个很简单的算法 因为其中没有引入temp变量,所以可以节省空间 代码如下: 一种节省空间的交换变量的基本算法

两种求幂集的方法

今天这一题是求幂集.小学数学都忘得差不多了- 幂集是什么? 幂集(power set)是一个集合的所有子集.比如[1, 2, 3]的幂集就是: [[], [1], [2], [1, 2], [3], [1, 3], [2, 3], [1, 2, 3]] 不过这道题有一个额外的要求: 在求幂集时要以"深度优先搜索"(depth-first search)的形式进行.也就是说,对于集合的每个元素,都有"取"和"舍"两种选择:在深度优先时,我们优先选择

两种求集合所有子集的方法

假设我们有一个求集合的全部子集(包含集合自身)的需求,即有一个集合s,包含两个元素 <a,b>,则其全部的子集为<a,ab,b>. 不难求得,子集个数sn与原集合元素个数n之间的关系为:sn=2^n-1. 本文分别讲述两种实现方法: 一:位图法: 1)构造一个和集合一样大小的数组A,分别与集合中的某个元素对应,数组A中的元素只有两种状态:"1"和"0",分别代表每次子集输出中集合中对应元素是否要输出,这样数组A可以看作是原集合的一个标记位图.

两种求集合全部子集的方法

如果我们有一个求集合的所有子集(包括集合自身)的需求,即有一个集合s,包括两个元素 <a,b>,则其所有的子集为<a,ab,b>. 不难求得,子集个数sn与原集合元素个数n之间的关系为:sn=2^n-1. 本文分别讲述两种实现方法: 一:位图法: 1)构造一个和集合一样大小的数组A,分别与集合中的某个元素相应,数组A中的元素仅仅有两种状态:"1"和"0",分别代表每次子集输出中集合中相应元素是否要输出.这样数组A能够看作是原集合的一个标记位图

记一种求最大公约数的方法

除了短除,还有下面两种方法求最大公约数,不但在数学中显得简单,而且在编程中有很好的效果 尤其是特别适合于编程... 先放文字说明: 1.更相减损法 第一步:任意给定两个正整数:判断它们是否都是偶数.若是,则用2约简:若不是则执行第二步. 第二步:以较大的数减较小的数,接着把所得的差与较小的数比较,并以大数减小数.继续这个操作,直到所得的减数和差相等为止. 则第一步中约掉的若干个2与第二步中等数的乘积就是所求的最大公约数. 其中所说的“等数”,就是最大公约数.求“等数”的办法是“更相减损”法.所以