转自 北京大学暑期课《 ACM/ICPC竞赛训练》
什么是计算几何?
- 计算几何 Computational Geometry
- 研究几何形体的计算机表示、分析与综合
- “计算几何” ——以计算为主的几何
计算几何有何用?
计算几何题的特点
- 题目比较长
- 图形抽象,需要良好的数学基础和空间想象能力
- 有许多容易忽视的特殊情况,而且往往需要单独处理,代码量大
- 需要考虑浮点运算时产生的精度误差
- 可以与其他类型的题目结合,从而更加复杂
- 常作为压轴题目出现在程序设计竞赛中
基础 -- 点、线、面
几何图形的表示
有没有更好的办法?
矢量法
- 表示简单
- 功能强大
- 特殊情况少,思维难度较低
- 函数可重复利用(即所谓的“模版”)
- 尽可能避免除法和三角函数,精度高,效率高
矢量表示
class CVector {
double x, y;
};
表示从0点到 ( x,y)的矢量
对矢量只关心方向和长度,不关心(位置)起点终点
矢量的基本运算
CVector operator + (CVector p, CVector q) {
return CVector(p.x + q.x, p.y + q.y);
}
用法: c = a + b;
//a,b,c都是CVector对象
CVector operator - (CVector p, CVector q) {
return CVector(p.x - q.x, p.y - q.y);
}
用法: c = a - b;
//a,b,c都是CVector对象
CVector operator *(double k, CVector p) {
return CVector(k * p.x, k * p.y);
}
用法: c = f * a;
//a是CVector对象,f是double
C方向与a相同, |c| = f * |a|
矢量的点积
- 性质: p · q = |p| |q| cos<p,q>
double operator *(CVector p, CVector q) {
return p.x * q.x + p.y * q.y;
}
a与b的点积,就是a的模乘以b在a上投影的模
若投影与a方向相反则为负值
功能:
- 求同向还是异向;
- 求投影;
- 求出投影后用勾股定理求点到直线距离;
用法: double c = a * b; //b,c都是CVector对象
- 若 a * b = 0,则 a和b垂直
矢量模长
- 用矢量与自身点积求模
double length(CVector p) {
return sqrt(p * p);
} //求矢量的模
矢量单位化
- 将矢量除以自身的长度以得到同方向的单位矢量
CVector unit(CVector p) {
return 1 / length(p) * p;
}
矢量的投影长度
- 矢量与该方向单位矢量的点积
- 注意:负数表示反方向
double project(CVector p, CVector n) {
return dot(p, unit(n)); //点积
}
double dot(CVector p, CVector q) {
return p.x*q.x+p.y*q.y;
}
矢量的叉积
- 性质:在二维情况中,|p×q|=|p||q|sin<p,q>
- a×b 为有向面积,可正可负
若a逆时针旋转小于180度可到b,则结果为正,否则结果为负
向量旋转公式的证明:https://www.zybang.com/question/143ceaa20d3942f3c6dbe9415dd81d0a.html
三角形外接圆圆心公式的证明: