点与向量
用程序求解几何问题,先要想办法用编程中的数据结构来表示几何对象。这里,使用向量就是解决办法之一。
我们将既有大小又有方向的量称为向量。相对地,只有大小没有方向的量称为标量。为了用数据结构表示向量,将向量考虑成从原点O(0, 0)指向对象点P(x, y)的有向线段。
向量落实在纸面上容易给人带来一种误解,觉得向量可以表示平面上的线段。但实际上,向量只具有大小和方向,而线段却要由两个端点确定,因此用向量表示线段还需要另外规定一个起点。
平面几何中最简单的元素是点(x, y),我们可以用如下所示结构体或类来实现:
表示点的结构体:
struct Point {
double x, y; };
由于向量也可以仅用一个点来定义,所以我们用和点完全相同的数据结构来表示向量。这里的typedef用来给已有数据类型创建新的名称,这样Point和Vector虽然表示同一个数据结构,却可以视情况分开使用(用于不同意义的函数、变量等)。
表示向量的结构体:
typedef Point Vector;
线段与直线
我们可以用包含两个点(起点p1和终点p2)的结构体或类来表示线段。
表示线段的结构体:
struct Segment {
Point p1, p2;
};
要注意区分线段与直线。线段是由两个端点及其间距离定义的具有一定长度的线,而直线是通过两个点且长度无限的线。也就是说,直线由两个不同的点定义,并不具有端点。
直线和线段可以用相同的方法实现。我们用与线段相同的数据结构来表示直线。
表示直线的结构体:
typedef Segment Line;
圆
圆可以用包含圆心c和半径r的结构体或类来表示。
表示圆的类:
class Circle {
public:
Point c;
double r;
Circle(Point c = Point(), double r = 0.0): c(c), r(r) {
}
};
多边形
多边形可以用点的序列来表示。
多边形的表示:
typedef vector<Point> Polygon;
向量的基本运算
向量的几种基本运算:
两个向量的和(sum)a + b
两个向量的差(difference)a - b
一个向量的标量倍(scalar multiplication)ka
向量运算可以定义为函数。我们为了更直观地对点对象进行操作,选择将点的结构体或类之间的运算定义为运算符。C++允许我们对运算符进行定义。
定义点/向量间的运算符:
double x, 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 k) {
return Point(x * k, y * k);
}
x、y表示相应类中的点,p表示对象点。
定义运算符之后,向量间的运算便可以用下面的方法描述了。
向量间的运算示例:
Vector a, b, c, d;
c = a - b;//向量的差
d = a * 2.0;//向量的标量倍
向量的大小
向量a=(ax,ay)a=(a_x,a_y)a=(ax,ay)的大小|a|(absolute,a的绝对值)就是原点到表示向量的点的距离。除此之外,还有表示向量大小的平方的概念,称为范数(norm)。
我们可以这样实现一个以向量为参数,返回该向量大小及范数的函数。
向量的范数及大小:
double norm(Vector a) {
return a.x * a.x + a.y * a.y;
}
double ab