计算几何入门
开始之前,给出一些处理小数的方法。
const double pi = acos(-1.0); //圆周率
const double eps = 1e-8; //eps偏差值
int sgn(double x) //判断x大小
{
if(fabs(x) < eps)return 0; //x是0
return x < 0 ? - 1 : 1; //x < 0返回-1,x > 0返回1
}
int dcmp(double x,double y) //比较两个浮点数
{
if(fabs(x - y) < eps)return 0; //两个数相同
return x < y ? -1 : 1; //x < y返回-1,x > y返回1
}
1.二维几何
1.1 点和向量
1.点
二维平面的点用坐标系中的 ( x , y ) (x, y) (x,y) 表示:
struct Point
{
double x, y;
Point(){
}
Point(double _x, double _y):x(_x), y(_y){
}
};
2.两点之间距离
把两个点看成一个 R t △ Rt\triangle Rt△ 的两个顶点算斜边长度:
double Distance(Point a, Point b)
{
return hypot(a.x - b.x, a.y - b.y);//hypot是知道直角三角形两边距离算斜边长。
}
double Dist(Point a,Point b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));//直接计算
}
3.向量
把向量放到直角坐标系中,向量即使由原点 ( 0 , 0 ) (0, 0) (0,0) 指向 一点 ( x , y ) (x, y) (x,y) 的一个有向线段,所以也可以用点表示:
typedef Point Vector;
4.向量的运算
初中的物理的力的合成和向量非常相似。满足平行四边形法则。
加法和减法的规则如上图。
向量乘除法就是按照一个系数 k k k 等比例的缩小和放大。
Point operator + (Point b){
return Point(x + b.x, y + b.y);}
Point operator - (Point b){
return Point(x - b.x, y - b.y);}
Point operator * (double k){
return Point(x * k, y * k);}
Point operator / (double k){
return Point(x / k, y / k);}
bool operator == (Point b){
return sgn(x - b.x) == 0 && sgn(y - b.y) == 0;}
1.2 点积和叉积
1.点积
向量 A , B A, B A,B 的点积 A × B A \times B A×B 的定义为:
A × B = ∣ A ∣ ∣ B ∣ cos θ A\times B = |A||B| \cos\theta A×B=∣A∣∣B∣cosθ
其中, ∣ A ∣ × cos θ |A| \times \cos \theta ∣A∣×cosθ 的定义是向量 A A A 在 B B B 上的投影。
若令 A = ( A . x , A . y ) , B = ( B . x , B . y ) A=(A.x, A.y), B=(B.x, B.y) A=(A.x,A.y),B=(B.x,B.y) ,则:
A × B = A . x × B . x + A . y × B . y A\times B=A.x\times B.x + A.y \times B.y A×B=A.x×B.x+A.y×B.y
如何证明呢?令 A , B A, B A,B 和 x x x 轴夹角分别为 θ 1 , θ 2 \theta_1, \theta_2 θ1,θ2。
则:
原式 = ( ∣ A ∣ cos θ 1 ) ( ∣ B ∣ cos θ 2 ) + ( ∣ A ∣ sin θ 1 ) ( ∣ B ∣ sin θ 2 )