1812: 三角形和矩形
Time Limit: 5 Sec Memory Limit: 128 MB Special JudgeSubmit: 316 Solved: 155
[ Submit][ Status][ Web Board]
Description
Bobo 有一个三角形和一个矩形,他想求他们交的面积。
具体地,三角形和矩形由 8 个整数 x
1,y
1,x
2,y
2,x
3,y
3,x
4,y
4 描述。 表示三角形的顶点坐标是 (x
1,y
1),(x
1,y
2),(x
2,y
1), 矩形的顶点坐标是 (x
3,y
3),(x
3,y
4),(x
4,y
4),(x
4,y
3).
Input
输入包含不超过 30000 组数据。
每组数据的第一行包含 4 个整数 x
1,y
1,x
2,y
2 (x
1≠x
2,y
1≠y
2).
第二行包含 4 个整数 x
3,y
3,x
4,y
4 (x
3<x
4,y
3<y
4).
(0≤x
i,y
i≤10
4)
Output
对于每组数据,输出一个实数表示交的面积。绝对误差或相对误差小于 10
-6 即认为正确。
Sample Input
1 1 3 3
0 0 2 2
0 3 3 1
0 0 2 2
4462 1420 2060 2969
4159 257 8787 2970
Sample Output
1.00000000
0.75000000
439744.13967527
HINT
Source
解题思路:求出三角形内包含的矩形的点矩形中包含的三角形的点以及三角形和矩形各个线段的交点这些点围成的多边形即为相交的面积
/* ***********************************************
Author : ryc
Created Time : 2016-09-06 Tuesday
File Name : E:\acm\csuoj\1812.cpp
Language : c++
Copyright 2016 ryc All Rights Reserved
************************************************ */
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#define eps 1e-8
using namespace std;
struct point{
double x,y;
}S[5],J[5],I[110];
struct Node{
point a,b;
}A[5];
int sig(double n){
if(fabs(n)<eps)return 0;
else if(n>eps)return 1;
else return -1;
}
bool judge(int a,int b){//判断线段相交
if(min(A[a].a.x,A[a].b.x)>max(A[b].a.x,A[b].b.x)||min(A[a].a.y,A[a].b.y)>max(A[b].a.y,A[b].b.y)||min(A[b].a.x,A[b].b.x)>max(A[a].a.x,A[a].b.x)||min(A[b].a.y,A[b].b.y)>max(A[a].a.y,A[a].b.y))
return false;
double h,i,j,k;
h=(A[a].b.x-A[a].a.x)*(A[b].a.y-A[a].a.y)-(A[a].b.y-A[a].a.y)*(A[b].a.x-A[a].a.x);
i=(A[a].b.x-A[a].a.x)*(A[b].b.y-A[a].a.y)-(A[a].b.y-A[a].a.y)*(A[b].b.x-A[a].a.x);
j=(A[b].b.x-A[b].a.x)*(A[a].a.y-A[b].a.y)-(A[b].b.y-A[b].a.y)*(A[a].a.x-A[b].a.x);
k=(A[b].b.x-A[b].a.x)*(A[a].b.y-A[b].a.y)-(A[b].b.y-A[b].a.y)*(A[a].b.x-A[b].a.x);
return h*i<=eps&&j*k<=eps;
}
void getinter(point p1,point p2,point p3,point p4,point &inter){//求交点
inter=p1;
double ans=((p1.x-p3.x)*(p3.y-p4.y)-(p1.y-p3.y)*(p3.x-p4.x))/((p1.x-p2.x)*(p3.y-p4.y)-(p1.y-p2.y)*(p3.x-p4.x));
inter.x+=(p2.x-p1.x)*ans;
inter.y+=(p2.y-p1.y)*ans;
}
double dist(point p1,point p2){
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
double cp(point p1,point p2,point p3){
return (p3.x-p1.x)*(p2.y-p1.y)-(p3.y-p1.y)*(p2.x-p1.x);
}
bool cmp(point a,point b){
double ans=cp(I[0],a,b);
if(sig(ans)==0){
return dist(I[0],a)-dist(I[0],b)<=0;
}
else return ans>0;
}
int main()
{
double x1,y1,x2,y2,x3,y3,x4,y4;
while(scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&x1,&y1,&x2,&y2,&x3,&y3,&x4,&y4)!=EOF){
S[0].x=x1;S[0].y=y1;S[1].x=x1;S[1].y=y2;S[2].x=x2;S[2].y=y1;
J[0].x=x3;J[0].y=y3;J[1].x=x3;J[1].y=y4;J[2].x=x4;J[2].y=y4;J[3].x=x4;J[3].y=y3;
int cnt=0;
for(int i=0;i<3;++i){//矩形中包含的三角形的点
if(S[i].x>=min(x3,x4)&&S[i].x<=max(x3,x4)&&S[i].y>=min(y3,y4)&&S[i].y<=max(y3,y4)){
I[cnt].x=S[i].x;I[cnt].y=S[i].y;cnt++;
}
}
for(int i=0;i<4;++i){//三角形中包含的矩形中的点
if(J[i].x>=min(x1,x2)&&J[i].x<=max(x1,x2)&&J[i].y>=min(y1,y2)&&J[i].y<=max(y1,y2)){
double k=(y1-y2)/(x2-x1);double b=y1-k*x2;
if((sig(k*x1-y1+b)>=0&&sig(J[i].x*k-J[i].y+b)>=0)||(sig(k*x1-y1+b)<=0&&sig(J[i].x*k-J[i].y+b)<=0)){
I[cnt].x=J[i].x;I[cnt].y=J[i].y;cnt++;
}
}
}
for(int i=0;i<3;++i){
for(int j=0;j<4;++j){//求出三角形和矩形的线段的交点
A[0].a=S[i];A[0].b=S[(i+1)%3];A[1].a=J[j];A[1].b=J[(j+1)%4];
//printf("%lf %lf %lf %lf\n",J[j].x,J[j].y,J[(j+1)%4].x,J[(j+1)%4].y);
if(judge(0,1)){
if(A[0].a.x==A[0].b.x&&A[0].a.x==A[1].a.x&&A[1].a.x==A[1].b.x)continue;
if(A[0].a.y==A[0].b.y&&A[0].a.y==A[1].a.y&&A[1].a.y==A[1].b.y)continue;
//printf("%lf %lf %lf %lf %lf %lf %lf %lf\n",A[0].a.x,A[0].a.y,A[0].b.x,A[0].b.y,A[1].a.x,A[1].a.y,A[1].b.x,A[1].b.y);
getinter(A[0].a,A[0].b,A[1].a,A[1].b,I[cnt]);cnt++;
// printf("%lf %lf\n",I[cnt-1].x,I[cnt-1].y);
}
}
}
// printf("%d\n",cnt);
if(cnt<2){
printf("0.00000000\n");
}
else {
int pos=0;
for(int i=0;i<cnt;++i){
if(I[pos].y>=I[i].y){
if(I[pos].y==I[i].y){
if(I[pos].x>I[i].x)pos=i;
}
else pos=i;
}
}
point temp=I[pos];I[pos]=I[0];I[0]=temp;
sort(I+1,I+cnt,cmp);//极角排序
double ans=0;
for(int i=0;i<cnt;++i){//求多边形面积
double area=(I[(i+1)%cnt].x*I[i].y-I[(i+1)%cnt].y*I[i].x)/2.0;
ans+=area;
}
printf("%.9lf\n",fabs(ans));
}
}
return 0;
}