zoukankan      html  css  js  c++  java
  • [模板] 计算几何1(基础): 点/向量/线/圆/多边形/其他运算

    类型定义

    
    typedef double db;
    
    const db eps=1e-8,pi=acos(-1);
    il int dcmp(db a){return fabs(a)<=eps?0:a>0;}
    il db p2(db v){return v*v;}
    il db gougu1(db a,db b){return sqrt(p2(a)+p2(b));}
    il db gougu2(db a,db b){return sqrt(p2(a)-p2(b));}
    il db rand01(){return rand()/(db)RAND_MAX;}
    
    //p:point l:line s:segment
    struct tvec{db x,y;};
    struct tline{tvec p,v;};
    struct tseg{tvec x,y;};
    struct tcir{tvec o;db r};
    
    ostream& operator<<(ostream &os,tvec a){os<<"("<<a.x<<", "<<a.y<<")";return os;}
    ostream& operator<<(ostream &os,tline a){os<<"<"<<a.p<<", "<<a.v<<">";return os;}
    ostream& operator<<(ostream &os,tseg a){os<<"<"<<a.x<<", "<<a.y<<">";return os;}
    ostream& operator<<(ostream &os,tcir a){os<<"<"<<a.o<<", r="<<a.r<<">";return os;}
    
    void shake(tvec &a){a.x+=(rand01()-0.5)*eps*10;a.y+=(rand01()-0.5)*eps*10;}//??
    il tvec operator+(tvec a,tvec b){return (tvec){a.x+b.x,a.y+b.y};}
    il tvec operator-(tvec a,tvec b){return (tvec){a.x-b.x,a.y-b.y};}
    il tvec operator*(tvec a,db b){return (tvec){a.x*b,a.y*b};}
    il tvec operator*(db a,tvec b){return b*a;}
    il db operator*(tvec a,tvec b){return a.x*b.y-b.x*a.y;}
    il db operator^(tvec a,tvec b){return a.x*b.x+a.y*b.y;}
    il tvec norm(tvec a){return (tvec){-a.y,a.x};}
    il tvec rotate(tvec a,db alp){db s=sin(alp),c=cos(alp);return (tvec){c*a.x-s*a.y,s*a.x+c*a.y};}
    il tvec rotate(tvec a,db s,db c){return (tvec){c*a.x-s*a.y,s*a.x+c*a.y};}
    il db len(tvec a){return gougu1(a.x,a.y);}
    il db ang(tvec a){return atan2(a.y,a.x);}
    il db ang(tvec a,tvec b){return (a^b)/(len(a)*len(b));}//cos<a,b>
    il bool para(tvec a,tvec b){return dcmp(a*b)==0;}
    il bool perp(tvec a,tvec b){return dcmp(a^b)==0;}
    

    算法

    向量, 直线, 线段

    点到直线距离, 对称点, 点在线段上

    il db dist(tvec b,tline a){return (a.v*(b-a.p))/len(a.v);}
    il tvec symm(tvec a,tline b){return a-norm(b.v)*(dist(a,b)*2/len(b.v));}
    il bool onseg(tseg a,tvec b){return dcmp((a.x-b)^(b.x-b))==0&&dcmp((a.x-b)*(b.x-b))<0;}
    

    判断线段相交

    il bool isinters_ss(tseg a,tseg b){ //strict
    	return dcmp(((a.y-b.x)*(b.y-b.x))*((a.x-b.x)*(b.y-b.x)))<0
    		&& dcmp(((b.x-a.x)*(a.y-a.x))*((b.y-a.x)*(a.y-a.x)))<0;
    }
    

    直线交点

    il tvec inters(tline a,tline b){db v=(b.v*(a.p-b.p))/(a.v*b.v);return a.p+a.v*v;}
    

    多边形

    面积

    db getarea(){
    	if(ppo==0)return 0;
    	db res=poly[ppo]*poly[1];
    	rep(i,1,ppo-1)
    		res+=poly[i]*poly[i+1];
    	return res/2.0;
    }
    

    还没写完...

    所有的代码

    
    typedef double db;
    
    const db eps=1e-8,pi=acos(-1);
    il int dcmp(db a){return fabs(a)<=eps?0:a>0;}
    il db p2(db v){return v*v;}
    il db gougu1(db a,db b){return sqrt(p2(a)+p2(b));}
    il db gougu2(db a,db b){return sqrt(p2(a)-p2(b));}
    il db rand01(){return rand()/(db)RAND_MAX;}
    
    //p:point l:line s:segment
    struct tvec{db x,y;};
    struct tline{tvec p,v;};
    struct tseg{tvec x,y;};
    struct tcir{tvec o;db r};
    
    ostream& operator<<(ostream &os,tvec a){os<<"("<<a.x<<", "<<a.y<<")";return os;}
    ostream& operator<<(ostream &os,tline a){os<<"<"<<a.p<<", "<<a.v<<">";return os;}
    ostream& operator<<(ostream &os,tseg a){os<<"<"<<a.x<<", "<<a.y<<">";return os;}
    ostream& operator<<(ostream &os,tcir a){os<<"<"<<a.o<<", r="<<a.r<<">";return os;}
    
    void shake(tvec &a){a.x+=(rand01()-0.5)*eps*10;a.y+=(rand01()-0.5)*eps*10;}//??
    il tvec operator+(tvec a,tvec b){return (tvec){a.x+b.x,a.y+b.y};}
    il tvec operator-(tvec a,tvec b){return (tvec){a.x-b.x,a.y-b.y};}
    il tvec operator*(tvec a,db b){return (tvec){a.x*b,a.y*b};}
    il tvec operator*(db a,tvec b){return b*a;}
    il db operator*(tvec a,tvec b){return a.x*b.y-b.x*a.y;}
    il db operator^(tvec a,tvec b){return a.x*b.x+a.y*b.y;}
    il tvec norm(tvec a){return (tvec){-a.y,a.x};}
    il tvec rotate(tvec a,db alp){db s=sin(alp),c=cos(alp);return (tvec){c*a.x-s*a.y,s*a.x+c*a.y};}
    il tvec rotate(tvec a,db s,db c){return (tvec){c*a.x-s*a.y,s*a.x+c*a.y};}
    il db len(tvec a){return gougu1(a.x,a.y);}
    il db ang(tvec a){return atan2(a.y,a.x);}
    il db ang(tvec a,tvec b){return (a^b)/(len(a)*len(b));}//cos<a,b>
    il bool para(tvec a,tvec b){return dcmp(a*b)==0;}
    il bool perp(tvec a,tvec b){return dcmp(a^b)==0;}
    
    
    il db dist(tvec b,tline a){return (a.v*(b-a.p))/len(a.v);}
    il tvec symm(tvec a,tline b){return a-norm(b.v)*(dist(a,b)*2/len(b.v));}
    il tvec inters(tline a,tline b){db v=(b.v*(a.p-b.p))/(a.v*b.v);return a.p+a.v*v;}
    il bool isinters_ss(tseg a,tseg b){ //strict
    	return dcmp(((a.y-b.x)*(b.y-b.x))*((a.x-b.x)*(b.y-b.x)))<0
    		&& dcmp(((b.x-a.x)*(a.y-a.x))*((b.y-a.x)*(a.y-a.x)))<0;
    }
    il bool onseg(tseg a,tvec b){return dcmp((a.x-b)^(b.x-b))==0&&dcmp((a.x-b)*(b.x-b))<0;}
    
    ////-1 same, 0 in, 1 out, 2 inscribe 3 cirsumscribe 4 intersect
    //il int inters(tcir a,tcir b,vector<tvec> *res){
    //	if(a.r<b.r)swap(a,b);
    //	db d=len(a.o-b.o),d1=a.r-b.r,d2=a.r+b.r;
    //	res->clear();
    //	if(dcmp(d)==0&&dcmp(d1)==0)return -1;
    //	if(dcmp(d-d1)<0)return 1;
    //	if(d>d2)return 0;
    //	if(d==d1||d==d2){
    //		res->push_back(a.o+(b.o-a.o)*(a.r/d));
    //		return (d==d1)?1:2;
    //	}
    //	
    //}
    
    void test(){
    	tline a{{1,1},{2,1}},c{{2,1},{-1,1}};
    	tvec b{3,4},d{4.6,0.8};
    //	cout<<dist(b,a)<<'
    '<<symm(d,a)<<'
    ';
    	cout<<inters(a,c)<<'
    ';
    }
    
    int main(){
    	ios::sync_with_stdio(0),cin.tie(0);
    	test();
    	return 0;
    }
    
  • 相关阅读:
    Kotlin Coroutines不复杂, 我来帮你理一理
    Refresh design pattern
    Android App安装包瘦身计划
    Google IO 2019 Android 太长不看版
    Effective Java读书笔记完结啦
    探究高级的Kotlin Coroutines知识
    移动应用中的非功能性(跨职能)需求
    Android程序员的Flutter学习笔记
    如何正确使用Espresso来测试你的Android程序
    MVP模式, 开源库mosby的使用及代码分析
  • 原文地址:https://www.cnblogs.com/ubospica/p/10121673.html
Copyright © 2011-2022 走看看