凸包算法 最简 nlogn
极点算法n4—极边算法n3—incremental javis march / gift wrapping
or 类似于 turning pattern insertion sort n2
更快地 O(nlogn) R.Graham Scan 线性时间进行扫描就可以了。主要的时间复杂度在于presorting。 1972年发明的算法。
- 预处理presorting
sort all vertices by polar angle 。 with regret to LTL。
关于LTL lowest then leftmost 根据他们的极角进行排序。实际上不用算出每一个角度。主要是对判断他们的toleft关系。对着三个点做一个to left,来判断极角大小判断。
把这些点画出来,只要有一个kernel,即从kernel出发到其余点的内对角线并没有被阻挡住,说明该图形是一个star-shaped。 对于所有的星型多边形,就可以采用R.Graham法。 如果LTL是star-shaped中的kernel,那么就要从LTL开始分析。
运用两个栈,上面的栈T朝下开口,下面的栈S朝上开口。
初始状态下面的S栈记录LTL以及极角最小的那个点。 S栈先存入两个。 上面的栈T存入其余的点。345…
每次 考虑S的栈顶&次栈顶,以及上面那个栈T的栈顶。 在T没空之前。对这三个点进行toleft测试。
while( !T.empty() )
//在T没有空之前
toLeft(U,V,W)?
//U,V为栈S的次栈顶和栈顶,W为T的栈顶
S.push( T.pop() ): //W pop出来 push至S栈中
S.pop();
最终S栈中存放的那些点,就是凸包所需要的点。
在scan过程中的复杂度分析:基本上是线性的。(证明简略如下:planar graph 平面图。也就是图中不存在交线。其性质为 v顶点 e边 f面 c连通域数目 v-e+f-c=1(欧拉公式) 也就是线性的复杂度。)
presorting 预排序的复杂度O(nlogn) 是不可避免的。
用leftmost&rightmost进行分割 划分为 上凸 upper hull & 下凸 lower hull
如果有一个算法先寻找到上凸包,再翻转一下利用同样的算法寻找到下凸包。
最左边和最右边。
先用一个现实中不存在的负无穷点,作为LTL。也就是该点与上面所有点的连线可以作为y方向的平行线。此时不再是通过极角进行排序,而是根据x坐标presorting。从Xmax—>Xmin。可以利用toleft比较器进行选取凸包点。得到了upperhull。反之得到lowerhull。
守卫长城
https://blog.youkuaiyun.com/qq_38064038/article/details/78494471
假设所有士兵都是朝左看的。请问建立多少烽火台能够照顾到所有点,且烽火台最少
假想负无穷的点是LTL,从最右边的点开始。求一个上凸包。
蓝色的点,都曾经进入过S栈中,并且会作为次栈顶。
三角剖分的应用 Art Gallery 艺术画廊
在一个不规则的画廊中,如何部署最少数量的摄像头是这个画廊中不存在监控盲区。星形多边形,可以只被极少数的摄像头覆盖住。
Art Gallery Theorm
n/3 向下取整,是 有必要的 而且总是足够的去覆盖监控 n边形。 n是边数。
梳状多边形,尖顶要足够的尖,底要足够的厚。每一个尖都需要一个哨兵。
证明 艺术画廊定理:
Fisk’s proof 三角剖分Triangulation 证明: 多边形,剖分为一个一个三角形。
Dual graph 对偶图。每一个节点都对应于一个三角形。每一三角面片的公共边界,都对应着一条中间对偶边。
一般来说中间没有洞的图,dual graph会是一个二叉树。因此可以 以 某个顶点开始做一个三染色。
注意如果每个顶点都装一个哨兵,就能完全照看住。如果选三染色之一的某种颜色的点 作为 哨兵 ,都可以完全覆盖。因为任何一块三角形,都可以用一个颜色的去照看住。
对于任何一个n多边形都存在n-2个三角剖分。
先对多边形的区域进行划分
ear=empty+convex. 顶点是一个凸角convex。 ear-cutting 割耳法。empty指三角形中间没有顶点——任何一个多边形都至少有一个耳朵。
mouth=empty+reflex 顶点是一个凹角(大于180度)
dirty = convex的前驱和后继连起以后的三角形不是empty 中间有其他点闯进。
任何一个多边形至少存在两个耳朵.任何一个非凸多边形至少存在两个耳朵,一张嘴。
如何寻找ear=empty+convex:
沿着边界遍历,确定leftturn如何判断是否是ear 其余n-3点利用intriangle test进行验证是dirty还是ear 。 一个ear的复杂度是O(n*n)。
也可以利用线性的时间完成三角剖分,但是算法比较复杂不实用。
Monotone Chain/Polygon
在实际应用中采用nlogn的复杂度。
单调多边形 单调链 monochain/Polygon : 在某一投影线点出现的顺序与原有的次序必然是一致的,投影线之间不会有任何的交叉。
以最低点和最高点为界。得到一个左侧链和右侧链。如果他们对于y轴都是单调的。那么该多边形为单调多边形。可以用线性的时间,剖分为一系列的三角形。
从顶上开始逐一进栈。出现耳朵就会割掉。如果出现在opposite site 均会变成耳朵。
该算法取决于我们当前扫描到的位置。
sweepline 扫描线算法。 c为current在扫描的元素
情况1A:sameside+reflex 栈顶t,次栈顶s cts为Reflex。rightturn ——push©
情况1B:循环 sameside + convex leftturn —— pop(t) 直到cts为reflex时 push©
情况2:c与所有栈元素为opposite side 所有的点都会变为ear 直到剩下唯一的元素c。 同时结束以后应该以t为栈底,重新进栈。再将c入栈。
对于非单调多边形。 会复杂一些
钟乳石 salagTite 望文生义!T&M
石笋 salagMite
通过T&M划分为多个单调的多边形。