lightoj1130【圆与多边形面积交】



C - Intersection between Circle and Rectangle
Time Limit:500MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu

Description

Given the co-ordinates of a circle and the lower left and upper right coordinate of an axis parallel rectangle, you have to find their common area. In the picture, the shaded area is their common area.

Input

Input starts with an integer T (≤ 4000), denoting the number of test cases.

Each case contains two lines, first line contains three integers x, y, r where (x, y) denotes the center of the circle and r denotes the radius. The next line contains four integers x1, y1, x2, y2 (x1<x2, y1<y2). All the integers are non-negative and not greater than 200.

Output

For each case, print the case number their common area. Errors less than 10-6 will be ignored.

Sample Input

3

1 1 10

2 2 5 5

1 1 10

20 20 30 30

1 1 5

0 1 8 8

Sample Output

Case 1: 9

Case 2: 0

Case 3: 24.6014178376

题意:如图所示给定圆和矩形相交的面积
圆与多边形公共面积模板题直接把模板给copy过来了
#include <cstdio>
#include<cstdlib>
#include<cstring>
#include <cmath>
using namespace std;

struct point
{
    double x,y;
}a[55];
double r;	

double dist_1point(double x0,double y0)	
{
    return sqrt(x0*x0+y0*y0);
}
double dist_2point(double x1,double y1,double x2,double y2)
{
    return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
double dist_line(double x1,double y1,double x2,double y2)
{
    double A,B,C,dist;
    A=y1-y2;
    B=x1-x2;
    C=x1*y2-x2*y1;
    dist=fabs(C)/sqrt(A*A+B*B);	
    return dist;
}
double get_cos(double a,double b,double c)  
{
	double angel=(b*b+c*c-a*a)/(2*b*c);
    return angel;
}
point get_point(double x0,double y0)
{
    double k;
    point temp;
    if(x0!=0)	
    {
        k=y0/x0;
        temp.x=fabs(r)/sqrt(1+k*k);	
		if(x0<0) temp.x=-temp.x;	
        temp.y=k*temp.x;
    }
    else		
    {
        temp.x=0;
		if(y0>0) temp.y=r;	
		else temp.y=-r;		
    }
    return temp;
}
int fi(double x1,double y1,double x2,double y2)	
{
    if (x1*y2-x2*y1>0) return 1;	
    else return -1;
}

double get_area(double x1,double y1,double x2,double y2) 
{
	int sign=fi(x1,y1,x2,y2);	
    double s;
    double l=dist_line(x1,y1,x2,y2);	   
    double a=dist_1point(x1,y1);	      
    double b=dist_1point(x2,y2);		  
    double c=dist_2point(x1,y1,x2,y2);     
	if(a==0 || b==0)
		return 0;	


    if(a<=r && b<=r)
    {
        s=fabs(x1*y2-x2*y1)/2.0;
        return s*sign;
    }

    
    else if(a>=r && b>=r && l>=r)
    {
        point t1=get_point(x1,y1);
        point t2=get_point(x2,y2);
        double d=dist_2point(t1.x,t1.y,t2.x,t2.y);
        double sita1=acos(get_cos(d,r,r));
        double s=fabs(sita1*r*r/2.0); 
        return s*sign;
    }

	
    else if(a>=r && b>=r && l<=r && (get_cos(a,b,c)<=0 || get_cos(b,a,c)<=0))
    {
        point t1=get_point(x1,y1);
        point t2=get_point(x2,y2);
        double d=dist_2point(t1.x,t1.y,t2.x,t2.y);
        double sita=acos(get_cos(d,r,r));
        s=fabs(sita*r*r/2.0);
        return s*sign;
    }

	
    else if(a>=r && b>=r && l<=r && (get_cos(a,b,c)>0 && get_cos(b,a,c)>0))
    {
		double xx1,xx2,yy1,yy2;	
		if(x1!=x2)
		{
			double k12=(y1-y2)/(x1-x2);
			double b12=y1-k12*x1;
			double a0=(1+k12*k12);
			double b0=(2*k12*b12);
			double c0=(b12*b12-r*r);
			xx1=(-b0+sqrt(b0*b0-4*a0*c0))/(2*a0);
			yy1=k12*xx1+b12;
			xx2=(-b0-sqrt(b0*b0-4*a0*c0))/(2*a0);
			yy2=k12*xx2+b12;
		}
		else	
		{
			xx1=x1;
			xx2=x1;
			yy1=sqrt(r*r-x1*x1);
			yy2=-sqrt(r*r-x1*x1);
		}
		point t1=get_point(x1,y1);		
		point t2=get_point(x2,y2);		
		double d1=dist_2point(xx1,yy1,xx2,yy2);	
		double d2=dist_2point(t1.x,t1.y,t2.x,t2.y);	
		double sita1=acos(get_cos(d1,r,r)); 
		double sita2=acos(get_cos(d2,r,r));	 
		double s1=fabs(sita1*r*r/2.0);  
		double s2=fabs(sita2*r*r/2.0);   
		double s3=fabs(xx1*yy2-xx2*yy1)/2.0;  
        s=s2+s3-s1;		
        return s*sign;
    }

	
    else if(a>=r && b<=r)
    {
		double xxx,yyy;
		if(x1!=x2)
        {
			double k12=(y1-y2)/(x1-x2);
			double b12=y1-k12*x1;
			double a0=(1+k12*k12);
			double b0=(2*k12*b12);
			double c0=(b12*b12-r*r);
			
			double xx1=(-b0+sqrt(b0*b0-4*a0*c0))/(2*a0);
			double yy1=k12*xx1+b12;
			double xx2=(-b0-sqrt(b0*b0-4*a0*c0))/(2*a0);
			double yy2=k12*xx2+b12;
			
			if(x1<=xx1 && xx1<=x2 || x2<=xx1 && xx1<=x1) {xxx=xx1; yyy=yy1;}
			else {xxx=xx2; yyy=yy2;}
		}
		else
		{
			double xx1=x1;
			double yy1=-sqrt(r*r-x1*x1);
			double yy2=sqrt(r*r-x1*x1);
		
			if(y1<=yy1 && yy1<=y2 || y2<=yy1 && yy1<=y1) {yyy=yy1; xxx=xx1;}
			else {yyy=yy2; xxx=xx1;}
		}
        point t1=get_point(x1,y1);
        double ddd=dist_2point(t1.x,t1.y,xxx,yyy);
        double sita1=acos(get_cos(ddd,r,r));
        double s1=fabs(sita1*r*r/2.0);
        double s3=fabs(xxx*y2-yyy*x2)/2.0;
        s=s1+s3;
        return s*sign;
    }
    else if(a<=r && b>=r)
    {
		double xxx,yyy;
		if(x1-x2!=0)
		{
			double k12=(y1-y2)/(x1-x2);
			double b12=y1-k12*x1;
			double a0=(1+k12*k12);
			double b0=(2*k12*b12);
			double c0=(b12*b12-r*r);
			double xx1=(-b0+sqrt(b0*b0-4*a0*c0))/(2*a0);
			double yy1=k12*xx1+b12;
			double xx2=(-b0-sqrt(b0*b0-4*a0*c0))/(2*a0);
			double yy2=k12*xx2+b12;
			if(x1<=xx1 && xx1<=x2 || x2<=xx1 && xx1<=x1) {xxx=xx1; yyy=yy1;}
			else {xxx=xx2; yyy=yy2;}
		}
		else
		{
			double yy1=-sqrt(r*r-x1*x1);
			double yy2=sqrt(r*r-x1*x1);
			double xx1=x1;
			if(y1<=yy1 && yy1<=y2 || y2<=yy1 && yy1<=y1) {yyy=yy1; xxx=xx1;}
			else {yyy=yy2; xxx=xx1;}
		}
        point t1=get_point(x2,y2);
        double ddd=dist_2point(t1.x,t1.y,xxx,yyy);
        double sita1=acos(get_cos(ddd,r,r));
        double s1=fabs(sita1*r*r/2.0);
        double s3=fabs(xxx*y1-yyy*x1)/2.0;
        s=s1+s3;
        return s*sign;
    }
	else return 0;
}

int main()
{
    int i,n,t,k=1;
	double area;
	scanf("%d",&t);
    while(t--)
    {
    	double xx,yy;
    	scanf("%lf%lf%lf",&xx,&yy,&r);
    	double x1,x2,y1,y2;
    	scanf("%lf%lf%lf%lf",&x1,&y1,&x2,&y2);
    	x1-=xx;x2-=xx;y1-=yy;y2-=yy;
    	a[0].x=x1;a[0].y=y1;
    	a[1].x=x2;a[1].y=y1;
    	a[2].x=x2;a[2].y=y2;
    	a[3].x=x1;a[3].y=y2;
        a[4]=a[0]; area=0;
        for(i=0;i<4;i++)
        {
            area+=get_area(a[i].x,a[i].y,a[i+1].x,a[i+1].y);
        }
        printf("Case %d: %.7lf\n",k++,fabs(area));
    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值