//结构体表示点
struct Point{
int x,y;
};
我们将既有大小又有方向的量称为“向量”。相对的,只有大小没有方向的量称为“标量”。这里,将向量考虑成从源点(0,0)指向对象点P(x,y)的有向线段。
//同时也完全可以用点的数据结构来表示向量
typedef Point Vector;
我们可以用包含两个点(起点p1和终点p2)的结构体或类来表示线段。这里要区分线段和直线,线段有始有终,而直线是通过两个点且长度无线的线。
struct Segment{
Point p1,p2;
};
//直线数据结构的表示和线段相同(注意区别)
typedef Segment Line
紧接着就是圆的表示了,所谓确定圆心和半径可以确定一个圆,这里我们用类表示。
class Circle{
public:
Point c;
double r;
Circle(Point c=Point(),double r=0.0):c(c),r(r){}
};
多边形就是许多点组成的封闭图形,所以可以用点的序列来表示。
typedef vector<Point> Polygon;
向量的基本运算(通过坐标运算实现)
向量的运算共有三种:向量的和(sum),向量的差(difference)
,向量的标量倍(scalar multipliaction)
。以下我们将点和向量写成类的形式并附加上运算函数以及 求向量大小和范数的函数。
#define EPS (1e-10)
#define equals(a,b) (fabs((a)-(b)) < EPS)
class Point{
public:
double x,y;
Point(double x=0,double y=0):x(x),y(y){}
Point operator + (Point p){
return Point(x+p.x,y+p.y);
}
Point operator - (Point p){
return Point(x-p.x,y-p.y);
}
Point operator * (double a){
return Point(a*x,a*y);
}
Point operator / (double a){
return Point(x/a,y/a);
}
double abs(){
return sqrt(norm());
}
double norm(){
return x*x+y*y;
}
//递增的顺序
bool operator < (const Point &p) const{
return x!=p.x?x<p.x:y<p.y;
}
//有精度误差(在规定的精度范围内都视为相同)
bool operator == (const Point &p) const{
return fabs(x-p.x)<EPS&&fabs(y-p.y)<EPS;
}
};
为了以后解决几何的相关问题,向量的内积和外积必不可少。
设向量a、b的夹角θ(0≤θ≤180),那么a,b的内积(dot product)。如图所示(手画一张):
//向量a和b的内积a·b=|a||b|cosθ
double dot(Vector a,Vector b){
return a.x*b.x+a.y*b.y;
}
a,b的外积(cross product)。两个向量的外积是一个具有大小和方向的向量。如下图所示,外积的方向与a,b所在的平面垂直,且满足右手螺旋定则。
//向量a和b的外积|a×b|=|a||b|sinθ
double cross(Vector a,Vector b){
return a.x*b.y-a.y*b.x;
}
可以继续噢——计算几何学(2)。