计算几何基础——【点积和叉积的用处】

计算几何是算法竞赛的一大块,而叉积是计算机和的基础。

首先叉积是计算说向量之间的叉积,那么我们可以这样定义向量,以及向量的运算符重载。

struct Point
{
    double x,y;
    Point(double x=0,double y=0):x(x),y(y) {}
};
typedef Point Vector;
Vector operator + (Vector A,Vector B) { return Vector(A.x+B.x,A.y+B.y); }
Vector operator - (Vector A,Vector B) { return Vector(A.x-B.x,A.y-B.y); }
Vector operator * (Vector A,double p) { return Vector(A.x*p,A.y*p); }
Vector operator / (Vector A,double p) { return Vector(A.x/p,A.y/p); }

bool operator < (const Point& a,const Point& b)
{
    return a.x<b.x || (a.x==b.x && a.y<b.y);
}
int dcmp(double x)  //
{
    if(fabs(x)<esp) return 0;
    else return x<0?-1:1;
}
bool operator == (const Point& a,const Point& b)
{
    return dcmp(a.x-b.x) == 0 && dcmp(a.y-b.y)==0;
}

首先在二维坐标下介绍一些定义:

点:A(x1,y1),B(x2,y2)

向量:向量AB=( x2 - x1 , y2 - y1 )= ( x ,  y );

向量的模 |AB| = sqrt ( x*x+y*y );

向量的点积: 结果为 x1*x2 + y1*y2。

点积的结果是一个数值。

点积的集合意义:我们以向量 a 向向量 b 做垂线,则 | a | * cos(a,b)为 a 在向量 b 上的投影,即点积是一个向量在另一个向量上的投影乘以另一个向量。且满足交换律

应用:可以根据集合意义求两向量的夹角,cos(a,b) =( 向量a * 向量b ) / (| a | * | b |) =  x1*x2 + y1*y2 / (| a | * | b |)

向量的叉积: 结果为 x1*y2-x2*y1

叉积的结果也是一个向量,是垂直于向量a,b所形成的平面,如果看成三维坐标的话是在 z 轴上,上面结果是它的模。

方向判定:右手定则,(右手半握,大拇指垂直向上,四指右向量a握向b,大拇指的方向就是叉积的方向)

叉积的集合意义:1:其结果是a和b为相邻边形成平行四边形的面积。

2:结果有正有负,有sin(a,b)可知和其夹角有关,夹角大于180°为负值。

3:叉积不满足交换律

应用:

1:通过结果的正负判断两矢量之间的顺逆时针关系

若 a x b > 0表示a在b的顺时针方向上

若 a x b < 0表示a在b的逆时针方向上

若 a x b == 0表示a在b共线,但不确定方向是否相同

2:判断折线拐向,可转化为判断第三点在前两的形成直线的顺逆时针方向,然后判断拐向。

3:判断一个点在一条直线的那一侧,同样上面的方法。

4:判断点是否在线段上,可利用叉乘首先判断是否共线,然后在判断是否在其上。

5:判断两条直线是否想交(跨立实验)

根据判断点在直线那一侧我们可以判断一个线段的上的两点分别在另一个线段的两侧,当然这是不够的,因为我们画图发现这样只能够让直线想交,而不是线段,所以我们还要对另一条线段也进行相同的判断就ok。

代码:

///计算点积,及向量长度,及向量夹角
double Dot(Vector A,Vector B) { return A.x*B.x+A.y*B.y; }
double Length(Vector A) { return sqrt(Dot(A,A)); }
double Angle(Vector A,Vector B) { return acos(Dot(A,B))/Length(A)/Length(B); }
//计算叉积,向量逆时针旋转,两线段是否想交
double Cross(Vector A,Vector B) { return (A.x*B.y-A.y*B.x); }
double Area2(Vector A,Vector B,Vector C)  { return Cross(B-A,C-A); }
Vector Rotate(Vector A,double rad)
{
    return Vector(A.x*cos(rad)-A.y*sin(rad),A.x*sin(rad)+A.y*cos(rad));
}
bool Converxline(Vector A,Vector B,Vector C,Vector D)
{
    //共线或平行
    if((Area2(A,B,C)==0&&Area2(A,B,D)==0) || Area2(A,B,C)*Area2(A,B,D)>0||Area2(C,D,A)*Area2(C,D,B)>0)
        return false;
    else
        return true;
}

计算几何基础——【点积和叉积的用处】

时间: 2024-11-09 07:38:15

计算几何基础——【点积和叉积的用处】的相关文章

nyis oj 68 三点顺序 (计算几何基础)

三点顺序 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描写叙述 如今给你不共线的三个点A,B,C的坐标,它们一定能组成一个三角形,如今让你推断A,B,C是顺时针给出的还是逆时针给出的? 如: 图1:顺时针给出 图2:逆时针给出 <图1>                   <图2> 输入 每行是一组測试数据,有6个整数x1,y1,x2,y2,x3,y3分别表示A,B,C三个点的横纵坐标.(坐标值都在0到10000之间) 输入0 0 0 0 0 0表示输入

知识点 - 计算几何基础

知识点 - 计算几何基础 讲义 点 我们把点 \(\mathbf r\) 看成从 \(\mathbf 0\) 到 \(\mathbf r\)的向量 \(\vec{\mathbf r}\) #define ftype long double struct point2d { ftype x, y; point2d() {} point2d(ftype x, ftype y): x(x), y(y) {} point2d& operator+=(const point2d &t) { x +=

【kuangbin专题】计算几何基础(极角相关)

[POJ 1696] Space Ants [题目大意] 给定多个点,对他们按照下面的规则排序,每个都在前一个点组成的左边,并且连线不相交(典型如图) [题目分析] 不断进行极角排序,不断选取一定区域内最符合要求的解 [代码] 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define ll double 5 using namespace std; 6 const double eps

关于向量点积和叉积的回顾和总结

一.点积 1.数量积,返回数值. 2.公式:a*b=|a|*|b|*cosθ,适用于二维和三维.向量基本以坐标的形式给出,计算的的话就是对应位置的相乘,然后相加,可以扩展到n维. 3.根据公式,我们可以判断这两个两个向量成锐角(<0),直角(=0),钝角(>0). 4. 公式:. 1 double Dot(point A,point B)//点乘 2 { 3 return A.x*B.x+A.y*B.y; 4 } 5 6 double Length(point A)//模 7 { 8 retu

计算几何及其应用——计算几何基础

写在前面:当时开计算几何这个专题神奇的从解析几何开始了,然后最近发现<计算几何及应用(金博)>这本书前面那章忽略掉了一些重要的东西比如说点定位.半平面相交之类的东西,恰好还有一些和计算几何扯上边但是不需要算法的简单题目没有整理,故在此开辟一块小空间. 我们再来看一道有关几何的问题.(Problem source:hdu2073)    数理分析:虽然这道题异常的简单,基本算不上计算几何这个专题当中的题目,但是把它拿到这里来,是源于这道简单几何题的思路其实体现了计算几何整个体系中比较重要的思维.

计算几何基础

记录点滴. 1 /* 2 2015.6 HT 3 ACM Work_8 4 5 */ 6 7 #include <iostream> 8 #include <cstdio> 9 using namespace std; 10 11 /* 12 线段判交--ACM 13 14 1.快速排斥实验 15 设以线段P1P2和线段Q1Q2为对角线的矩形为M,N;若M,N 不相交,则两个线段显然不相交: 16 2.跨立实验 17 如果两线段相交,则两线段必然相互跨立对方.若P1P2跨立Q1Q2

BZOJ_1610_[Usaco2008_Feb]_Line连线游戏_(计算几何基础+暴力)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1610 给出n个点,问两两确定的直线中,斜率不同的共有多少条. 分析 暴力枚举直线,算出来斜率放在k数组里面(斜率不存在记为INF),然后去个重统计个数就行了. 其实特水... 1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int maxn=200+5; 5 const double eps=1e-8,INF=0x7f

UVA 10652 Board Wrapping(计算几何基础,求凸包)

题目链接:传送门 分析: 没有什么好说的就是求一个凸包就好了.可以当作模板. 代码如下: #include <iostream> #include <cstring> #include <cstdio> #include <cmath> #include <algorithm> using namespace std; const double eps = 1e-10; //判断符号,提高精度 int dcmp(double x){ if(fab

【习题整理】计算几何基础

bzoj1074[Scoi2007]折纸 思路:考虑倒着做,每次将在折叠的直线右边的扔掉,左边的点再对称一次加入: 算几知识:求向量关于法向量的对称向量 点$A$关于点$B$对称的点$C = 2B - A$ 如果要求$\vec{A}$关于法向量$\vec{l}$的对称向量$\vec{A'}$: 可以考虑都平移到原点 利用点积求出$\vec{A}$在$\vec{l}$上的投影点$D$, 再将点$A$关于$D$对称到$A'$: $A'$的坐标就是向量$\vec{A'}$ 1 #include<bit