题目:
(0,0)-(10000,10000)的平面,给出n条直线切,求最后的面积。
思路:
半平面交裸题,注意给的点的顺序就好。
#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
const double eps = 1e-6;
struct Point
{
double x, y;
Point(double x = 0, double y = 0):x(x),y(y) {}
};
typedef Point Vector;
Vector operator + (Vector A, Vector B){return Vector(A.x+B.x, A.y+B.y);}
Vector operator - (Point A, Point B){return Vector(A.x-B.x, A.y-B.y);}
Vector operator * (Vector A, double p){return Vector(A.x*p, A.y*p);}
Vector operator /(Vector A, double p){return Vector(A.x/p,A.y/p);}
int sgn(double x)
{
if(fabs(x) < eps)
return 0;
if(x < 0)
return -1;
return 1;
}
double Dot(Vector A, Vector B){return A.x*B.x + A.y*B.y;}
double Cross(Vector A, Vector B){return A.x*B.y-A.y*B.x;}
double Length(Vector A){return sqrt(Dot(A, A));}
Vector Normal(Vector A)
{
double L = Length(A);
return Vector(-A.y/L, A.x/L);
}
struct Line
{
Point p;
Vector v;
double ang;
Line() {}
Line(Point p, Vector v) : p(p), v(v)
{
ang = atan2(v.y, v.x);
}
bool operator < (const Line& L) const
{
return ang < L.ang;
}
} line[1000];
bool OnLeft(Line L, Point p)
{
return Cross(L.v, p - L.p) >= 0;
}
Point GetIntersection(Line a, Line b)
{
Vector u = a.p - b.p;
double t = Cross(b.v, u)/Cross(a.v, b.v);
return a.p + a.v*t;
}
int HalfplaneIntersection(Line* L, int n, Point* poly)
{
sort(L, L + n);
int fst = 0, lst = 0;
Point *P = new Point[n];
Line *q = new Line[n];
q[fst = lst = 0] = L[0];
for(int i = 1; i < n; ++i)
{
while(fst < lst && !OnLeft(L[i], P[lst - 1])) --lst;
while(fst < lst && !OnLeft(L[i], P[fst])) ++fst;
q[++lst] = L[i];
if(sgn(Cross(q[lst].v, q[lst - 1].v)) == 0)
{
--lst;
if(OnLeft(q[lst], L[i].p)) q[lst] = L[i];
}
if(fst < lst)
P[lst - 1] = GetIntersection(q[lst - 1], q[lst]);
}
while(fst < lst && !OnLeft(q[fst], P[lst - 1])) --lst;
if(lst - fst <= 1) return 0;
P[lst] = GetIntersection(q[lst], q[fst]);
int m = 0;
for(int i = fst; i <= lst; ++i) poly[m++] = P[i];
return m;
}
Point poly[20500];
void init()
{
Point a[4];
a[0] = Point(0, 0);
a[1] = Point(0,10000);
a[2] = Point(10000, 10000);
a[3] = Point(10000,0);
for(int i =0; i<4; i++)
{
line[i] = Line(a[i],a[i]- a[(i+1)%4]);
}
}
int main()
{
Point a,b;
int cnt = 4;
char s[20];
init();
int n;
scanf("%d", &n);
for(int i = 0;i<n;i++)
{
scanf("%lf%lf%lf%lf",&a.x, &a.y, &b.x,&b.y);
line[cnt++] = Line(a, b-a);
}
int m = HalfplaneIntersection(line, cnt, poly);
double area = 0;
for(int i = 0;i<m;i++)
{
area += Cross(poly[i], poly[(i+1)%m]);
}
area = fabs(area)/2;
printf("%.1f\n",area);
return 0;
}