[POJ2826] An Easy Problem?! && 计算几何

保存一个不错的叉积讲解 http://blog.csdn.net/hustspy1990/article/details/11082745

本题需判断有无交点 是否被覆盖 以及是否水平

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<cstring>
#include<cmath>
#define SF scanf
#define PF printf
using namespace std;
typedef long long LL;
const double PI = acos(-1.0);
const double EPS = 1e-6;
struct Vector {
	double x, y;
	Vector() {}
	Vector(double xx, double yy) { x = xx; y = yy; }
	Vector(double rad) { x = cos(rad); y = sin(rad); }
	double len() const { return sqrt(x*x + y*y); }
	
	Vector operator + (const Vector &b) const {
		return Vector(x + b.x, y + b.y);
	}
	Vector operator - (const Vector &b) const {
		return Vector(x - b.x, y - b.y);
	}
	Vector operator * (const Vector &b) const {
		return Vector(x - b.x, y - b.y);
	}
	Vector operator * (const double &b) const {
		return Vector(x*b, y*b);
	}
	Vector operator / (const double &b) const {
		return Vector(x / b, y / b);
	}
	bool operator == (const Vector &b) const {
		return x == b.x && y == b.y;
	}
};
double Dot(const Vector &a, const Vector &b) {
	return a.x * b.x + a.y * b.y;
}
double Cross(const Vector &a, const Vector &b) {
	return a.x * b.y - a.y * b.x;
}
Vector GetAngle(const Vector &a, const Vector &b) {
	double l1 = a.len(), l2 = b.len();
	return Vector(Dot(a, b) / l1 / l2, Cross(a, b)/ l1 / l2);
}
Vector Rotate(const Vector &a, const Vector &angle) {
	return Vector(a.x * angle.x - a.y * angle.y, a.x * angle.y + a.y * angle.x);
}
typedef Vector Point, Angle;
Point Line1[2], Line2[2];
Vector A, B;
Point GetIntersection(const Point &a, const Point &b, const Point &c, const Point &d)
{
    double t = 1.0 * Cross(d - c, a - c) / Cross(b - a, d - c);
	return a + (b - a) * t;
}
int main()
{
	int T; SF("%d", &T); while(T--) {
		SF("%lf%lf%lf%lf", &Line1[0].x, &Line1[0].y, &Line1[1].x, &Line1[1].y);
		SF("%lf%lf%lf%lf", &Line2[0].x, &Line2[0].y, &Line2[1].x, &Line2[1].y);
		Point a = Line1[0], b = Line1[1], c = Line2[0], d = Line2[1];
		if(a.y < b.y) swap(a, b);
		if(c.y < d.y) swap(c, d);
		A = a - b; B = c - d;
		if(fabs(A.y) < EPS || fabs(B.y) < EPS) {
			puts("0.00");
			continue;
		}
		if(fabs(A.y * B.x - B.y * A.x) < EPS) { puts("0.00"); continue; }
		if(Cross(b-a, c-a) * Cross(b-a, d-a) > 0  // Line2 是否跨越Line1 检查端点相对Line1的位置
		|| Cross(d-c, a-c) * Cross(d-c, b-c) > 0)  // Line1 是否跨越Line2 检查端点相对Line2的位置
		{
			puts("0.00");
			continue;
		}
		Point p = GetIntersection(a, b, c, d);
		Vector Y(0, 1);
		
		if((Cross(a-p, c-p) < 0 && c.x - a.x <= EPS)
		|| (Cross(a-p, c-p) > 0 && c.x - a.x >= -EPS))
		{
			puts("0.00");
			continue;
		}
		double H = min(a.y, c.y);
		double x1 = a.x + A.x * (H - a.y) / A.y;
		double x2 = c.x + B.x * (H - c.y) / B.y;
		double ans = fabs((x1 - x2) * (H - p.y)) / 2.0;
		printf("%.2f\n", ans + EPS);
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值