向量的点乘与叉乘(转载)

来源:互联网 发布:软件无限试用 编辑:程序博客网 时间:2024/04/28 18:36
向量(Vector
在几乎所有的几何问题中,向量(有时也称矢量)是一个基本点。向量的定义包含方向和一个数(长度)。在二维空间中,一个向量可以用一对xy来表示。例如由点(1,3)到(5,1的向量可以用(4,-2)来表示。这里大家要特别注意,我这样说并不代表向量定义了起点和终点。向量仅仅定义方向和长度。

向量加法
向量也支持各种数学运算。最简单的就是加法。我们可以对两个向量相加,得到的仍然是一个向量。我们有:
    V1
x1, y1+V2x2, y2=V3(x1+x2, y1+y2)
下图表示了四个向量相加。注意就像普通的加法一样,相加的次序对结果没有影响(满足交换律),减法也是一样的。

 

点乘(Dot Product
如果说加法是凭直觉就可以知道的,另外还有一些运算就不是那么明显的,比如点乘和叉乘。
点乘比较简单,是相应元素的乘积的和:
    V1( x1, y1)   V2(x2, y2) = x1*x2 + y1*y2
注意结果不是一个向量,而是一个标量(Scalar)。点乘有什么用呢,我们有:
    A   B = |A||B|Cos(θ)
θ
是向量A和向量B见的夹角。这里|A|我们称为向量A的模(norm),也就是A的长度, 在二维空间中就是|A| = sqrt(x2+y2)。这样我们就和容易计算两条线的夹角
    Cos(θ) = A   B /(|A||B|)

当然你知道要用一下反余弦函数acos()啦。(回忆一下cos(90)=0 cos(0) = 1还是有好处的,希望你没有忘记。)这可以告诉我们如果点乘的结果,简称点积,为0的话就表示这两个向量垂直。当两向量平行时,点积有最大值
另外,点乘运算不仅限于2维空间,他可以推广到任意维空间。(译注:不少人对量子力学中的高维空间无法理解,其实如果你不要试图在视觉上想象高维空间,而仅仅把它看成三维空间在数学上的推广,那么就好理解了)


叉乘(cross product
相对于点乘,叉乘可能更有用吧。2维空间中的叉乘是:
    V1(x1, y1) X V2(x2, y2) = x1y2 – y1x2
看起来像个标量,事实上叉乘的结果是个向量,方向在z轴上。上述结果是它的模。在二维空间里,让我们暂时忽略它的方向,将结果看成一个向量,那么这个结果类似于上述的点积,我们有:
    A x B = |A||B|Sin(θ)
然而角度 θ和上面点乘的角度有一点点不同,他是有正负的,是指从AB的角度。下图中 θ为负。
另外还有一个有用的特征那就是叉积的绝对值就是AB为两边说形成的平行四边形的面积。也就是AB所包围三角形面积的两倍。在计算面积时,我们要经常用到叉积。
(译注:三维及以上的叉乘参看维基:http://en.wikipedia.org/wiki/Cross_product


-线距离
找出一个点和一条线间的距离是经常遇见的几何问题之一。假设给出三个点,ABC,你想找出点C到点AB定出的直线间距离。第一步是找出AB的向量ABAC的向量AC,现在我们用该两向量的叉积除以|AB|,这就是我们要找的的距离了(下图中的红线)。
    d = (AB x AC)/|AB| 


如果你有基础的高中几何知识,你就知道原因了。上一节我们知道(AB X AC)/2是三角形ABC的面积,这个三角形的底是|AB|,高就是CAB的距离。有时叉积得到的是一个负值,这种情况下距离就是上述结果的绝对值。
当我们要找点到线段的距离时,情况变得稍稍复杂一些。这时线段与点的最短距离可能是点到线段的某一端点,而不是点到直线的垂线。例如上图中点C到线段AB的最短距离应该是线段BC。我们有集中不同的方法来判断这种特殊情况。第一种情况是计算点积AB Bc来判定两线段间夹角。如果点积大于等于零,那么表示ABBC是在-9090度间,也就是说CAB的垂线在AB外,那么AB上到C距离最近的点就是B。同样,如果BAAC大于等于零,那么点A就是距离C最近的点。如果两者均小于零,那么距离最近的点就在线段AB中的莫一点。

源代码参考如下:

     //Compute the dot product AB   BC
     int dot(int[] A, int[] B, int[] C){
         AB = new int[2];
         BC = new int[2];
         AB[0] = B[0]-A[0];
         AB[1] = B[1]-A[1];
         BC[0] = C[0]-B[0];
         BC[1] = C[1]-B[1];
         int dot = AB[0] * BC[0] + AB[1] * BC[1];
         return dot;
     }
     //Compute the cross product AB x AC
     int cross(int[] A, int[] B, int[] C){
         AB = new int[2];
         AC = new int[2];
         AB[0] = B[0]-A[0];
         AB[1] = B[1]-A[1];
         AC[0] = C[0]-A[0];
         AC[1] = C[1]-A[1];
         int cross = AB[0] * AC[1] - AB[1] * AC[0];
         return cross;
     }
     //Compute the distance from A to B
     double distance(int[] A, int[] B){
         int d1 = A[0] - B[0];
         int d2 = A[1] - B[1];
         return sqrt(d1*d1+d2*d2);
     }
     //Compute the distance from AB to C
     //if isSegment is true, AB is a segment, not a line.
     double linePointDist(int[] A, int[] B, int[] C, boolean isSegment){
         double dist = cross(A,B,C) / distance(A,B);
         if(isSegment){
             int dot1 = dot(A,B,C);
             if(dot1 > 0)return distance(B,C);
             int dot2 = dot(B,A,C);
             if(dot2 > 0)return distance(A,C);
         }
         return abs(dist);
     }

上面的代码看起来似乎是很繁琐。不过我们可以看看在C++C#中,采用了运算符重载的类point,用‘*’代表点乘,用'^'代表叉乘(当然'+''-'还是你所希望的),那么看起来就简单些,代码如下:

   //Compute the distance from AB to C
     //if isSegment is true, AB is a segment, not a line.
     double linePointDist(point A, point B, point C, bool isSegment){
         double dist = ((B-A)^(C-A)) / sqrt((B-A)*(B-A));
         if(isSegment){
             int dot1 = (C-B)*(B-A);
             if(dot1 > 0)return sqrt((B-C)*(B-C));
             int dot2 = (C-A)*(A-B);
             if(dot2 > 0)return sqrt((A-C)*(A-C));
         }
         return abs(dist);
     }
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 天猫被投诉商标侵权怎么办 虚假发货有天猫红包怎么办 淘宝代购是假货怎么办 闲鱼对方不在怎么办 小米商城退款慢怎么办 小米手机第三方拿货是怎么办 oppo手机卡被锁怎么办 下巴粉刺特别多怎么办 苹果6sp手机卡怎么办 苹果手机无服务怎么办 京东买电脑没发票怎么办 买东西发票丢了怎么办 在天猫上买了假货怎么办 苹果发票丢了怎么办 iphone8屏幕摔了怎么办 在手机店买到翻新机怎么办 信用卡网上买东西退款怎么办 在唯品会买到假的护肤品怎么办 天猫买东西发票怎么办 支付宝无法收款怎么办 买到苹果假货怎么办 16周岁怎么办手机分期 淘宝打假扣分了怎么办 买到不合格食品怎么办 买到不合格面膜怎么办 买假货怎么处理怎么办 咸鱼买手机被骗怎么办 华为p9超级卡怎么办 花呗分期退货怎么办 华为荣耀10网咯好卡怎么办 官网买手机坏了怎么办 三星c5发热严重怎么办 iphone7一直重启怎么办 预售商品不发货怎么办 vivo手机跑电快怎么办 手机跑电太快了怎么办 手机home键失灵怎么办 小米手机发货慢怎么办 京东卡1元流量怎么办 苹果手机系统太大怎么办 苹果电池用电快怎么办