【kuangbin专题】计算几何基础(直线,线段相交)
【POJ 2318】 TOYS
【题目大意】
给定 n 条直线,m个玩具,每两个直线之间是一个隔间,一个玩具有一个坐标,问一个隔间内有多少个玩具
【题目思路】
暴力枚举,每读入一个点,扫一遍所有边,判断这个点是不是在两边之间,如果在,就给当前边的答案
1 bool is_midd(P a, L b, L c) 2 {//分别求点a 和 b,c的叉乘,判断他是在直线的左边还是右边
//如果两者异号,,则说明两边分别在点的不同方向 3 int x = cmp(cross(a - b.s, b.t - b.s)),
y = cmp(cross(a - c.s, c.t - c.s)); 4 return x * y <= 0; 5 6 }
【代码】
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<queue> 5 #include<iostream> 6 #include<algorithm> 7 #include<cmath> 8 using namespace std; 9 const double eps = 1e-6; 10 const int MAXN = 20010; 11 const double lim = 10000; 12 const double PI = acos(-1.0); 13 int n, m; 14 inline int cmp(double x) 15 { 16 if (x > eps)return 1; 17 return x < -eps ? -1 : 0; 18 } 19 struct V 20 { 21 int x, y; 22 double ang; 23 double angle() 24 {//求取极角 25 return atan2(y, x); 26 } 27 V(int X = 0,int Y = 0) 28 { 29 //初始化 30 x = X, y = Y; 31 } 32 bool operator ==(const V &b) 33 { 34 return cmp(x - b.x) && cmp(y - b.y); 35 } 36 37 }; 38 typedef V P; 39 V operator +(V a, V b) { return V(a.x + b.x, a.y + b.y); } 40 V operator -(V a, V b) { return V(a.x - b.x, a.y - b.y); } 41 V operator *(V a, double b) { return V(a.x *b, a.y*b); } 42 V operator /(V a, double b) { return V(a.x / b, a.y / b); } 43 struct L 44 { 45 P s, t; 46 double ang; 47 L(P X = V(), P Y = V()) 48 { 49 s = X, t = Y; 50 } 51 }; 52 typedef L S; 53 double cross(V a, V b) 54 { 55 return 1.0*a.x*b.y - 1.0*a.y*b.x; 56 } 57 bool is_midd(P a, L b, L c) 58 { 59 int x = cmp(cross(a - b.s, b.t - b.s)), y = cmp(cross(a - c.s, c.t - c.s)); 60 return x * y <= 0; 61 62 } 63 P p[MAXN]; 64 L l[MAXN]; 65 int ans[MAXN]; 66 int main() 67 { 68 int n, m, x1, y1, x2, y2; 69 while (scanf("%d", &n)) 70 { 71 if (n == 0) 72 break; 73 scanf("%d%d%d%d%d", &m, &x1, &y1, &x2, &y2); 74 l[0].s = P(x1, y2), l[0].t = P(x1, y1); 75 l[n + 1].s = P(x2, y2), l[n + 1].t = P(x2, y1); 76 for (int i = 1; i <= n; i++) 77 { 78 int u, v; 79 scanf("%d%d", &u, &v); 80 l[i].s = P(v, y2), l[i].t = P(u, y1); 81 } 82 memset(ans, 0, sizeof(ans)); 83 int temp = 0; 84 for (int i = 1; i <= m; i++) 85 { 86 int x, y; 87 scanf("%d%d", &x, &y); 88 P tmp = P(x, y); 89 for (int j = 0; j <= n; j++) 90 { 91 if (is_midd(tmp,l[j],l[j+1])) 92 { 93 94 ans[j]++; 95 break; 96 } 97 } 98 } 99 for (int i = 0; i <= n; i++) 100 printf("%d: %d\n", i, ans[i]); 101 printf("\n"); 102 } 103 return 0; 104 }
【POJ 3304】Segments
【题目大意】
给定 n 条线段,判断是否存在一个线段使他们投影在那条线端上的投影有交点,有输出“Yes”,无输出“No”
【题目分析】
思考下对于这个几何问题,投影的话可以看作从一条直线上对要投影的直线进行投影
所以,对投影区域的直线做一条垂直的直线,而这条直线就能够和所有直线相交,所以问题可以简化为
(以上说明变成几何形状放在脑子里面思考一下)
是否存在一条直线,能够和给定的所有直线相交
一条直线能够和所有直线相交的情况,最极端的看作,如果这条直线和线段端点有交点,则可以进行缩减
如果没有,因为已经到了端点,继续转必然导致无法相交
所以只需要判断各个直线的端点即可
double cross(V a, V b)
{
return a.x*b.y - a.y*b.x;
}
double cross(P a, P b, P c)
{
return cross(b-a, c-a);
}
bool L_is_Inter(L a, L b) {
//分别判断线段 b的起始点和终止点在 线段 a 的左侧还是右侧
//如果在不同侧的话,就说明两个线段相交 return cmp(cross(b.s, a.s, a.t))*cmp(cross(b.t, a.s, a.t)) <= 0; }
【代码】
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<queue> 5 #include<iostream> 6 #include<algorithm> 7 #include<cmath> 8 #define cmp sgn 9 using namespace std; 10 const double eps = 1e-8; 11 const int MAXN = 110; 12 const double lim = 10000; 13 const double PI = acos(-1.0); 14 int n, m; 15 inline int sgn(double x) 16 { 17 if (x > eps)return 1; 18 return x < -eps ? -1 : 0; 19 } 20 struct V 21 { 22 double x, y; 23 double ang; 24 double angle() 25 {//求取极角 26 return atan2(y, x); 27 } 28 V(double X = 0, double Y = 0) 29 { 30 //初始化 31 x = X, y = Y; 32 ang = atan2(y, x); 33 } 34 bool operator ==(const V &b) 35 { 36 return cmp(x - b.x) && cmp(y - b.y); 37 } 38 39 }; 40 typedef V P; 41 V operator +(V a, V b) { return V(a.x + b.x, a.y + b.y); } 42 V operator -(V a, V b) { return V(a.x - b.x, a.y - b.y); } 43 V operator *(V a, double b) { return V(a.x *b, a.y*b); } 44 double operator *(V a, V b) { return a.x*b.x+a.y*b.y; } 45 V operator /(V a, double b) { return V(a.x / b, a.y / b); } 46 struct L 47 { 48 P s, t; 49 double ang; 50 L(P X = V(), P Y = V()) 51 { 52 s = X, t = Y, ang = (Y - X).angle(); 53 } 54 }; 55 typedef L S; 56 double cross(V a, V b) 57 { 58 return a.x*b.y - a.y*b.x; 59 } 60 double cross(P a, P b, P c) 61 { 62 63 return cross(b-a, c-a); 64 } 65 bool L_is_Inter(L a, L b) 66 { 67 return cmp(cross(b.s, a.s, a.t))*cmp(cross(b.t, a.s, a.t)) <= 0; 68 } 69 P p[MAXN]; 70 L l[MAXN]; 71 72 bool check(P b,P c) 73 { 74 L a = L(b, c); 75 if (sgn(dis(a.s, a.t)) == 0)return false; 76 for(int i=1;i<=n;i++) 77 if (!L_is_Inter(a, l[i])) 78 { 79 return false; 80 } 81 return true; 82 } 83 int main() 84 { 85 int T; 86 scanf("%d", &T); 87 while (T--) 88 { 89 bool flag = false; 90 scanf("%d", &n); 91 for (int i = 1; i <= n; i++) 92 { 93 scanf("%lf%lf%lf%lf", &l[i].s.x, &l[i].s.y,&l[i].t.x,&l[i].t.y); 94 } 95 for(int i=1;i<=n;i++) 96 for (int j = 1; j <= n; j++) 97 { 98 if (check(l[i].s, l[j].s) || check(l[i].s, l[j].t) || check(l[i].t, l[j].t) || check(l[i].t, l[j].s)) 99 { 100 flag = true; 101 break; 102 } 103 if (flag) 104 break; 105 } 106 if (flag) 107 printf("Yes!\n"); 108 else 109 printf("No!\n"); 110 } 111 return 0; 112 }
【POJ 1269】Intersecting Lines
【题目大意】
给定n组线段,每组有两个线段,判断他们是否相交,如果相交输出交点,没有输出“NONE”,重合输出 “LINE”
【题目分析】
计算几何基础知识裸题,考察计算几何知识
【代码】
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cstring> 3 #include<vector> 4 #include<queue> 5 #include<iostream> 6 #include<algorithm> 7 #include<cmath> 8 using namespace std; 9 const double eps = 1e-6; 10 const int MAXN = 20010; 11 const double lim = 10000; 12 const double PI = acos(-1.0); 13 int n, m; 14 inline int cmp(double x) 15 { 16 if (x > eps)return 1; 17 return x < -eps ? -1 : 0; 18 } 19 struct V 20 { 21 double x, y; 22 double ang; 23 double angle() 24 {//求取极角 25 return atan2(y, x); 26 } 27 V(double X = 0, double Y = 0) 28 { 29 //初始化 30 x = X, y = Y; 31 ang = atan2(y, x); 32 } 33 bool operator ==(const V &b) 34 { 35 return cmp(x - b.x) && cmp(y - b.y); 36 } 37 38 }; 39 typedef V P; 40 V operator +(V a, V b) { return V(a.x + b.x, a.y + b.y); } 41 V operator -(V a, V b) { return V(a.x - b.x, a.y - b.y); } 42 V operator *(V a, double b) { return V(a.x *b, a.y*b); } 43 V operator /(V a, double b) { return V(a.x / b, a.y / b); } 44 struct L 45 { 46 P s, t; 47 double ang; 48 L(P X = V(), P Y = V()) 49 { 50 s = X, t = Y, ang = (Y - X).angle(); 51 } 52 }; 53 typedef L S; 54 double cross(V a, V b) 55 { 56 return a.x*b.y - a.y*b.x; 57 } 58 59 double dot(V a, V b) 60 { 61 return a.x*b.x + a.y*b.y; 62 } 63 bool is_parallel(L a, L b) 64 { 65 return cmp(cross(a.t - a.s, b.t - b.s)) == 0; 66 } 67 double cross(P a, P b, P c) 68 { 69 70 return cross(b - a, c - a); 71 } 72 bool L_is_Inter(L a, L b) 73 { 74 //分别判断线段 b的起始点和终止点在 线段 a 的左侧还是右侧 75 //如果在不同侧的话,就说明两个线段相交 76 //return cmp(cross(b.s, a.s, a.t))*cmp(cross(b.t, a.s, a.t)) <= 0; 77 return cmp(cross(b.s, b.t, a.s))==0; 78 } 79 P intersection(L a, L b) 80 { 81 return a.s + (a.t - a.s)*(cross(b.t - b.s, a.s - b.s)) / cross(a.t - a.s, b.t - b.s); 82 } 83 P p[MAXN]; 84 L l[MAXN]; 85 int main() 86 { 87 int n; 88 scanf("%d", &n); 89 printf("INTERSECTING LINES OUTPUT\n"); 90 for (int i = 1; i <= n; i++) 91 { 92 L a, b; 93 scanf("%lf %lf %lf %lf %lf %lf %lf %lf", &a.s.x, &a.s.y, &a.t.x, &a.t.y, &b.s.x, &b.s.y, &b.t.x, &b.t.y); 94 if (is_parallel(a, b)) 95 { 96 if (L_is_Inter(a, b)) 97 printf("LINE\n"); 98 else 99 printf("NONE\n"); 100 } 101 else 102 { 103 104 P p = intersection(a, b); 105 printf("POINT %.2f %.2f\n", p.x, p.y); 106 107 108 } 109 } 110 printf("END OF OUTPUT\n"); 111 return 0; 112 }
【POJ 1556】The Doors
【题目大意】
给定一个正方形和里面的墙,求从点(0,5)到点(10,5)的最短路径
【题目分析】
枚举所有点两两之间的点,当两个点之间没有墙壁挡着,即没有和墙相交的情况下,说明这两个点可以互相到达,记录
处理完所有可以走的点之间的路径之后
因为最多只有18堵墙,所以直接一波Floyd求最短路径
就能够得到我们所想要的答案
【代码】
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cmath> 3 #include<iostream> 4 #include<algorithm> 5 #define sgn cmp 6 #define e t 7 #define ll long long 8 using namespace std; 9 const int MAXN = 5010; 10 const double eps = 1e-9; 11 const double INF = 1e5; 12 inline int cmp(double x) 13 { 14 if (x > eps)return 1; 15 return x < -eps ? -1 : 0; 16 } 17 struct P 18 { 19 double x, y; 20 P(double a = 0, double b = 0) :x(a), y(b) {} 21 double operator ^(const P &b)const 22 { 23 return x * b.y - y * b.x; 24 } 25 }; 26 27 struct L 28 { 29 P s, t; 30 L(P a = P(0, 0), P b = P(0, 0)) :s(a), t(b) {} 31 }; 32 typedef P V; 33 bool operator ==(V a, V b) { return (cmp(a.x - b.x) == 0) && (cmp(a.y - b.y)); } 34 V operator +(V a, V b) { return V(a.x + b.x, a.y + b.y); } 35 V operator -(V a, V b) { return V(a.x - b.x, a.y - b.y); } 36 V operator *(V a, double b) { return V(a.x *b, a.y*b); } 37 double operator *(V a, V b) { return a.x*b.x + a.y*b.y; } 38 V operator /(V a, double b) { return V(a.x / b, a.y / b); } 39 double dis(P a, P b) 40 { 41 P tmp = b - a; 42 return sqrt(tmp * tmp); 43 } 44 double cross(V a, V b) 45 { 46 return a.x*b.y - a.y*b.x; 47 } 48 double cross(P a, P b, P c) 49 { 50 51 return cross(b - a, c - a); 52 } 53 bool L_is_Inter(L l1, L l2) 54 { 55 return 56 max(l1.s.x, l1.e.x) >= min(l2.s.x, l2.e.x) && 57 max(l2.s.x, l2.e.x) >= min(l1.s.x, l1.e.x) && 58 max(l1.s.y, l1.e.y) >= min(l2.s.y, l2.e.y) && 59 max(l2.s.y, l2.e.y) >= min(l1.s.y, l1.e.y) && 60 sgn((l2.s - l1.s) ^ (l1.e - l1.s))*sgn((l2.e - l1.s) ^ (l1.e - l1.s)) < 0 && 61 sgn((l1.s - l2.s) ^ (l2.e - l2.s))*sgn((l1.e - l2.s) ^ (l2.e - l2.s)) < 0; 62 } 63 P p[MAXN]; 64 L l[MAXN]; 65 double a[MAXN][MAXN]; 66 int main() 67 { 68 int n = 0, m = 0; 69 int N; 70 while (scanf("%d", &N)) 71 { 72 n = 0, m = 0; 73 if (N == -1) return 0; 74 p[++n] = P(0, 5); 75 for (int i = 1; i <= N; i++) 76 { 77 double x; 78 double y[7]; 79 y[0] = 0, y[5] = 10; 80 scanf("%lf%lf%lf%lf%lf", &x, &y[1], &y[2], &y[3], &y[4]); 81 for (int j = 1; j <= 4; j++) p[++n] = P(x, y[j]); 82 for (int j = 1; j <= 5; j += 2) l[++m] = L(P(x, y[j - 1]), P(x, y[j])); 83 } 84 p[++n] = P(10, 5); 85 for (int i = 1; i <= n; i++) 86 for (int j = 1; j <= n; j++) 87 a[i][j] = INF; 88 89 for (int i = 1; i <= n; i++) 90 for (int j = 1; j <= n; j++) 91 { 92 if (i == j) 93 { 94 a[i][j] = 0; 95 continue; 96 } 97 bool flag = 1; 98 for (int k = 1; k <= m; k++) 99 { 100 if (L_is_Inter(L(p[i], p[j]), l[k])) 101 { 102 flag = 0; break; 103 } 104 } 105 if (flag) a[i][j] = dis(p[i], p[j]); 106 107 } 108 for (int i = 1; i <= n; i++) 109 for (int j = 1; j <= n; j++) 110 for (int k = 1; k <= n; k++) 111 if (a[i][k] + a[k][j] < a[i][j]) 112 a[i][j] = a[i][k] + a[k][j]; 113 printf("%.2f\n", a[1][n]); 114 } 115 return 0; 116 }
【POJ 2653】Pick-up sticks
【题目大意】
给定 n 条木棍,按照顺序依次往下扔,问最后有哪几个木棍在最上面,输出编号
【题目分析】
木棍个数不多,直接暴力
【代码】
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cmath> 3 #include<iostream> 4 #include<algorithm> 5 #define sgn cmp 6 #define e t 7 #define ll double 8 using namespace std; 9 const int MAXN = 100010; 10 const double eps = 1e-9; 11 const double INF = 1e5; 12 inline int cmp(double x) 13 { 14 if (x > eps)return 1; 15 return x < -eps ? -1 : 0; 16 } 17 struct P 18 { 19 double x, y; 20 P(double a = 0, double b = 0) :x(a), y(b) {} 21 double operator ^(const P &b)const 22 { 23 return x * b.y - y * b.x; 24 } 25 }; 26 struct L 27 { 28 P s, t; 29 L(P a = P(0, 0), P b = P(0, 0)) :s(a), t(b) {} 30 }; 31 typedef P V; 32 bool operator ==(V a, V b) { return (cmp(a.x - b.x) == 0) && (cmp(a.y - b.y)); } 33 V operator +(V a, V b) { return V(a.x + b.x, a.y + b.y); } 34 V operator -(V a, V b) { return V(a.x - b.x, a.y - b.y); } 35 V operator *(V a, double b) { return V(a.x *b, a.y*b); } 36 double operator *(V a, V b) { return a.x*b.x + a.y*b.y; } 37 V operator /(V a, double b) { return V(a.x / b, a.y / b); } 38 double dis(P a, P b) 39 { 40 P tmp = b - a; 41 return sqrt(tmp * tmp); 42 } 43 double cross(V a, V b) 44 { 45 return a.x*b.y - a.y*b.x; 46 } 47 double cross(P a, P b, P c) 48 { 49 return cross(b - a, c - a); 50 } 51 bool L_is_Inter(L l1, L l2) 52 { 53 return 54 max(l1.s.x, l1.e.x) >= min(l2.s.x, l2.e.x) && 55 max(l2.s.x, l2.e.x) >= min(l1.s.x, l1.e.x) && 56 max(l1.s.y, l1.e.y) >= min(l2.s.y, l2.e.y) && 57 max(l2.s.y, l2.e.y) >= min(l1.s.y, l1.e.y) && 58 sgn((l2.s - l1.s) ^ (l1.e - l1.s))*sgn((l2.e - l1.s) ^ (l1.e - l1.s)) <= 0 && 59 sgn((l1.s - l2.s) ^ (l2.e - l2.s))*sgn((l1.e - l2.s) ^ (l2.e - l2.s)) <= 0; 60 } 61 L l[MAXN]; 62 bool t[MAXN]; 63 int ans[1010]; 64 int main() 65 { 66 int n; 67 while (scanf("%d", &n) && n) 68 { 69 for (int i = 1; i <= n; i++) 70 { 71 double x1, x2, y1, y2; 72 scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); 73 l[i] = L(P(x1, y1), P(x2, y2)); 74 t[i] = true; 75 } 76 ans[0] = 0; 77 for (int i = 1; i <= n; i++) 78 { 79 bool flag = 1; 80 for (int j = i + 1; j <= n; j++) 81 { 82 if (L_is_Inter(l[i], l[j])) 83 { 84 flag = 0; 85 break; 86 } 87 } 88 if (flag) ans[++ans[0]] = i; 89 } 90 printf("Top sticks: "); 91 for (int i = 1; i <=ans[0]; i++) 92 { 93 printf("%d", ans[i]); 94 if (i == ans[0]) 95 printf(".\n"); 96 else 97 printf(", "); 98 } 99 } 100 return 0; 101 }
【POJ 1066】Treasure Hunt
【题目大意】 给定一个正方形,再给定N条直线,再给定一个点,问从这个点出去到外面需要打破几堵墙,即和多少条直线相交
【题目分析】 枚举这个点和其他直线顶点的连线,然后记录最小即可
【注意】
1.N等于0的情况
2.有关需不需要忽略顶点的需求
【代码】
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #define e t 5 #define ll double 6 using namespace std; 7 const double eps = 1e-9; 8 const int MAXN = 500; 9 const int INF = 2e9; 10 int sgn(ll x) 11 { 12 if (x > eps) return 1; 13 if (x < -eps) return -1; 14 return 0; 15 } 16 struct P 17 { 18 double x, y; 19 P(double a = 0, double b = 0) : x(a), y(b) {} 20 double operator ^(P a) { return x * a.y - y * a.x; } 21 double operator *(P a) { return x * a.x + y * a.y; } 22 P operator *(double a) { return P(x*a, y*a); } 23 P operator -(P a) { return P(x - a.x, y - a.y); } 24 bool operator==(P a) { return sgn(a.x - x) == 0 && sgn(a.y - y); } 25 }; 26 typedef P V; 27 struct L 28 { 29 P s, t; 30 L(P a = P(0, 0), P b = P(0, 0)) :s(a), t(b) {} 31 }; 32 double cross(P a, P b, P c) 33 { 34 return (b - a) ^ (c - a); 35 } 36 bool is_para(L a, L b) 37 { 38 return sgn((a.t - a.s) ^ (b.t - b.s))==0; 39 } 40 bool onL(L a, P b) 41 { 42 V check = P(b - a.s); 43 V tmp = a.t - a.s ; 44 if (!is_para(a, check)) return 0; 45 return tmp*tmp > check*check; 46 } 47 bool L_is_inter(L l1, L l2) 48 { 49 return 50 max(l1.s.x, l1.e.x) >= min(l2.s.x, l2.e.x) && 51 max(l2.s.x, l2.e.x) >= min(l1.s.x, l1.e.x) && 52 max(l1.s.y, l1.e.y) >= min(l2.s.y, l2.e.y) && 53 max(l2.s.y, l2.e.y) >= min(l1.s.y, l1.e.y) && 54 sgn((l2.s - l1.s) ^ (l1.e - l1.s))*sgn((l2.e - l1.s) ^ (l1.e - l1.s)) < 0 && 55 sgn((l1.s - l2.s) ^ (l2.e - l1.s))*sgn((l1.e - l2.s) ^ (l2.e - l2.s)) < 0; 56 } 57 L l[MAXN]; 58 P p[MAXN]; 59 int main() 60 { 61 int N; 62 scanf("%d", &N); 63 if (N == 0) 64 { 65 printf("Number of doors = 1"); 66 return 0; 67 } 68 int n = 0,m = 0; 69 for (int i = 1; i <= N; i++) 70 { 71 ll x1, x2, y1, y2; 72 scanf("%lf%lf%lf%lf", &x1, &y1, &x2, &y2); 73 l[++m] = L(P(x1, y1), P(x2, y2)); 74 p[++n] = P(x1, y1), p[++n] = P(x2, y2); 75 } 76 P beg; 77 scanf("%lf%lf", &beg.x, &beg.y); 78 int ans = INF; 79 int pos; 80 for (int i = 1; i <= n; i++) 81 { 82 int cnt = 0; 83 L check = L(beg, p[i]); 84 for (int j = 1; j <= m; j++) 85 { 86 if (L_is_inter(check, l[j])) 87 { 88 cnt++; 89 // l1[++siz] = l[j]; 90 } 91 } 92 if (cnt < ans) 93 { 94 ans = cnt; 95 } 96 } 97 printf("Number of doors = %d", ans+1); 98 99 return 0; 100 }
【POJ 1410】Intersection
【题目大意】
给定一个线段的起始点和终止点,再给定一个矩形的左上点和右下点,求这个线段是否和矩形相交,相交输出“T”,否则输出“F”
【题目分析】
好,又是一道裸题
但是注意,线段包含在矩形中时,输出“ T ”
【代码】
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cmath> 3 #include<algorithm> 4 #define e t 5 #define ll double 6 using namespace std; 7 const double eps = 1e-9; 8 int sgn(ll x) 9 { 10 if (x > eps) return 1; 11 if (x < -eps) return -1; 12 return 0; 13 } 14 struct P 15 { 16 double x, y; 17 P(double a = 0, double b = 0) : x(a), y(b) {} 18 double operator ^(P a) { return x * a.y - y * a.x; } 19 double operator *(P a) { return x * a.x + y * a.y; } 20 P operator *(double a) { return P(x*a, y*a); } 21 P operator -(P a) { return P(x - a.x, y - a.y); } 22 bool operator==(P a) { return sgn(a.x - x) == 0 && sgn(a.y - y); } 23 }; 24 typedef P V; 25 struct L 26 { 27 P s, t; 28 L(P a = P(0, 0), P b = P(0, 0)) :s(a), t(b) {} 29 }; 30 double cross(P a, P b, P c) 31 { 32 return (b - a) ^ (c - a); 33 } 34 bool L_is_inter(L l1, L l2) 35 { 36 return 37 max(l1.s.x, l1.e.x) >= min(l2.s.x, l2.e.x) && 38 max(l2.s.x, l2.e.x) >= min(l1.s.x, l1.e.x) && 39 max(l1.s.y, l1.e.y) >= min(l2.s.y, l2.e.y) && 40 max(l2.s.y, l2.e.y) >= min(l1.s.y, l1.e.y) && 41 sgn((l2.s - l1.s) ^ (l1.e - l1.s))*sgn((l2.e - l1.s) ^ (l1.e - l1.s)) <= 0 && 42 sgn((l1.s - l2.s) ^ (l2.e - l1.s))*sgn((l1.e - l2.s) ^ (l2.e - l2.s)) <= 0; 43 } 44 L line[10]; 45 int main() 46 { 47 int T; 48 scanf("%d", &T); 49 while (T--) 50 { 51 L l; 52 int n = 0; 53 scanf("%lf %lf %lf %lf", &l.s.x, &l.s.y, &l.t.x, &l.t.y); 54 double x1, x2, y1, y2; 55 scanf("%lf %lf %lf %lf", &x1, &y1, &x2, &y2); 56 if (x1 > x2) swap(x1, x2); 57 if (y1 < y2) swap(y1, y2); 58 line[++n] = L(P(x1, y1), P(x2, y1)); 59 line[++n] = L(P(x1, y1), P(x1, y2)); 60 line[++n] = L(P(x2, y1), P(x2, y2)); 61 line[++n] = L(P(x1, y2), P(x2, y2)); 62 bool flag = false; 63 for (int i = 1; i <= n; i++) 64 { 65 if (L_is_inter(line[i], l)) 66 { 67 flag = true; 68 break; 69 } 70 } 71 if (l.s.x >= x1 && l.s.x <= x2 72 && l.t.x >= x1 && l.t.x <= x2 73 && l.s.y >= y2 && l.s.y <= y1 74 && l.t.y >= y2 && l..y <= y1) 75 flag = true; 76 printf("%c\n", flag ? 'T' : 'F'); 77 } 78 return 0; 79 }