二维计算几何基础
二维计算几何基础
前置
-
基本的几何知识
-
平面直角坐标系
-
向量
极坐标与极坐标系
我们在做题的时候会遇到说“点 \(B\) 在点 \(A\) 北偏东 \(30^{\circ}\) 方向上,距离 \(100\) 米”之类的,实际情况也是如此,而不是用“以 \(A\) 为原点建立平面直角坐标系,\(B(50,50\sqrt{3})\)”。
-
在平面选定一个点 \(O\),称之为极点
-
自极点引出一条射线 \(Ox\),称为极轴
-
选择一个单位长度(在数学问题上通常为 \(1\)),一个角度单位(通常是弧度)及其正方向(通常是逆时针方向)
就建立了极坐标系
极坐标系下的位置描述
设 \(A\) 为平面上一点。
-
极点 \(O\) 与 \(A\) 之间的距离 \(|OA|\) 称为极径,记为 \(\rho\)
-
以极轴为始边,\(OA\) 为终边的角 \(\angle xOA\) 称为极角,记为 \(\varphi\)
那么有序数对 \((\rho,\varphi)\) 即为 \(A\) 的极坐标
由于 \((\rho,\varphi)\) 与 \((\rho,\varphi+2k\pi)(k\in\mathbb{Z})\) 表示的其实是一样的点,所以如果规定 \(\rho\ge0,0\le \varphi<2\pi\),那么除极点以外都可以用唯一的有序数对来表示。
特别的,极点在没有限制的条件下可以表示成 \((\rho,\varphi)(\varphi\in\mathbb{R} )\),所以极点的表示方法是无数种。
图形的记录
点
在平面直角坐标系中,我们可以用一个数对来表示,也就是一个坐标,比如点 \((9,7),(2,3)\) 等等。
我们记录其横纵坐标值即可,我们可以用 pair
或者结构体来存储。
在极坐标系下,用极坐标表示即可。记录其极径与极角。
向量
由于向量的坐标表示和点相同,所以只要像点一样存即可(当然点不是向量
在极坐标系下,与点同理。
当然这里如果不了解数量积和向量积的话建议自己看一下。
直线与射线
考虑我们只想知道这条直线在哪,它的倾斜程度怎么样。于是我们用直线上一个点来大致确定位置,然后用一个向量来表示它的倾斜程度,好了,这条直线确定了。
因此我们记录的是:直线上一点和直线方向的方向向量。
线段
线段比较好记录,只要记录两个数组就好了。
在极坐标下记录线是比较麻烦的,所以大多数直线问题都在平面直角坐标系下解决。
多边形
我们可以直接用数组来依次记录多边形的每一个顶点即可。
特殊的,如果是各边都与坐标轴平行的矩形,我们可以只记录左下角和右上角的顶点。
曲线
一些特殊曲线,如二次函数,反比例函数等其他的函数图像,我们可以记录他们的解析式,对于圆,我们可以只记录其圆心坐标和半径长度。
基本公式
必修四应该学的。
正弦定理
在 $\triangle{ABC} $ 中,若角 \(A,B,C\) 所对应的边分别为 \(a,b,c\),则有:
其中,\(R\) 为 \(\triangle ABC\) 的外接圆的半径。
余弦定理
在 \(\triangle ABC\) 中,若角 \(A,B,C\) 所对应的边分别为 \(a,b,c\),则有:
判断一个点在直线的哪边
我们有直线上的一点 \(P\) 的直线的方向向量 \(v\),想知道某个点 \(Q\) 在直线的哪边。
我们利用向量积的性质,算出 \(\overrightarrow{PQ}\times v\),如果向量积为负,则 \(Q\) 在直线上方,如果向量积为 \(0\),则 \(Q\) 在直线上,如果向量积为正,则 \(Q\) 在直线下方。
快速排斥实验与跨立实验
我们需要判断两条线段是否相交。
首先判断一些特殊情况,如果两线段平行,自然不能相交。这种情况通过判断线段所在的直线的斜率是否相等即可。
当然,如果两线段重合或者部分重合或两线段的交点为其中一条线段的端点,只需要判断是否有三点共线的情况即可。
规定一条线段的区域为以这条线段为对角线的,各边均与坐标轴平行的矩形所占的区域,如果这两个区域没有公共区域,那么这两条线段一定不相交。
比如有下面两条线段。
他们的占用区域是这样的:
于是可以快速地判断出来这两条线段不相交。
这就是快速排斥实验。
但是两个区域有重合部分却不一定是相交的线段,比如下面这样:
很明显他们的占用的区域是有交的,但这两条线段并没有交集。
因为两线段 \(a,b\) 相交,\(b\) 线段的两个端点一定分布在 \(a\) 线段所在的直线两个;同理 \(a\) 线段的两个端点一定分布在 \(b\) 线段所在的直线两侧。我们可以直接判断一条线段的两个端点相对于另一条线段所在直线的位置关系,如果不同,则两线段相交,反之则不相交。对于直线与点关系的判断,我们可以用向量积来判断。
上述方法称为跨立实验。
注意到当两条线段共线但不相交时也可以通过跨立实验,因此想要准确判断还需要与快速排斥实验结合。
判断一个点是否在任意多边形内部
光线投射算法
我们可以先判断一些特殊情况,考虑一个能够完全覆盖此多边形的一个最小矩形,如果这个点不在这个矩形范围内,那么这个点一定不在多边形内。这样的矩形很好求,只需要知道多边形横坐标与纵坐标的最小值和最大值,坐标两两组合成四个点,就是这个矩形的四个顶点了。
在多边形边和点上时,对于点我们可以直接枚举判断,对于边,我们可以用斜率加起始的 \(x\) 坐标结合来判断。
我们考虑以该点为端点引出一条射线,如果这条射线与多边形有 奇数个交点,则该点在多边形内部,否则在该多边形外部,我们简记为奇内偶外。这个算法同样被称为奇偶规则。
我们看上面的图,其中 \(K,H\) 分别为在多边形外和多边形内的两点,我们对于上面的算法来寻找个例。
例如射线 \(KL\),我们对于经过边的情况计算的交点个数没有明确的定义,所以我们在挑选射线时需要舍去会和边重合的情况。
我们发现,射线 \(KM\) 与多边形的交点为三个,但是 \(K\) 实际上是在多边形外部。
同样的,我们可以看到射线 \(HJ\) 与多变形的交点为两个,但 \(H\) 实际上在多边形内部。
所以我们也要挑选没有经过点的射线。
当然可能经过了点也是正确的答案,比如上面如果作射线 \(KF\) 的话我们得到的就是正确的结论,但我们并不可能在代码中加入更多繁琐的代码来判断这个,毕竟没有经过点和没有和边共线的情况多了去了。
回转数算法
回转数是数学上的概念,是平面内闭合曲线逆时针绕过该点的总次数。很容易发现,当回转数等于 \(0\) 的时候,点在曲线外部,这个算法同样被称为非零规则。
我们把该点与多边形的所有顶点链接起来,计算相邻两边夹角的和。注意这里的夹角是有方向的。如果夹角和为 \(0\),则这个点在多边形外,否则在多边形内。
求两条直线的交点
首先,我们需要确定两条直线相交,只需判断一下两条直线的方向向量是否平行即可。
如果方向向量平行,则两条直线平行,交点个数为 \(0\)。进一步地,若两条直线平行且过同一点,则两直线重合。
然后我们有直线 \(AB,CD\) 交于一点,想求出交点 \(E\)。
如果两直线相交,则交点只有一个,我们记录了直线上的一个点和直线的方向向量,所以我们只需要知道这个点与交点的距离 \(l\),再将这个点沿方向向量平移 \(l\) 个单位长度即可。
考虑构造三角形,利用正弦定理来求解 \(l\),可以利用向量积构造出正弦定理。
由上图可知,\(|a\times b|=|a||b|\sin\beta,|u\times b|=|u||b|\sin\theta\)。
做商得:
可以看出 \(|\frac{|u|\sin\theta}{\sin\beta}|=l\).若绝对值内部式子取值为正,代表沿 \(a\) 方向平移,反之则为反方向。
同时,我们将 \(T\) 直接乘上 \(a\),就自动出现了直线的单位向量,不需要进行其他消去操作了。
于是,只需要将点 \(B\) 减去 \(Ta\) 即可得出交点。
求任意多边形的周长和面积
求周长
没有好办法,枚举每两个点就是最好的。
求面积
考虑向量积的模的几何意义,我们可以利用向量积来完成。
将多边形上的点逆时针标记为 \(p_{1},p_{2},\dots,p_{n}\),再任选一个辅助点 \(O\),记向量 \(v_{i}=p_{i}-O\),那么这个多边形的面积 \(S\) 可以表示为:
圆与直线相关
求直线与圆的交点
首先判断直线与圆的位置关系。如果直线与圆相离则无交点,若相切则可以利用切线求出切点与半径所在直线,之后转化为求两直线交点。
若有两交点,则可以利用勾股定理求出两交点的中点,然后沿直线方向加上半弦长即可。
求两圆交点
首先我们判断一下两个圆的位置关系,如果外离或内含则无交点,如果相切,可以算出两圆心连线的方向向量,然后利用两圆半径计算出平移距离,最后将圆心沿这个方向向量进行平移即可。
如果两圆相交,则必有两个交点,并且关于两圆心连线对称。因此下面只说明一个交点的求法,另一个交点可以用类似方法求出。
我们先将一圆圆心与交点相连,求出两圆心连线与该连线所成角。这样,将两圆心连线的方向向量旋转这个角度,就是圆心与交点相连形成的半径的方向向量了。
最后还是老套路——沿方向向量方向将圆心平移半径长度。
极角序
一般来说,这类题需要先枚举一个极点,然后计算出其他点的极坐标,在极坐标系下按极角的顺序解决问题。
大部分参考自 oiwiki