描述
给出平面上两条线段的两个端点,判断这两条线段是否相交(有一个公共点或有部分重合认为相交)。 如果相交,输出”Yes”,否则输出”No”。
Input
第1行:一个数T,表示输入的测试数量(1 <= T <= 1000)
第2 - T + 1行:每行8个数,x1,y1,x2,y2,x3,y3,x4,y4。(-10^8 <= xi, yi <= 10^8)
(直线1的两个端点为x1,y1 | x2, y2,直线2的两个端点为x3,y3 | x4, y4)
Output
输出共T行,如果相交输出”Yes”,否则输出”No”。
Input示例
2
1 2 2 1 0 0 2 2
-1 1 1 1 0 0 1 -1
Output示例
Yes
No
题解
计算几何相关问题。
代码
#include <iostream>
using namespace std;
const double eps = 1e-10;
struct point
{
double x, y;
};
double min(double a, double b)
{
return a < b ? a : b;
}
double max(double a, double b)
{
return a > b ? a : b;
}
bool inter(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))
{
return 0;
}
double h, i, j, k;
h = (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);
i = (b.x - a.x) * (d.y - a.y) - (b.y - a.y) * (d.x - a.x);
j = (d.x - c.x) * (a.y - c.y) - (d.y - c.y) * (a.x - c.x);
k = (d.x - c.x) * (b.y - c.y) - (d.y - c.y) * (b.x - c.x);
return h * i <= eps && j * k <= eps;
}
int main(int argc, const char * argv[])
{
#ifndef TEST_DATA
freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int T;
cin >> T;
point a, b, c, d;
while (T--)
{
cin >> a.x >> a.y >> b.x >> b.y >> c.x >> c.y >> d.x >> d.y;
if (inter(a, b, c, d))
{
cout << "Yes\n";
}
else
{
cout << "No\n";
}
}
return 0;
}