实用几何算法
基本几何算法针对点、线、三角形、多边形等基本几何对象及其二维和三维属性,提供对其计算边界容器、凸包和折线简化的快速算法。
基本几何对象
- 点
- 线
- 射线
- 线段
- 三角形
- 多边形
- 平面
基本几何属性
- 面积
- 距离
- 集合关系
其中, \(\vec{c}\) 是圆心位置向量, \(r\) 是半径, \(t\) 是参数(通常在 \([0,\theta]\))范围内, \(\theta\) 是圆弧的总角度, \(\vec{u}\) 和 \(\vec{v}\) 是与圆弧方向相关的单位向量
圆弧的动态采样方法通常涉及根据弧线的曲率和长度智能地确定采样点的位置和数量
通过计算圆弧的曲率来决定采样点的密度。曲率 \kappaκ 可以用以下公式计算: \(k = \frac{1}{r}\) 曲率越大,表示圆弧的弯曲程度越大,因此在该处可能需要更多的采样点。
将圆弧分成若干段,每段长度根据预设的最大误差或曲率变化来确定。在每段中,根据需要计算或保持一定的采样点密度。
根据曲率和圆弧长度,选择适当的参数步长来控制采样点的分布。通常,在曲率较大的部分和细节较多的区域会使用更小的步长。
根据需要和计算能力,动态调整每段的采样点数量,以平衡精度和性能要求。
始终确保始点和终点包含在采样点列表中,以确保完整性和准确性
在求解 2D 和 3D 的线段与直线的相交性时, 一般采用 “参数方程” 来描述两者
同理可定义另一条直线的方程 \(Q(t) = Q_0 + v(Q_1 - Q_0) = Q_0 + t*\vec{v}\)
当且仅当 \(\vec{u} = a\vec{v}, \ \vec{u} = P_1-P_0, \ \vec{v} = Q_1 - Q_0\)
直角线性坐标系统具有一个固定的绝对参考点作为原点,以及一组非零的坐标轴作为方向向量,这些方向向量确定了测量的方向。
一个坐标系统通过有序的n元组\((x_1, x_2, … x_n)\)来指定n维空间中的点,数值规则为:在第一个轴上, 行动 \(x_1\) 的距离, 然后在第二个轴上, 行动 \(x_2\) 的距离, 一次类推到第n个轴上, 其中有序的数字集合\((x_1, x_2, … x_n)\)称为点的坐标。
所有这些点的集合称为坐标空间。
一组特定的坐标轴构成的坐标空间称为坐标参考框架或空间的基。
不同的坐标系统可以跨越相同的坐标空间。
如果坐标轴彼此独立,即没有任何坐标轴可以写成其他坐标轴的组合,则这些轴被称为独立轴。
当独立时,它们是坐标空间的最小轴集,轴的数量即为空间的维度。
一整套的几何算法, 所以, 应该有一个几何算法的系统只是, 有次第地进行学习
渐进快速的精确算法
一切的问题都可以被几何的语言描述的话
针对 平面点集凸包的构造问题 的众多解决方法
有一种 P 进制数的概念, 其中还有 左进制数, 右进制数
Input: 平面点集 P
Output: 描述凸包的点集 l
Input: 平面点集 P
Output: 描述凸包的点集 l
算法: SLOWCONVEXHULL(P)
Input: 平面点集 P
Output: 由\(CH(P)\)的顶点沿顺时针方向排列成的队列 \(l\)
退化和鲁棒性, 是为了构建完备的几何算法而需要具备的敏感性
所谓退化, 其关联计算机处理浮点数计算过程中的舍入误差而使得几何计算的结果在进入下一次计算时候带来的可能的影响
鲁棒性, 多是因为在构建算法之初, 为了平衡(问题的几何描述的逻辑性而做出的)一些一般性假设与实际问题上的偏差, 对算法的稳定性的度量.
因为实际问题在某个算法的应用场景是有界的, 所以提出一种上帝几何算法的可能, 是有限的.
4.1 沿某个方向\(\vec{d}\)通过一次平移, 多面体\(P\)能够从其铸模中抽取出来, 当且仅当相对于\(P\)的每一张普通面的外法矢, 移动方向\(\vec{d}\)v 与之所呈的角度都至少为 90度
由4.1 可推出: 若可以通过多次小幅度的平移将 p 抽取出, 则必然可以仅通过一次平移就将其抽取出来(向量的合成)
Input: 由平面上 n 张半平面组成的一个集合 H
Output: 凸多边形区域 C
专题图的叠合(也称为地图的叠加或图层叠加)是地理信息系统(GIS)中一种常用的技术, 地理信息系统将(不同类型的)信息划分为若干层(layer), 每一层都是一幅专题图(thematic map)(存放某一特定类型的信息), 用于将多种地理数据的图层组合在一起, 以分析、比较和可视化不同类型的数据。通过叠合,可以发现不同数据集之间的关系、趋势和模式。这种技术广泛应用于城市规划、环境管理、资源评估等领域。
给定由平面上 \(n\) 条闭线段构成的一个集合 \(S\), 求出 \(S\) 中个线段之间
的所有交点. 其中闭线段是指不同线段端点的重合也将被视为交点
我们所希望得到的算法,其运行时间不仅取决于输入中线段的数目,还取决于(实际的)交 点数目。这样的算法,被称为“输出敏感的”算法(output-sensitive algorithm)⎯⎯ 也就 是说,这种算法的运行时间对(实际)输出的大小很敏感。也可以称这样一个算法是“交点 敏感的”(intersection-sensitive)⎯⎯ 因为,输出的大小就是由交点的数目决定的
设两条非水平的线段 \(si\) 和 \(sj\) 只相交于其内部的一点 \(p\),而且,任 何第三条线段都不经过 \(p\)。则在(扫描线到达)高于 \(p\)$ 的某个事件点处( 时),\(si\) 和 \(sj\) 必然会彼此紧邻,并因此接受相交测试(于是对应的交点 将被发现)。
在该算法中的队列是一个有序队列, 且在该队列中的查找是基
于平衡二分查找树(balanced binary search tree).
状态(是与当前扫描线相交的所有线段构成的有序序列), 通过一个状态结构(status structure),可以访问某一给定线段\(s\)的(左、右)邻居.
在插入一个线段\(s\)之后, 就可以立即进行相应的相交测试
这个状态结构式动态的, 当有某条线段开始(或不再)与扫描线相交,就应将它插入到状
态结构中(或从状态结构中删去)
在任一时刻(在某一事件点), 状态结构中的所有线段之间具有一个定义明确的次序(与当前
扫描线相交的每条线段,都按照其次序,),因此可以使用一棵平衡二分查找树来实现状
态结构
只有在扫描线触及某个事件点的时候,算法才会进行实质的处理⎯⎯更新扫描线的状态,并进行一些相交测试
算法: \(FINDINTERSECTIONS(S)\)
Input:平面线段集 S
Output: S 中各线段之间的所有交点(以及穿过各交点的线段的信息)
相交测试算法: \(HANDLEEVENTPOINT(p)\)
判断两条直线是否相交, 如果存在交点, 分两种情况: 1. 已被处理, 2. 未被处理. 另外, 如果两条直线中存在水平直线时候(因为扫描线与 x 轴平行), 即出现与扫描线 y 坐标相同 的事件点时, 按照从左向右的顺序处理
算法: FindNewEvent(sl, sr, p)
算法 FINDINTERSECTIONS 能够正确地计算出所有的交点,并能同时给出穿过各交点的线 段。
对于由平面上任意 n 条线段组成的集合 S,算法 FINDINTERSECTIONS 的运行时间都是 O(nlogn + Ilogn),其中 I 为 S 中各线段之间的交点总数
给定由平面上任意 n 条线段构成的一个集合 S。可以在 O(nlogn + Ilogn)时间内,使用 O(n)空间,报告 出 S 中各线段之间的所有交点,以及与每个交点相关的所有线段。其中 ,I 为实际的交点总数