[模板] 计算几何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;
}
原文地址:https://www.cnblogs.com/ubospica/p/10121673.html