链接:戳这里
1812: 三角形和矩形
Time Limit: 5 Sec Memory Limit: 128 MB Special Judge
[Submit][Status][Web Board]
Description
Bobo 有一个三角形和一个矩形,他想求他们交的面积。
具体地,三角形和矩形由 8 个整数 x1,y1,x2,y2,x3,y3,x4,y4 描述。 表示三角形的顶点坐标是 (x1,y1),(x1,y2),(x2,y1), 矩形的顶点坐标是 (x3,y3),(x3,y4),(x4,y4),(x4,y3).
Input
输入包含不超过 30000 组数据。
每组数据的第一行包含 4 个整数 x1,y1,x2,y2 (x1≠x2,y1≠y2).
第二行包含 4 个整数 x3,y3,x4,y4 (x3<x4,y3<y4).
(0≤xi,yi≤104)
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
湖南省第十二届大学生计算机程序设计竞赛
思路:
半平面交板子题
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<list>
#include<stack>
#include<iomanip>
#include<cmath>
#include<bitset>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef long double ld;
#define INF (1ll<<60)-1
#define Max 1e9
using namespace std;
struct point {
long double x,y;
point(long double x=0,long double y=0):x(x),y(y) {}
};
typedef point vec;
const long double eps=1e-8;
const long double pi=acos(-1.0);
bool cmp(point a,point b) {
if(fabs(a.x-b.x)<=eps) return a.y<b.y;
return a.x<b.x;
}
vec operator -(point a,point b) {
return vec(a.x-b.x,a.y-b.y);
}
vec operator +(point a,point b) {
return vec(a.x+b.x,a.y+b.y);
}
vec operator *(point a,long double t) {
return vec(a.x*t,a.y*t);
}
vec operator /(point a,long double t) {
return vec(a.x/t,a.y/t);
}
bool operator < (const point &a,const point &b) {
return a.y<b.y || (fabs(a.y-b.y)<=eps && a.x<b.x);
}
bool operator == (const point &a,const point &b) {
if(fabs(a.x-b.x)<=eps && fabs(a.y-b.y)<=eps)
return true;
return false;
}
int dcmp(long double x) {
if(fabs(x)<=eps) return 0;
return x<0?-1:1;
}
long double cross(vec a,vec b) {///叉积
return a.x*b.y-a.y*b.x;
}
long double dot(vec a,vec b) {///点积
return a.x*b.x+a.y*b.y;
}
long double disn(point a,point b) {
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
/*两点之间的距离*/
}
struct line {
point p;
vec v;
long double ang;
line() {}
line(point p,vec v):p(p),v(v) {
ang=atan2(v.y,v.x);
}
point po(long double t) {
return p+v*t;
}
bool operator < (const line &l) const {
return ang<l.ang;
}
};
bool onleft(line l,point p){///点在直线的左边 =0表示点不能在直线上
return cross(l.v,p-l.p)>=0;
}
point GetLineIntersection(line a,line b){
vec u=a.p-b.p;
long double t=cross(b.v,u)/cross(a.v,b.v);
return a.p+a.v*t;
/*两条直线的交点*/
}
void convexhull(point *s,int &n) {
sort(s,s+n,cmp);
int m=0;
point p[110];
for(int i=0; i<n; i++) {
while(m>1 && dcmp(cross(p[m-1]-p[m-2],s[i]-p[m-2]))<=0)
m--;
p[m++]=s[i];
}
int k=m;
for(int i=n-2; i>=0; i--) {
while(m>k && dcmp(cross(p[m-1]-p[m-2],s[i]-p[m-2]))<=0)
m--;
p[m++]=s[i];
}
m--;
n=m;
for(int i=0; i<n; i++) s[i]=p[i];
/*建立凸包*/
}
vector<point> HalfplaneIntersection(vector<line> l) {
int n=l.size();
sort(l.begin(),l.end());
int top=0,bot=0;
vector<point> p(n);
vector<line> q(n);
vector<point> ans;
q[0]=l[0];
for(int i=0; i<n; i++) {
while(bot<top && !onleft(l[i],p[top-1])) top--;
while(bot<top && !onleft(l[i],p[bot])) bot++;
q[++top]=l[i];
if(dcmp(q[top].ang-q[top-1].ang)==0) {
top--;
if(onleft(q[top],l[i].p))
q[top]=l[i];
}
if(bot<top) p[top-1]=GetLineIntersection(q[top-1],q[top]);
}
while(bot<top && !onleft(q[bot],p[top-1])) top--;
if(top-bot<=1) return ans;
p[top]=GetLineIntersection(q[top],q[bot]);
for(int i=bot; i<=top; i++) {
ans.push_back(p[i]);
}
return ans;
/*半平面交 返回相交区域的点集*/
}
long double polyarea(vector<point> p){
int num=p.size();
long double area=0;
for(int i=1;i<num-1;i++){
area+=cross(p[i]-p[0],p[i+1]-p[0]);
}
return fabs(area*0.5);
/*点集的面积
p为点集 num为点的个数
*/
}
point s[10],p[10];
vector<line> L;
int main(){
long double x1,y1,x2,y2,x3,y3,x4,y4;
while(cin>>x1>>y1>>x2>>y2){
cin>>x3>>y3>>x4>>y4;
s[0].x=x1;s[0].y=y1;
s[1].x=x1;s[1].y=y2;
s[2].x=x2;s[2].y=y1;
p[0].x=x3;p[0].y=y3;
p[1].x=x3;p[1].y=y4;
p[2].x=x4;p[2].y=y4;
p[3].x=x4;p[3].y=y3;
int n=3,m=4;
convexhull(s,n);
convexhull(p,m);
s[n]=s[0];p[m]=p[0];
L.clear();
for(int i=0;i<n;i++) L.push_back(line(s[i],s[i+1]-s[i]));
for(int i=0;i<m;i++) L.push_back(line(p[i],p[i+1]-p[i]));
vector<point> poly=HalfplaneIntersection(L);
//for(int i=0;i<n;i++) cout<<setprecision(20)<<poly[i].x<<" "<<poly[i].y<<endl;
long double ans=polyarea(poly);
cout<<setprecision(20)<<ans<<endl;
}
return 0;
}