叉积
来源:互联网 发布:淘宝买管制刀具 编辑:程序博客网 时间:2024/05/01 11:14
1.叉积判断线段拐向
如上图,可以通过计算向量的叉积来判断拐向,即判断(C-B)×(A-B)的符号。
#若(C-B)×(A-B)> 0 ,则CB在B点顺时针得到AB
#若(C-B)×(A-B)< 0 ,则CB在B点逆时针得到AB
#若(C-B)×(A-B)= 0 ,则A,B,C三点共线。
如图,我们给三个点A,B,C,判断沿着AB到BC,在B点是向右拐还是向左拐。并求出拐的 角度。这个先直接用叉积判断拐向,然后再余弦定理计算角度即可,
用180减去这个角度便是拐的角度。
2.叉积还有一个重要的用处,就是用来求面积。
叉积用来求面积,求出的是有向面积,也就是说带正负号,
不过再取一下绝对值就是真正的面积大小了。
比如求三角形ABC的面积,先计算出叉积cross(A,B,C),
那么面积就是fabs(cross(A,B,C))/ 2.0
为什么呢?
我们看一下叉积的定义就知道了,a与b的叉积模为:
|a×b|=|a| |b| sin(a,b)他的几何意义就是以a和b为邻边的平行四边形的面积。
例1:(http://acm.hdu.edu.cn/showproblem.php?pid=2036)
#include <iostream>#include <stdio.h>#include <cmath>using namespace std;int main(){int n; int x[105],y[105]; while(cin>>n&&n!=0) { double sum=0; for(int i=0;i<n;i++) { cin>>x[i]>>y[i]; } for(int i=1;i<n-1;i++) { sum+=(x[i]-x[0])*(y[i+1]-y[0])-(x[i+1]-x[0])*(y[i]-y[0]); } printf("%.1lf\n",fabs(sum)/2); } //cout << "Hello world!" << endl; return 0;}
例2:
判断点p是否在三角形内。
若在三角形内,则必有S.abc=S.abp+S.acp+S.bcp;若在三角形外,式子就不成立。
3.叉积能判断两直线是否相交。
对于给出的两条线段A1A2,B1B2,判断他们是否相交需要分两步
(1)快速排斥实验
设以线段A1A2和线段B1B2为对角线的矩形为M,N;
若M,N 不相交,则两个线段显然不相交;
判断矩形相交,只需判断某一矩形是否有顶点在另一个矩形内即可。
所以:只有当满足第一个条件时,两个线段才可能相交。
(2)跨立实验
如果两线段相交,则两线段必然相互跨立对方.若A1A2跨立B1B2,则矢量( A1 - B1 ) 和(A2-B1)位于矢量(B2-B1)的两侧,
即:((A1-B1) × (B2-B1) )·( (A2-B1) × (B2-B1))<0。
上式可以改写成:((A1-B1) × (B2-B1)) · ((B2-B1) × (A2-B1))>0。
当(A1-B1) × (B2-B1)=0时,说明A1B1和B2B1共线,但前面已经通过了快速排斥实验,所以A1一定在B1B2上,所以判断线段A1A2是否跨立B1B2的依据就是:
((A1-B1) × (B2-B1)) · ((B2-B1) × (A2-B1))>=0。
同理,判断线段B1B2是否跨立A1A2的依据是:((B1-A1) × (A2-A1)) · ((A2-A1) × (B2-A1))>=0。
图示:
例:(http://acm.hdu.edu.cn/showproblem.php?pid=1086)
#include <iostream>#include <cmath>using namespace std;struct point{ double x,y;};double mult(point a,point b,point c){ return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);}bool cross(point a,point b,point c,point d){ if(max(a.x,b.x)>=min(c.x,d.x)&&max(c.x,d.x)>=min(a.x,b.x)&& max(a.y,b.y)>=min(c.y,d.y)&&max(c.y,d.y)>=min(a.y,b.y)&& mult(d,a,c)*mult(d,c,b)>=0&&mult(a,c,b)*mult(a,b,d)>=0) return true; else return false;}int main(){int n; point a[105],b[105]; int sum; while(cin>>n&&n) { sum=0; for(int i=0;i<n;i++) {cin>>a[i].x>>a[i].y; cin>>b[i].x>>b[i].y;} for(int i=0;i<n-1;i++) { for(int j=i+1;j<n;j++) { if(cross(a[i],b[i],a[j],b[j])) sum++; } } cout<<sum<<endl; } //cout << "Hello world!" << endl; return 0;}
- 叉积
- 叉积
- 叉积
- 叉积
- 叉积
- 叉积
- 叉积
- [zz]叉积
- 1.4 叉积
- 求直线交点 叉积
- 叉积+二分:Toy Storage
- 求直线交点 叉积
- PKU 2318 叉积+二分
- NEFU 652 叉积
- poj 3304 叉积
- [复习] 向量-叉积
- TOYS - POJ 2318 叉积
- hdu2398 叉积+二分法
- Object-C内存管理
- Android 5.1 如何内置APK在/system/priv-app目录下的Android.mk
- 内存管理
- HTTP协议 (二) 基本认证
- HUD 5176 The Experience of Love
- 叉积
- ExtJS的History使用
- 20. JavaScript 事件处理
- HDU 1181--变形课【DFS】
- OpenCV中GPU模块使用
- Android.mk文件语法规范(Android.mk File)
- Xcode5发布企业版app
- C++中的substr()和find()
- 华为机试——将一个字符串的元音字母复制到另一个字符串,并排序