向量,点积和叉积

来源:互联网 发布:数据冰雹重点场所监控 编辑:程序博客网 时间:2024/05/29 13:07

ps:为了好(偷)写(懒),本蒟蒻用va表示a是个向量
再ps:下面讨论的都是平面几何

向量

定义

既有方向,又有长度,且可以自由平移的线段,可称作向量(不是有向线段,有向线段不可以自由平移,因为具有起点)。

实现

程序实现中,我们经常把向量的起点移到(0,0),然后用坐标x,y表示这个向量,向量的加减乘除法可以通过重载实现。

代码

struct Point{    double x,y;    Point(double X=0,double Y=0) {x=X;y=Y;}}; //向量和点可归为一个结构体typedef Point vec;vec operator + (const vec& a,const vec& b) {return vec(a.x+b.x,a.y+b.y);}//向量+向量vec operator - (const vec& a,const vec& b) {return vec(a.x-b.x,a.y-b.y);}//向量-向量vec operator * (const vec& a,double b) {return vec(a.x*b,a.y*b);}//向量*实数vec operator / (const vec& a,double b) {return vec(a.x/b,a.y/b);}//向量/实数

点积

定义

对于两个向量va和vb,他们的点积(也叫数量积)=|va|*|vb|*cosθ,其中θ是va和vb的夹角,这是点积的几何意义。

计算

可以证明,点积也=xa*xb+ya*yb,这就是点积的代数意义。

证明如下:
设va的终点为A(xa,ya),vb的终点为B(xb,yb),则vAB=(xb-xa,yb-ya)
在△AOB中,根据余弦定理,得:|vAB|^2=|va|^2+|vb|^2-2*|va|*|vb|*cosθ
根据距离公式,得:
|va|*|vb|*cosθ={xa^2+ya^2+xb^2+yb^2-[(xb-xa)^2+(yb-ya)^2]}/2
即|va|*|vb|*cosθ=xa*xb+ya*yb

有了这个代数意义的公式,我们就可以方便的计算点积,然后算夹角θ了。

代码

double Dot (const vec& a,const vec& b) {return a.x*b.x+a.y*b.y;}//点积double Length (const vec& a) {return sqrt(a.x*a.x+a.y*a.y);}//长度double Angle (const vec& a,const vec& b) {return acos(Dot(a,b)/Length(a)/Length(b));}//算夹角θ(弧度制)

叉积

定义

对于两个向量va和vb,他们的叉积(也叫向量积)=|va|*|vb|*sinθ,其中θ是va和vb的夹角,这是叉积的几何意义(也就是说叉积=va和vb所成三角形有向面积的2倍)。
ps:叉积是伪向量,因为叉积在不同维度中不同(比如二维中叉积是没有方向的,但是在三维中有方向),但叉积的正负又代表了不同的意思,所以叉积是有向面积但不一定是个向量。
再ps:所以不难发现如果Cross(va,vb)是正数,说明vb在va的逆时针180度内;如果Cross(va,vb)是负数,说明vb在va的顺时针180度内;否则如果Cross(va,vb)=0,说明va和vb在同一条直线上(方向相同或者相反)。

计算

和点积一样,叉积也有代数意义,叉积=xa*yb-xb*ya(这下我不会证明了,有人会的话可以私信我,谢谢!)。

代码

double Cross (const vec& a,const vec& b) {return a.x*b.y-b.x*a.y;}//点积double Area (const Point& a,const Point& b,const Point& c) {return Cross(b-a,c-a);}//求三角形ABC面积的两倍(有向面积)
0 0
原创粉丝点击