您的位置:首页 > 其它

向量,点积和叉积

2017-02-24 21:22 190 查看
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面积的两倍(有向面积)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: