1.向量基础知识
-
(atan2)可以求极角,但是不是特别精确,在坐标接近(10^{9})时会出锅,安全的做法是叉积。
-
旋转、反射和平移等都可以抽象为矩阵,即,它们可以复合。(需要一些必修四知识)
-
给一个序列,每个位置表示旋转、反射、平移中的一种,求((x,y))经过序列([l,r])的点。
线段树维护矩乘就好了,矩阵里需要带个常数位置。
- Simpson积分
不会积分,告辞。
2.简单题
- 求点(p)在直线(p_1p_2)上的投影。
投影就是点积,直接积就行了,必修四怎么学的。
- 求点(p)在直线(p_1p_2)的反射点。
跟上面的一模一样。
- 判断两个向量的(5)种位置关系。
叉积判出不共线的两种,剩下的直接比较横坐标就可以了。
- 给两条直线,问它们是平行还是垂直还是都不是。
平行向量叉积为(0),垂直向量点积为(0)。
- 判两条线段是否相交(不严格,端点交也算)。
跨立实验:对于一条线段,看另一条线段的两个点是否在它两侧,两边都是的话就对。
在一条直线上的情况会锅。
可以先判断外接矩形是否相交。(必要条件,不充分)
- 求两条线段交点,保证有交(其实可以用上面的判一下)。
发现答案是(Acdot k_A)或者(Bcdot k_B)的形式,列两个方程解就行了。
特判共线情况。
- 求两条线段距离。((A,B)各找一个点,使距离最小)。
发现一定取在某条线段的端点,转化为求点到线段距离。
计算(A)在(p_1p_2)上投影占(p_1p_2)比例,(leq 0)离(p_1)最近,(geq 1)离(p_2)最近,否则离投影点最近。
- 逆时针给一个多边形,求面积。
一路叉积过去就好。
- 逆时针给一个多边形,求是否凸。
一路叉积过去,两两边之间的叉积都要(>0)。
- 逆时针给一个多边形,求一个点在多边形内、上还是外。
在多边形上很好判。
射线法,交奇数次在内部,偶数次在外部,但是会出现一些问题。
一种简单办法是把射线斜率设为无理数。
否则就要特判。硬点射线斜率是(0),且水平向右。
依次考虑每条边,平行的可以直接无视。
本质要解决的是穿过顶点的问题。
如果(A)在(R)上,且(AB)向上,或(B)在(R)上,且(AB)向下则算相交。
- 给点集,求凸包。
烂大街经典问题。
- 给凸包,求直径。
旋转卡壳。从横坐标最小和最大的点开始,每次前移一条边(类似双指针)。
- 给凸多边形和一条射线,求凸多边形在射线左侧的面积。
扫一遍凸多边形,把符合要求的顶点和交点都拿出来求面积。
-(n)个点求最近点对。
分治,对于跨过中点的点对,只要找(|x_i-x_j|)不超过(d)的点即可。按(y)排序,每个点有贡献的点是常数个。
- 圆之间的关系:相离((2+2)条公切线),外切((1+2)),相交((0+2)),内切((0+1)),包含((0+0))。
- 求圆和直线的交点。
求出弦心距,即可解出三角形,用夹角计算即可。
- 求两个圆交点。
可以形成一个三边长为(r_1,r_2,dis(o_1,o_2))的三角形,余弦定理解出夹角即可。
- 点到圆的切点。
解三角形求夹角。
- 求两个圆的公切线((0-4)条)。
判一下(0,1)条公切线的情况。否则一定有两条外公切线。
由于公切线垂直于两条半径,可以平移一下,构造一个(r_1-r_2,d,len)的直角三角形,解三角形即可。
内公切线形成了两个相似三角形。
- 求圆和多边形交的面积。
可以把多边形切成若干个有向三角形,转化成圆和三角形交的面积。
不妨把三角剖分的原点设为圆心。
如果整个三角形都在圆内,返回三角形面积。
如果整个(AB)都在圆外(垂线长(geq r)),返回扇形面积。
否则按照(AB)与圆的交点切开,递归处理。发现最多递归常数次。
- 最小圆覆盖。
经典问题,随机增量法。
3.较难题
- (n)个圆盘从天而降,后面的会盖住前面的,求最后可见的轮廓线总长。(nleq 1000)。
对每个圆盘求出后面的圆盘覆盖它的角度区间(求两个交点),并一下即可求出可见弧长。
- 一棵有根树,每个点有(a_i,b_i),从某个点跳到子树某个点上,代价为(a_icdot b_j)。问每个点出发,跳到任意叶子节点最小代价。(n leq 10^5)。
斜率优化的经典形式。启发式合并或者DSU on tree都可以。
- 给若干个向量,每个向量有个代价。可以选若干个,用非负系数组合它们,要求能组合出任意向量,问最小代价。(nleq 2 imes 10^5)。
每个向量等价于一个射线。相当于要找三个向量,使得两两之间极角差$ <pi$。
每个向量取反之后插进去,发现答案一定首尾之间(<pi),并且答案形如“正反正”的三个向量。
特判四个互相垂直的情况。
- (n)个点,问多少对顶点是这些点的三角形不相交(重合面积为(0)且无交点)。(n leq 2000)。
结论:两个三角形不相交等价于它们有两条内公切线。
可以枚举两个点组成的公切线,求出两边点对数。
- 圆反演:有一个圆作为基础,设为单位圆。每个点到圆心的向量方向不变,长度变为倒数。
- (n)次操作,每次加入一个过原点的圆,或者询问一个点((x,y))是否在所有圆内部。(nleq 5 imes 10^5)。
结论:过原点的圆反演后变成一条不过原点的直线。
在圆内部等价于反演后的点在反演后的直线特定的一侧。
动态半平面交,分治维护凸包即可。
- 给定平面上不相交的两个圆和圆外一点,求过这个点且与两个圆外切的圆。
结论:不过原点的圆反演后还是不过原点的圆,且相交/相切等位置关系反演后仍然成立(因为同一个点反演后还是同一个点)。
圆反演后求公切线即可,需要一些特判。
- 给出(n)个不相交的多边形,每次给出一个点,问它在哪个多边形内,或者不在任何一个多边形内,强制在线。(n,qleq 10^5,sum pointsleq 3 imes 10^5)。
多边形不相交是很强的限制。
硬点多边形的边是逆时针给出的。
对每个点找到竖直往上走最近的边,如果是从左往右则不在,否则在对应多边形内部。
如果可以离线,按横坐标扫描线一下,维护线段之间的上下位置关系。由于线段不相交,上下关系只会在插入删除时才会改变。用set维护就行了。
强制在线需要一个可持久化treap,不会写。
一大堆特判。
考虑一个二维平面,横轴时间,纵轴dfs序。
树剖以后变成(mlog n)条线段,求最早相交时间。
按(x)扫描线,set维护(y)的大小关系。
如果两条线段有交,它们一定在某个时刻在set中相邻,否则任意两条线段之间关系不会改变。
插入删除的时候check一下前驱后继即可。
- 一个凸多边形,(q)组询问,给出((x_i,y_i)),求经过这一点的直线,把凸多边形面积平分,输出极角或无解。(nleq 10^4, qleq 10^5)。
设(f(x))表示极角为(x)的射线左侧-右侧的面积。有(f(0)=-f(pi)),所以必然存在零点,二分这个点即可。
考虑对叉积求前缀和,先二分出射线落在哪两条边上,然后内部的变化是线性的,可以直接算。
4.微积分在计算几何中的应用
这一段疯狂掉线……我太菜了。
-
偏导数:多元函数只导其中一维。
-
重积分:多元函数的每一维都积分,比如(k)维空间,对空间的每一个点都取一个函数值,取的足够细时有一个极限。
-
曲线积分:把曲线参数化然后积分。
-
闭合曲线的面积:掉线了,咕咕咕。
-
一元函数的极值:极大不代表最大,只需要一个足够小的邻域,在邻域内最大。极值点导数为(0)。
-
驻点:导数为(0)的点。极值点一定是驻点,驻点不一定是极值点。求一个函数的最大值,可以把所有驻点、不可导点都拉出来check一下。
-
对于多元函数,可以对每一维偏导,然后硬点每个偏导都为(0),解方程就行了。
-
可以把原函数进行修改,使得它在一些边界可导((|x|->x^2))。
-
拉格朗日乘数法:假设有若干(g_i(x_1,…,x_n)=0)的限制条件,在这种条件下最大化(f(x_0,…,x_n))的值,可以设(F(x_0,…,x_n,lambda_0,…,lambda_m)=f(x_0,…,x_n)+sum_{j=0}^mlambda_i g_i(x_1,…,x_n)),然后对(F)的每一维偏导,利用上面的方法求解。
-
曲线的切线、法平面:掉线了,咕咕咕。
-
曲面的切平面、法线:掉线了,咕咕咕。