首页 > 其他分享 >计算几何全家桶

计算几何全家桶

时间:2023-02-04 13:00:09浏览次数:36  
标签:AB return Point int 全家 db 计算 几何 Cro

还需要不断增加,目前只有一点

#include<bits/stdc++.h>
/*一:【准备工作】*/
#define db double
#define ll long long
#define Vector Point
using namespace std;
const int N=1e6+3;
const db eps=1e-8,Pi=acos(-1.0);
inline int dcmp(db a){return a<-eps?-1:(a>eps?1:0);}//处理精度
inline db Abs(db a){return a*dcmp(a);}//取绝对值
struct Point
{
    db x,y;Point(db X=0,db Y=0){x=X,y=Y;}
    void in(){cin>>x>>y;}
    void out(){cout<<fixed<<setprecision(10)<<x<<" "<<y<<endl;}
};
/*二:【向量】*/
db Dot(Vector a,Vector b){return a.x*b.x+a.y*b.y;}//【点积】
db Cro(Vector a,Vector b){return a.x*b.y-a.y*b.x;}//【叉积】
db Len(Vector a){return sqrt(Dot(a,a));}//【模长】
db Angle(Vector a,Vector b){return acos(Dot(a,b)/Len(a)/Len(b));}//【两向量夹角】
Vector Normal(Vector a){return Vector(-a.y,a.x);}//【法向量】
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,db b){return Vector(a.x*b,a.y*b);}
bool operator==(Point a,Point b){return !dcmp(a.x-b.x)&&!dcmp(a.y-b.y);}//两点坐标重合则相等

/*三:【点、向量的位置变换】*/

/*1.【点、向量的旋转】*/
Point turn_P(Point a,db theta){//【点A\向量A顺时针旋转theta(弧度)】
    db x=a.x*cos(theta)+a.y*sin(theta);
    db y=-a.x*sin(theta)+a.y*cos(theta);
    return Point(x,y);
}
Point turn_PP(Point a,Point b,db theta){//【将点A绕点B顺时针旋转theta(弧度)】
    db x=(a.x-b.x)*cos(theta)+(a.y-b.y)*sin(theta)+b.x;
    db y=-(a.x-b.x)*sin(theta)+(a.y-b.y)*cos(theta)+b.y;
    return Point(x,y);
}

/*四:【图形与图形之间的关系】*/

/*1.【点与线段】*/
int OnSeg(Point p,Point a,Point b){//【判断点P是否在线段AB上】
    return !dcmp(Cro(p-a,b-a))&&dcmp(Dot(p-a,p-b))<=0;//做法一
//  return !dcmp(Cro(p-a,b-a))&&dcmp(min(a.x,b.x)-p.x)<=0&&dcmp(p.x-max(a.x,b.x))<=0&&dcmp(min(a.y,b.y)-p.y)<=0&&dcmp(p.y-max(a.y,b.y))<=0;//做法二
    //PA,AB共线且P在AB之间(其实也可以用len(p-a)+len(p-b)==len(a-b)判断,但是精度损失较大)
}
db dis_PL(Point p,Point a,Point b){//【点P到线段AB距离】
    if(a==b)return Len(p-a);//AB重合
    Vector x=p-a,y=p-b,z=b-a;
    if(dcmp(Dot(x,z))<0)return Len(x);//P距离A更近
    if(dcmp(Dot(y,z))>0)return Len(y);//P距离B更近
    return Abs(Cro(x,z)/Len(z));//面积除以底边长
}

/*2.【点与直线】*/
int OnLine(Point p,Point a,Point b){//【判断点P是否在直线AB上】
    return !dcmp(Cro(p-a,b-a));//PA,AB共线
}
db dis_PL_(Point p,Point a,Point b){//【点P到直线AB距离】
    if(a==b)return Len(p-a);//AB重合
    Vector x=p-a,y=p-b,z=b-a;
    return Abs(Cro(x,z)/Len(z));//面积除以底边长
}
Point FootPoint(Point p,Point a,Point b){//【点P到直线AB的垂足】
    Vector x=p-a,y=p-b,z=b-a;
    db len1=Dot(x,z)/Len(z),len2=-1.0*Dot(y,z)/Len(z);//分别计算AP,BP在AB,BA上的投影
    return a+z*(len1/(len1+len2));//点A加上向量AF
}
Point Symmetry_PL(Point p,Point a,Point b){//【点P关于直线AB的对称点】
    return p+(FootPoint(p,a,b)-p)*2;//将PF延长一倍即可
}

/*3.【线与线】*/
Point cross_ll(Point a,Point b,Point c,Point d){//【两直线AB,CD的交点】
    Vector x=b-a,y=d-c,z=a-c;
    return a+x*(Cro(y,z)/Cro(x,y));//点A加上向量AF
}
int pan_cross_L_L(Point a,Point b,Point c,Point d){//【判断直线AB与线段CD是否相交】
    return OnSeg(cross_ll(a,b,c,d),c,d);//直线AB与直线CD的交点在线段CD上
}
int pan_cross_ll(Point a,Point b,Point c,Point d){//【判断两线段AB,CD是否相交】
    db c1=Cro(b-a,c-a),c2=Cro(b-a,d-a);
    db d1=Cro(d-c,a-c),d2=Cro(d-c,b-c);
    return dcmp(c1)*dcmp(c2)<0&&dcmp(d1)*dcmp(d2)<0;//分别在两侧
}
int Gongxian(Point a,Point b,Point c,Point d){//【判断直线AB与直线CD是否相交】还要分平行和重合 
    return !dcmp(Cro(b-a,d-c)); 
}
int Chuizhi(Point a,Point b,Point c,Point d){//【判断直线AB与直线CD是否垂直】
    return !dcmp(Dot(b-a,d-c)); 
}

/*4.【点与多边形】*/
int PIP(Point *P,int n,Point a){//【射线法】判断点A是否在任意多边形Poly以内
    int cnt=0;db tmp;
    for(int i=1;i<=n;++i){
        int j=i<n?i+1:1;
        if(OnSeg(a,P[i],P[j]))return 2;//点在多边形上
        if(a.y>=min(P[i].y,P[j].y)&&a.y<max(P[i].y,P[j].y))//纵坐标在该线段两端点之间
            tmp=P[i].x+(a.y-P[i].y)/(P[j].y-P[i].y)*(P[j].x-P[i].x),cnt+=dcmp(tmp-a.x)>0;//交点在A右方
    }
    return cnt&1;//穿过奇数次则在多边形以内
}
int judge(Point a,Point L,Point R){//判断AL是否在AR右边
    return dcmp(Cro(L-a,R-a))>0;//必须严格以内
}
int PIP_(Point *P,int n,Point a){//【二分法】判断点A是否在凸多边形Poly以内
    //点按逆时针给出
    if(judge(P[1],a,P[2])||judge(P[1],P[n],a))return 0;//在P[1_2]或P[1_n]外
    if(OnSeg(a,P[1],P[2])||OnSeg(a,P[1],P[n]))return 2;//在P[1_2]或P[1_n]上
    int l=2,r=n-1;
    while(l<r){//二分找到一个位置pos使得P[1]_A在P[1_pos],P[1_(pos+1)]之间
        int mid=l+r+1>>1;
        if(judge(P[1],P[mid],a))l=mid;
        else r=mid-1;
    }
    if(judge(P[l],a,P[l+1]))return 0;//在P[pos_(pos+1)]外
    if(OnSeg(a,P[l],P[l+1]))return 2;//在P[pos_(pos+1)]上
    return 1;
}
int main()
{
    int T;cin>>T;
    while(T--)
    {
        Point A,B,C,D;A.in();B.in();C.in();D.in();
        if(Gongxian(A,B,C,D))cout<<2<<endl;
        else if(Chuizhi(A,B,C,D))cout<<1<<endl;
        else cout<<0<<endl;
    }
    return 0;
}
View Code

 

标签:AB,return,Point,int,全家,db,计算,几何,Cro
From: https://www.cnblogs.com/Hanghang007/p/17091290.html

相关文章

  • B站计算机导论课学习心得
    这个作业属于哪个课程https://edu.cnblogs.com/campus/fzzcxy/2023learning这个作业要求在哪里https://edu.cnblogs.com/campus/fzzcxy/2023learning/homework/1......
  • 【计算机网络】Stanford CS144 Lab 2: the TCP receiver 学习记录
    这次实验的目标为实现一个TCP协议的接收器。SequenceNumbersSequenceNumbersAbsoluteSequenceNumbersStreamIndicesStartattheISNStartat0Start......
  • 一.计算机基础
    一.计算机基础1.什么是计算机computer:全称电子计算机,俗称电脑,能够按照程序运行、自动、高速处理海量数据的现代化智能电子设备.常见的形式有台式计算机、笔记本计算机、......
  • OpenMMLab AI实战营 第二课笔记 计算机视觉之图像分类算法基础
    OpenMMLabAI实战营第二课笔记计算机视觉之图像分类算法基础1.什么是图像分类?1.1问题的数学表示1.2视觉任务的难点1.2.1超越规则:让机器从数据中学习1.2.2机......
  • 阿里oss视频流出流量计算
    阿里oss视频流出流量计算这个需求源于前几天老板问我:在阿里oss上,1080p高清视频,播放1分钟,存储和下载的价格分别是多少。因为之后要推广系统使用用户人数,所以就很关心流......
  • 官宣:计算中间件 Apache Linkis 正式毕业成为 Apache 顶级项目
    Apache软件基金会(ASF)孵化器于2022年12月03日,通过了ApacheLinkis计算中间件项目的孵化毕业投票。2023年01月18日,Apache软件基金会官方宣布ApacheLinkis顺利毕业,成为......
  • 计算机中负数的表示法
    在数学中我们使用+-来表示正数和负数。在计算机中数据都需要以二进制保存,那么负数如何在计算中用二进制存储呢?计算机中常用的是三种方法:原码、反码、补码。需要强调,......
  • 位运算符<<和>>计算方法详细说明
    左移和右移详细说明1、<<(左移)1.运算规则:按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。2.语法格式:需要移位的数字<<移位的次数例......
  • 计算机网络-hosts文件作用及如何修改hosts文件
    一、Host的简介一般情况下hosts文件都会在电脑的这个路径下: 如果找不到文件有可能是被系统隐藏,可以通过以下方法找到隐藏文件: 在电脑上网过程中,人们一般输入的都是网......
  • 矩阵分解的梯度计算
    https://homepages.inf.ed.ac.uk/imurray2/pub/16choldiff/choldiff.pdf......