POJ1410线段相交快速排斥实验跨立实验
Posted hesorchen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ1410线段相交快速排斥实验跨立实验相关的知识,希望对你有一定的参考价值。
题目
给出二维平面中一条线段和一个矩形,问线段和矩形是否有交点,矩形包括边和内部。
解题思路
先判断线段和四条边是否相交,如果没交点,再继续判断线段是否在矩形内。
判断线段相交需要使用快速排斥实验和跨立实验。
直接使用跨立实验会有问题,比如其中一条线段退化成一个点的情况,可以通过跨立实验,但是不能通过快速排斥实验:
代码
#include <iostream>
using namespace std;
const int N = 1e5 + 5;
typedef struct Point
{
int x, y;
Point operator-(const Point temp)
{
Point T;
T.x = x - temp.x;
T.y = y - temp.y;
return T;
}
bool operator==(const Point temp)
{
if (x == temp.x && y == temp.y)
return 1;
return 0;
}
} Vector;
double cross(Vector A, Vector B)
{
return A.x * B.y - B.x * A.y;
}
const double eps = 0;
int sign(double x)
{
if (x < eps)
return -1;
else if (x > eps)
return 1;
return 0;
}
bool f(Point a1, Point a2, Point b1, Point b2)
{
if (max(a1.x, a2.x) < min(b1.x, b2.x) ||
max(a1.y, a2.y) < min(b1.y, b2.y) ||
max(b1.x, b2.x) < min(a1.x, a2.x) ||
max(b1.y, b2.y) < min(a1.y, a2.y))
return 0; //先通过快速排斥实验
double c1 = cross(a2 - a1, b1 - a1), c2 = cross(a2 - a1, b2 - a1);
double c3 = cross(b2 - b1, a2 - b1), c4 = cross(b2 - b1, a1 - b1);
return sign(c1) * sign(c2) <= 0 && sign(c3) * sign(c4) <= 0;
}
bool f2(Point X, Point A, Point B, Point C, Point D)
{
if (cross(A - X, B - X) * cross(C - X, D - X) < eps)
return 1;
return 0;
}
void solve()
{
Point A, B, C, D, E, F;
cin >> E.x >> E.y >> F.x >> F.y;
cin >> A.x >> A.y >> D.x >> D.y;
B.x = A.x, B.y = D.y;
C.x = D.x, C.y = A.y;
if (f(A, B, E, F) || f(B, D, E, F) || f(C, D, E, F) || f(A, C, E, F) ||
(f2(E, A, B, C, D) && f2(E, A, C, B, D)) ||
(f2(F, A, B, C, D) && f2(F, A, C, B, D)))
printf("T\\n");
else
printf("F\\n");
}
int main()
{
int t;
cin >> t;
while (t--)
solve();
return 0;
}
/*
*/
参考资料
以上是关于POJ1410线段相交快速排斥实验跨立实验的主要内容,如果未能解决你的问题,请参考以下文章