计算几何(一) by 邓俊辉老师

计算几何

诞生于上世纪八十年代中后期。在竞赛中考察概率不高,因为不易编成竞赛题,但是在实际应用中遇到的情况会非常多。
计算几何的特点 - 注重于符号 仅有加法乘法没有除法

in-Triangle Test 三角测试

每三个点(P、Q、R)确定一个三角形。如何判断第四个点S,落在三角形内部还是在三角形外部。

针对一般多边形可以采用射线法:随意做一条射线,穿越边界奇数次(odd)则在内部;穿越边界偶数次(even 0,2)在外部。
要用到分而治之和减而治之的方法。reduction。减&简
正确且简洁的办法:三角形是一种单纯性simplex。
PQ\QR\RP 三条边。分开来考虑。

  1. 先考虑,PQ确定的有向线。把平面切分成两半。明确名字,一半是左侧,另一半是右侧。half-plane 半平面。
  2. 再考虑QR\RP确定的有向直线。确定是在左边还是右边。
  3. s是在内部,这三个子问题的解均应该为left。他们互为充要条件。

在这里插入图片描述

判断三次test是否都是同号? 要么均为true 要么均为false 。
由于PQR三点的次序不一定一样。PQR构成的顺序如果是CCW逆时针的话。counter clockwise。是+++。 CW clockwise 顺时针是—。 学界规范是CCW。

如何判断left or right 。中学里的海伦公式。求任何给定三个点的面积。面积是存在所谓的符号的。取决于三个点如何给次序。
三角形的面积是由两个矢量的叉积cross product形成的。叉积也就是一种面积。PQ QS。 若为顺时针则为正,否则为负。 叉积的计算符合右手螺旋定理。下表所列的为PQ与PS的叉积
行列式。求三角形面积. 如果行列式的值是正的,那么PQS就是顺时针。可以再常数时间内确定左侧右侧。
2 ⋅ S Δ P Q S = ∣ P x P y 1 Q x Q y 1 S x S y 1 ∣ 2 \cdot S_{\Delta P Q S}=\left|\begin{array}{lll}{P_{x}} & {P_{y}} & {1} \\ {Q_{x}} & {Q_{y}} & {1} \\ {S_{x}} & {S_{y}} & {1}\end{array}\right| 2SΔPQS=PxQxSxPyQySy111

判断线段ST与线段PQ是否存在交点

bool intersect(P,Q,S,T)
return ToLeft(S, T, P) ^ ToLeft (S, T, Q) 异或 P\Q两点相对于有向直线ST必须一左一右。
&& ToLeft(P, Q, S) ^ ToLeft(P, Q, T) S\T两点相对于有向直线PQ必须一左一右。 并且两者要且在一起。从而排除其他情况。

Ponit location in a Ladder

任何一个点是否比另外一个点要大。
点定位问题。
两组平行的点。判断落在这些梯形中的哪一个当中。trap Sorted seqence。
query 查询 这个s是属于那个梯形中。有序的次序可以做一个binary search。 比较器。猜出一个pivot,在左边还是右边。
每次做一个ToLEFT判断作为一个比较器进行二分查找。复杂度是一个O(logn)。
变式,两组是互相垂直的点。判断点落在哪个三角形中。

二维凸包(2D convex hull)

如何构造一个凸包?
可以看做是对给定点做二分类。
最外围的一圈称为extreme point,极点EP。以及在内部的点。
EP的特点,可以寻找到一条穿越该点的直线,所有的点可以落在他的左侧的那一半
内部的点,不存在这样的特质,找不到这样子的点。可以简明的表述为数学中的空。

**法一:**判断点。
PQR三个点形成三角形做三重循环,还需要枚举中间那个点。以前三个为基础测试第四点是否在内部。
一共只需要枚举四重循环。
O(N^4)。
**法二:**判断边。
凸包上的那条极边。EE Extreme Edges。级边的有一侧必然为空。
EP都来自于该级边。
PQ两重嵌套的循环枚举所有的可以形成的边。再有一重S 遍历所有点集,判断是否只有一侧为空以确定该PQ是否为级边。 是的话将该PQ作为级边。
O(N^3)。
法三:
类似于选择排序。selection sort。 incremental strategy 。找到一个点,将E.P 逐步扩大。
寻找一个起点,立足于刚生成的点去寻找下一条边。
gift wrapping 礼品包装法 Jarvis March 纪念发明者。
如何立足于k,寻找下一个点。K有一个前驱I。IK均为E.P.
从IK出发去,一层循环 去 寻找minimal left turn.
O(N^2)。
注意第一点,第一条边如何寻找出来。可以一一测试每个点。
最简单的方式寻找与X轴Y轴边平行的点。lowest&highest。这些都是边缘点。
但是存在一个边缘情况。同时有两个low点。此时比较左右,选取left most。 LTL:lowest then leftmost 。 此时第一条边也就可以设置为x轴
法四:
插入排序。这也是一种incremental construction。可能中间会插一个进去。会更加灵活,来一个算一个。会动态地改变E.P.

  • In-Convex-Polygon Test—>一开始对两种情况分开分析,后面又合并分析了
    加入一个以后的变化情况, E.P. 不变,+1,减少(可能多个)。
    起点选取 leftmost&lowest,存在一个前驱边和后继边。
    如何判断E.P 是否会增加。以某点的前驱和后缀级边 做一个二分查找。
    star-shaped = kernel内核点。由该点能够无阻碍地沿直线到达其他位置的点。对于凸多边形,一定是star shaped. 但是star shaped 就不一定是凸包。
    将凸包划分为n-2个三角形区域。binary search。在logn的时间内确定新加入点所在三角形位置。对其该三角形对应的极边EE,再做一次toleft测试。如果toleft就在内部,right在凸包外部需要更新凸包。
  • Supprot lines + Turn pattern
    加入凸包外部一点以后,可以分为 support/tangent line(point) 把向阳面去除构成一个新的凸包。
    如何判断该support point?
    将该点与新加入点的连线作为基准线,与根据其前驱和后继 在其上标上Left or right标签。该标签称之为turning pattern 专项pattern 从R-L是一个阴面,但是LR阳面 LL是下支撑点(support line) RR是上止点(tangent line)在这里插入图片描述
    通过 turning pattern ,引入XT&XS边进入凸包,形成一个新的凸包。

如果一点 在内部,那么每一个E.P. 由前驱和后继构成的pattern。所有的点都是RL pattern。
不管在外还是在内,都只要不断去环游。
复杂度O(n*n) n个点每个点遍历n次。
该算法的主要在于如何寻找第一个点。发现TS之后如何做。

法五: 见计算几何(二) nlogn的算法

例题,水果忍者。 fruit ninja

有无存在一条直线,通过一刀能够切除所有水果。 每个水果可以抽象成(x, y1, y2)
分类和染色 上面五个点一种颜色和下面五个点一种颜色。各自构成凸包。
separation theorem 分割定理。 如果有两个点集合可以用一条直线分割的(线性分割),当且仅当他们的凸包也可以分割。
根据左右极点,可以将每个凸包按逆时针方向分为两个部分。lower hull 下凸 还有一个 upper hull 上凸。
判断上面一个凸包的下凸和下面凸包的上凸之间是否存在交点。没有交点的话就是线性可以分的。

在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值