堆坂子的题目。
判断线段相交,共线视为不相交。
求出交点,然后判断在上面的那条线段有没有覆盖住下面的那条线段。
最后输出面积的时候小心输出-0.00的情况。
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <cstdio>
using namespace std;
typedef unsigned long long ll;
#define maxn 111111
#define pi acos (-1)
#define rotate Rotate
const double eps = 1e-8;
int dcmp (double x) {
if (fabs (x) < eps)
return 0;
else return x < 0 ? -1 : 1;
}
struct point {
double x, y;
point (double _x = 0, double _y = 0) : x(_x), y(_y) {}
point operator - (point a) const {
return point (x-a.x, y-a.y);
}
point operator + (point a) const {
return point (x+a.x, y+a.y);
}
bool operator < (const point &a) const {
return x < a.x || (x == a.x && y < a.y);
}
bool operator == (const point &a) const {
return dcmp (x-a.x) == 0 && dcmp (y-a.y) == 0;
}
}p[maxn];
point operator * (point a, double p) {
return point (a.x*p, a.y*p);
}
double cross (point a, point b) {
return a.x*b.y-a.y*b.x;
}
double dot (point a, point b) {
return a.x*b.x + a.y*b.y;
}
bool OnSegment (point p, point a1, point a2) {
return dcmp (cross (a1-p, a2-p) == 0) && dcmp (dot (a1-p, a2-p) <= 0);
}
bool SegmentProperIntersection (point a1, point a2, point b1, point b2) {
double c1 = cross (a2-a1, b1-a1), c2 = cross (a2-a1, b2-a1),
c3 = cross (b2-b1, a1-b1), c4 = cross (b2-b1, a2-b1);
if (dcmp (c1) == 0 && dcmp (c2) == 0)
return 0; //两条线段共线
if (dcmp (c1)*dcmp (c2) < 0 && dcmp (c3)*dcmp (c4) < 0)
return 1;
else if (OnSegment (a1, b1, b2) || OnSegment (a2, b1, b2) || OnSegment (b1, a1, a2) || OnSegment (b2, a1, a2)) {
return 1;
}
return 0;
}
point GetLineIntersection (point p, point v, point q, point w) {
point u = p-q;
double t = cross (w, u) / cross (v, w);
return p+v*t;
}
int n, m, tot;
bool ok (point a1, point a2) {
if (a1.x*a2.x <= 0)
return 1;
double ang1 = abs (a1.y/a1.x), ang2 = abs (a2.y/a2.x);
if (ang1 > ang2 && fabs (a1.x) >= fabs (a2.x))
return 0;
if (ang2 > ang1 && fabs (a2.x) >= fabs (a1.x))
return 0;
return 1;
}
const double INF = 1e30;
int main () {
//freopen ("in", "r", stdin);
int t;
scanf ("%d", &t);
point a1, a2, b1, b2;
while (t--) {
cin >> a1.x >> a1.y >> a2.x >> a2.y;
cin >> b1.x >> b1.y >> b2.x >> b2.y;
if (a1.y > a2.y)
swap (a1, a2);
if (b1.y > b2.y)
swap (b1, b2);
if (!SegmentProperIntersection (a1, a2, b1, b2)) {
printf ("0.00\n");
}
else {
point ans = GetLineIntersection (a1, a2-a1, b1, b2-b1);
double h = min (a2.y, b2.y);
if (dcmp (h-ans.y) == 0 || !ok (a2-ans, b2-ans)) {
printf ("0.00\n");
continue;
}
double p2 = b1.x+(b2.x-b1.x)*(h-b1.y)/(b2.y-b1.y);
double p1 = a1.x+(a2.x-a1.x)*(h-a1.y)/(a2.y-a1.y);
double area = (p2-p1)*(h-ans.y)/2;
printf ("%.2f\n", abs (area)+eps);
}
}
return 0;
}