计算几何 点积 叉积 凸包

向量
简单的说,向量(vector)就是一个有方向有大小的量,如速度,位移等物理量都是向量。在几何上,一个起点为A,终点为B的向量a可以用一跳有向线段向量AB来表示,也可以理解为点B与点A的差值(B-A)

点积
概念
两个向量v和w的点积等于两者长度的乘积乘上它们夹角的余弦,因此当夹角小于90°时点积为正,夹角等于90°时点积为0,大于90°时点积为负。
其中根据几何知识也可得到点积的结果等于x1x2+y1y2
代码
double operator (const Vector & v, const Vector & w)
{
return v.x
w.x+v.y*w.y;
}

#include
using namespace std;
struct Point{
    double x,y;
};
typedef Point Vector;
Vector operator -(Vector v,Vector w)
{
    return {v.x-w.x,v.y-w.y};
}
double operator *(Vector v,Vector w)
{
    return v.x*w.x+v.y*w.y;
}
Vector operator *(double k,Vector v)
{
    return {k*v.x,k*v.y};
}
Vector operator +(Vector v,Vector w)
{
    return {v.x+w.x,v.y+ w.y};
}
Point calc(Point A,Point B,Point P)
{
    Vector v=B-A,w=P-A;
    double t=(v*w)/(v*v);
    return A+(t*v);
}
int main()
{
    double a,b,c,d;
    cin>>a>>b>>c>>d;
    int T;
    cin>>T;
    while(T--)
    {
        double e,f;
        cin>>e>>f;
        Point res = calc({a,b},{c,d},{e,f});
        cout<

叉积
几何意义:向量v和w叉积的绝对值是他们所围成三角形的两倍v^w=|v||w|sin0
当向量满足右手定则的时候叉积为正(w在v的逆时针方向)否则为负,(w在v的顺时针方向)通过v和w的叉积,我们可以判断两向量的相对位置
代码实现
double operator ^ (const Vector & v, const Vector & w)
{
return v.x
w.y_v.y
w.x;
}
给定两条直线判断两直线的关系,平行,正交或者其他

平行:两直线的叉积等于0
正交:两直线的点积等于0
其他

#include
using namespace std;
struct Point{
    double x,y;
};
double a,b,c,d,e,f,g,h;
typedef Point Vector;
double operator *(Vector v,Vector w)
{
    return v.x*w.x+v.y*w.y;
}
double operator ^(Vector v,Vector w)
{
    return v.x*w.y-v.y*w.x;
}
int judge()
{
    Vector v ={c-a,d-b},w={g-e,h-f};
    if((v^w)==0)return 2;
    if((v*w)==0)return 1;
    return 0;
}

int main()
{
    int T;
    cin>>T;
    while(T--)
    {

        cin>>a>>b>>c >>d>>e>>f>>g>>h;
        cout<

凸包
凸包就是把给定点包围在内部的,面积最小的凸多边形
凸多边形,其每一个内角均不大于180°
如何构建凸包?
1.暴力枚举O(n^3)
2.graham扫描法

暴力枚举
由于凸多边形的每个内角都不大于180度,由此可知对于凸包边界上相邻的任意两个点所构成的直线将会位于平面上所有点的一侧所以可以枚举出所有边界点,时间复杂度为O(n^3)
步骤
寻找点集中最下最左方的点
对所有点以斜率为关键字进行排序
模拟栈首先将最起始的两个点入栈
之后顺序查找栈顶两个点以及排序好的点构成的夹角小于180
是:将该点入栈
否:将栈顶的点弹出直到满足要求

你可能感兴趣的:(数据结构,算法)