7.24 学习记录

这篇博客总结了平面计算几何的主要知识点,包括矢量表示、叉乘应用、点线关系判断、多边形面积计算及点在多边形内的判断等。还探讨了精度问题、线段交点计算、旋转卡壳法,并分享了若干相关算法的POJ题目,强调了正确理解题意和避免精度陷阱的重要性。
摘要由CSDN通过智能技术生成

今天下午讲了平面计算几何的大部分内容,知识密度比较大,在这里做简单总结。方法比较偏数学,也相对直观,理解起来比较简单,但是相对的代码量不小,想熟练掌握还要练题。

平面计算几何课堂笔记

一般来讲大型比赛(区域赛、区域赛决赛)中必出,难度是中等到高等难度,代码量较大,且要考虑精度(太高太低都不行,小概率会莫名被卡)和特判问题,所以选手一般放在后面写。

用一个类(class)or结构体来表示一个矢量(用坐标的形式),重载操作符来或者是写个函数来表示操作。

关于操作符(operator)重载可以参考:https://blog.csdn.net/liitdar/article/details/80654324

基本的矢量操作均非常容易。(对称操作可以通过类似镜像阵的构造向量操作来实现)

二维中叉乘:p.x*q.y-q.x*p.x(最常用)

叉乘直接与方向、面积相关,因此与之相关的所有问题都可以用叉乘作为基础来解决。

有向面积(平行四边形,有正负,在二维中,看旋转向即可,这样就给出了一个1.顺序

POJ  2007 凸多边形点的顺序

凸多边形面积:三角剖分+海伦公式(麻烦)

2.多边形面积(叉乘):找一个点(任一点)按序算各个两个点的组与之构成的有向三角形面积,算一圈累加即可。

3.点线(矢量)关系:判断点在直线的哪一侧(计算几何中直线(因为是矢量)有方向)

两条直线的交点->两个线段的交点(规范相交,另外还有9种情况,带板子,准备充分

补一下,我还不太会

精度不够和精度太高导致WA:例如判断两个点重合(重叠点计数,这样结果是整数,因此误差会被放大)。

能不牵扯角度就不牵扯角度,因为会拖慢速度且会降低精度(增大误差)。

与浮点数相关的运算不能写==(a-b>or<FPS)

double PI=acos(-1);

double INF=1e20;

double EPS=1e-6;

点绕点旋转/点到直线垂线(足)/…

POJ 1569

判断点是否在三角形(多边形)内部:(就是拓扑可定向问题,类似斯托克斯公式的定向)

先把边排序给出(使之连接后是一个封闭曲线),如果点在每一条(相邻两个顶点连成的)直线的同侧,则点在多边形的内部。(出现不同侧则在外部)

进一步地,如何判断这个序是顺时针还是逆时针?(对于凹凸多边形均可用)

方法一:考察最左下角的点和其前点与后点的关系O(nlogn)(需要找点)

方法二:遍历叉乘符号(点乘符号?):看如果不是凸多边形统计符号差(顺时针负号多,逆时针正号多)O(n);凸多边形(顺时针只有负号,逆时针只有正号)O(1).(此法应该有拓扑依据,但是现在想不起来)

旋转卡壳法(钉子和木板)

解释:

因为直线的普通情况不可穷尽,无法枚举,因此枚举极值情况

一般地,直线的可行解在可行域内可以任意地平移与旋转,因此,旋转到卡壳就是其边界,也就是极值-因此,往往要枚举题目中约束线段端点。

POJ 3304

问题:给定一些线段,问是否存在直线L,使得所有线段到L的所有投影至少有一个公共点。
解题思路:如果有存在这样的直线,过投影相交区域作直线的垂线,该垂线必定与每条线段相交,问题转化为问是否存在一条线和所有线段相交。

而被某两个端点限定的两个直线就是可行域中的边界。所以枚举这些直线是否与所有线段都相交即可。

POJ 1039

枚举由上部分一个顶点与下部分一个顶点所限定的直线,其中要判定与折线管道不相交

判定:关于不相交,可以枚举每一部奋的端点(如果上部的所有端点都在一侧;下部的端点都在另一侧则可以说明光线与管道不相交)

POJ 1066 没啥意思 连直线

进阶

点在多边形内外:

1.叉乘-拓扑定向

2. O(n)射线法(最常用):(射线与边界的)交点奇数点在内,交点偶数点在外,在边界上要特判。(具体怎么实现?

因为有特殊情况,所以要找比较别扭(随机)的射线(防hack);实在不行就两条射线,保证交点个数一致。

3. 旋角法

凸包(最常用,考查最频繁)

(不严格地说)对欧式空间来说,离散点集最小的凸边界(顶点由属于集合的点组成,且刚好包裹整个点集)

(意义:保证任何两点的连线都在凸多边形内部与边界)

凸包唯一吗?

轨迹唯一,但是要说明可能有属于点集的点作为凸包边上的点出现。

O(N^2)卷包裹法(点是钉子,拿橡皮筋一绕)

最左最低(最左下)(其必然是凸包的一个端点)为起点,枚举起点与所有点的连线,优先与水平线夹角最小的,以其作为新起点迭代。

O(NlogN)Graham扫描法

最左最低(最左下)(其必然是凸包的一个端点)为起点

极角序

(注意极角序保留不了全部的凸包上的非端点,会由于排序规则的不同而舍弃漏掉的部分)

按极角从小到大排序,同角近在前(or远在前)

stack维护:先加入p0和p1;

(注:左拐or右拐or直走是预备点的后点相对于预备点来说的。)

遍历所有点之后结束。

左拐加入作为预备点,右拐弹出预备点,直走看情况

(保证凸和小)

(如果想保留全部边界则不弹出,不想则弹出)

水平序(代码相对简单但是有特殊情况不适用)

大致框架与极角序相似。

排序先x后y(or先y后x)

对所有的点,类似的stack模拟过程,出现一半壳。

对所有的点逆序同上操作,出现另一半壳,拼起来就是整个凸包。

补一下,我还不太会

总结:不要求保留凸包上的非端点则用极角序,(代码量少,复杂度相同)要求则用水平序(事实上对于极角序实际上可以加个补丁:可以用如线段树的lazy-tag的操作,对于同角不同距离的点,延迟弹出,即到全部弹出时才弹出。)。

POJ  1113 Wall

凸包扩大一下即得,总周长=凸包周长加一个圆的周长(半径就是最小距离)(易证明)。

POJ  1228恢复农场

做凸包,如果任意一条边上有大于等于3个钉子(点),则可确定。

半平面交(线性规划?)

(半平面=有向直线+(一般左)侧)

有限半平面交必然为凸区域

无穷大的区域上的问题可以用一个足够大的矩形框进去。

POJ 1474

能看到的点<=>(转360度)的直线与边界的交点能扫描整个边界。

<=>以边界线段为边界的半平面的交生成的区域内的任意点

晚上训练赛:

打得比较压抑,出了一道签到题之后一直卡在题意上(完全看不懂在说什么...按自己理解的题意与样例试了好几发都wa了,后来补题的时候才搞明白题的意思,题本身很简单,但是一直读不懂题一直卡...

还是要仔细读题,尽量完全读懂再去做。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值