poj2826
要判断线段相交,然后就各种情况分类讨论虽然过了,但是discuss里某组样例没过而且还是g++WA, c++A
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const double EPS = 1e-6;
struct Point
{
Point() {}
Point(double _x, double _y): x(_x), y(_y) {}
void input()
{
scanf("%lf%lf", &x, &y);
}
double getDis(Point &rhs)
{
double xx = x - rhs.x;
xx *= xx;
double yy = y - rhs.y;
yy *= yy;
return sqrt(xx + yy);
}
double x, y;
};
Point operator -(Point lhs, Point rhs)
{
Point ret = Point(lhs.x - rhs.x, lhs.y - rhs.y);
return ret;
}
double operator ^(Point lhs, Point rhs)
{
double ret = lhs.x * rhs.y - lhs.y * rhs.x;
return ret;
}
bool isCross(Point &a, Point &b, Point &c, Point &d)
{
if(min(a.x, b.x) <= max(c.x, d.x) &&
min(a.y, b.y) <= max(c.y, d.y) &&
min(c.x, d.x) <= max(a.x, b.x) &&
min(c.y, d.y) <= max(a.y, b.y))
{
double u, v, w, z;
u = (c - a) ^ (b - a);
v = (d - a) ^ (b - a);
w = (a - c) ^ (d - c);
z = (b - c) ^ (d - c);
if(u * v <= EPS && w * z <= EPS && fabs((a - b) ^ (c - d)) > EPS) return true;
}
return false;
}
Point getIntersect(Point &a, Point &b, Point &c, Point &d)
{
double D = (a - b) ^ (c - d);
double a1 = b.y - a.y, a2 = d.y - c.y;
double b1 = a.x - b.x, b2 = c.x - d.x;
double c1 = a ^ (b - a), c2 = c ^ (d - c);
Point ret = Point((b2 * c1 - b1 * c2) / D, (a1 * c2 - a2 * c1) / D);
return ret;
}
Point a, b, c, d;
int n;
Point getMaxY(Point &a, Point &b, Point &o)
{
Point ret = a;
if(b.y > o.y) ret = b;
return ret;
}
double solve()
{
if(isCross(a, b, c, d) && a.y != b.y && c.y != d.y)
{
Point o = getIntersect(a, b, c, d);
Point p = getMaxY(a, b, o);
Point q = getMaxY(c, d, o);
Point r, s;
Point oo = o;
++oo.y;
double s1 = (oo - o) ^ (p - o), s2 = (oo - o) ^ (q - o);
if(fabs(p.y - q.y) <= EPS)
{
r = p;
s = q;
goto getSum;
}
if(fabs(p.x - q.x) <= EPS) return 0.0;
if(fabs(p.x - o.x) <= EPS || fabs(q.x - o.x) <= EPS) goto getRS;
if(s1 * s2 > 0)
{
double s3;
Point temp1 = p - o, temp2 = q - o, temp3 = p - q;
double k1 = fabs(temp1.y / temp1.x), k2 = fabs(temp2.y / temp2.x);
double k3 = fabs(temp3.y / temp3.x);
if(p.y > q.y)
{
s3 = (oo - o) ^ (p - q);
}
else
{
s3 = (oo - o) ^ (q - p);
}
if(s3 * s1 > 0 && k3 > k1 && k3 > k2) return 0.0;
// printf("k3:%lf k2:%lf k1:%lf\n", k3, k2, k1);
}
getRS:
if(p.y > q.y)
{
s = q;
double part1 = s.y - o.y, part2 = p.y - s.y;
r.x = o.x + (p.x - o.x) * part1 / (part1 + part2);
r.y = o.y + (p.y - o.y) * part1 / (part1 + part2);
}
else
{
r = p;
double part1 = r.y - o.y, part2 = q.y - r.y;
s.x = o.x + (q.x - o.x) * part1 / (part1 + part2);
s.y = o.y + (q.y - o.y) * part1 / (part1 + part2);
}
getSum:
// printf("r: %lf %lf\ns: %lf %lf\no:%lf %lf\n", r.x, r.y, s.x, s.y, o.x, o.y);
double ret = (r - o) ^ (s - o);
ret = fabs(ret) / 2.0;
return ret;
}
else return 0.0;
}
int main()
{
// freopen("in.txt", "r", stdin);
scanf("%d", &n);
for(int i = 1; i <= n; ++i)
{
a.input();
b.input();
c.input();
d.input();
printf("%.2f\n", solve());
}
}