• 萌萌哒的计算几何


    对,我今天又没吃药。

    poj2826

    喜闻乐见的计算几何题,WA几十发就是爽!

    思路很简单,然后程序写的我就萌萌哒了

    1. 两条线段没有交点,或者互相平行,或者至少有一条平行于x轴的线段,则答案为0.00
    2. 如果有一条线段覆盖了另一条,则答案为0.00
    3. 否则答案就是交点和交点上方最低的点和过这个点做的平行与x轴的线围成的三角形的距离

    对,思路非常简单,谁也不会想错
    就是写不对!

    我已弃疗

    附AC代码:

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    #include <cmath>
    
    #define INF (999999.9)
    
    using namespace std;
    
    const double eps = 1e-8;
    const double pi = acos(-1.0);
    
    inline bool isint(double x){return fabs((x-int(x+0.5))) < eps;}
    inline int cmp(double x){
    	if (fabs(x)<eps)	return 0;
    	if (x>0)	return 1;
    	return -1;
    }
    
    struct point{
    	double x,y;
    	point(double x=0,double y=0):x(x),y(y) {}
    	friend point operator + (const point &a,const point &b){return point(a.x+b.x,a.y+b.y);}
    	friend point operator - (const point &a,const point &b){return point(a.x-b.x,a.y-b.y);}
    	friend bool operator == (const point &a,const point &b){return cmp(a.x-b.x)==0 && cmp(a.y-b.y)==0;}
    	friend bool operator != (const point &a,const point &b){return cmp(a.x-b.x)!=0 || cmp(a.y-b.y)!=0;}
    	friend point operator * (const point &a,const double &b){return point(a.x*b,a.y*b);}
    	friend point operator * (const double &a,const point &b){return point(a*b.x,a*b.y);}
    	friend point operator / (const point &a,const double &b){return point(a.x/b,a.y/b);}
    	friend double operator * (const point &a ,const point &b) { return a.x*b.y-b.x*a.y; }
    	
    	inline double len() const {return sqrt(x*x+y*y);}
    	inline point rotate(double rad) const {return point(x*cos(rad)-y*sin(rad),x*sin(rad)+y*cos(rad));}
    	#ifdef DEBUG
    	void print(string debug="debug"){cout<<debug<<" "<<x<<" "<<y<<endl;}
    	#endif
    
    };
    typedef point vec;
    inline double dot(const point &a,const point &b){return a.x*b.x+a.y*b.y;}
    inline double dis(const point &a,const point &b){return (a-b).len();}
    inline double angle(const point &a,const point &b){return acos(dot(a,b)/a.len()/b.len());}
    inline double area(point a,point b,point c){return (b-a)*(c-a)/2.0;}
    
    
    
    point CircumCenter(point a,point b,point c){//三角形外心
    	vec A=b-a , B=c-a;
    	double c1=A.len()*A.len()/2.0 , c2=B.len()*B.len()/2.0;
    	return point(a.x+(c1*B.y-c2*A.y)/(A*B),a.y+(A.x*c2-B.x*c1)/(A*B));
    }
    
    //点与直线相关
    //L 是直线的方向向量
    inline double dis_P2L(const point p,const vec L){return p*L/L.len();}
    point projection(const point p,const vec L){return L*(dot(L,p)/dot(L,L));}//投影点
    point getIntersection(point p,vec v,point q,vec w){//v,w是方向向量,p,q是直线上任意两点
    	vec u=p-q;
    	double t=(w*u)/(v*w);
    	return p+v*t;
    }
    bool parallel(point a,point b,point c,point d){//平行
    	return !(cmp((a-b)*(c-d)));
    }
    
    
    
    
    //点与线段相关
    bool onSegment(point p,point a1,point a2){
    	return cmp((a1-p)*(a2-p))==0 && cmp(dot(a1-p,a2-p))<0;
    }
    bool seg_intersection(point a1,point a2,point b1,point b2){
    	if (onSegment(a1,b1,b2) || onSegment(a2,b1,b2) ||onSegment(b1,a1,a2)||onSegment(b2,a1,a2))	return true;//端点在另一条线段上
    	if (a1==b1 || a1==b2 || a2==b1 || a2==b2)	return true;//端点相同
    	double c1=(a2-a1)*(b1-a1),c2=(a2-a1)*(b2-a1),c3=(b2-b1)*(a1-b1),c4=(b2-b1)*(a2-b1);
    	return cmp(c1)*cmp(c2)<0 && cmp(c3)*cmp(c4)<0;//规范相交
    }
    
    
    bool under(point p,point a,point b){
    	if (b.x<a.x)	swap(a,b);
    	if (onSegment(p,a,b))	return true;
    	if (!seg_intersection(a,b,p,point(p.x,20000.0)))	return false;
    	if (cmp(getIntersection(p,point(0,1),a,a-b).y-p.y)>0)	return true;
    	return false;
    }
    int main (int argc, char *argv[])
    {	
    	int n;
    	scanf("%d",&n);
    	while (n--){
    		double ans;
    		double x1,y1,x2,y2,x3,y3,x4,y4;
    		cin>>x1>>y1>>x2>>y2>>x3>>y3>>x4>>y4;
    		point a,b,c,d;
    		a=point(x1,y1);
    		b=point(x2,y2);
    		c=point(x3,y3);
    		d=point(x4,y4);
    		
    		if (!seg_intersection(a,b,c,d)){
    			printf("0.00
    ");
    			continue;
    		}
    		if (a.y==b.y || c.y==d.y){//cout<<"w"<<endl;
    			printf("0.00
    ");
    			continue;
    		}	
    		if (parallel(a,b,c,d)){//cout<<"w"<<endl;
    			printf("0.00
    ");
    			continue;
    		}	
    		
    		
    		point ins=getIntersection(a,a-b,c,c-d);
    		
    		//ins.print("ins");
    		
    		point p;
    		double ymin=900000;
    		double s=0.0;
    		int cnt=0;
    		
    		
    		
    		if (a.y>ins.y&&a.y<ymin&&!under(a,c,d)&&seg_intersection(point(-100001,a.y),point(10001,a.y),c,d))	ymin=a.y , p=getIntersection(a,vec(1,0),c,c-d) , s=area(a,p,ins);
    		if (b.y>ins.y&&b.y<ymin&&!under(b,c,d)&&seg_intersection(point(-100001,b.y),point(10001,b.y),c,d))	ymin=b.y , p=getIntersection(b,vec(1,0),c,c-d) , s=area(b,p,ins);
    		if (c.y>ins.y&&c.y<ymin&&!under(c,a,b)&&seg_intersection(point(-100001,c.y),point(10001,c.y),a,b))	ymin=c.y , p=getIntersection(c,vec(1,0),a,a-b) , s=area(c,p,ins);
    		if (d.y>ins.y&&d.y<ymin&&!under(d,a,b)&&seg_intersection(point(-100001,d.y),point(10001,d.y),a,b))	ymin=d.y , p=getIntersection(d,vec(1,0),a,a-b) , s=area(d,p,ins);
    		
    		
    		printf("%.2lf
    ",fabs(s));
    
    	}
    	return 0;
    }
    
  • 相关阅读:
    《30天自制操作系统》17_day_学习笔记
    《30天自制操作系统》18_day_学习笔记
    湖大OJ-实验E----可判定的DFA的空问题
    湖大OJ-实验C----NFA转换为DFA
    《30天自制操作系统》16_day_学习笔记
    《30天自制操作系统》19_day_学习笔记
    《30天自制操作系统》15_day_学习笔记
    《30天自制操作系统》14_day_学习笔记
    [Leetcode Week11]Kth Largest Element in an Array
    [Leetcode Week10]Minimum Time Difference
  • 原文地址:https://www.cnblogs.com/loveidea/p/3945685.html
Copyright © 2020-2023  润新知