poj 1410 线段与矩形相交

时间:2023-02-10 20:21:23
题意:判断是否线段有和给定的矩形右交点
解法:几何模板题

坑点

  • 不一定就是左上点和右下点

  • 线段如果在矩形内也算是相交

 
  1. /************************************************************************* 
  2.     > File Name: poj1410.cpp 
  3.     > Author: cy 
  4.     > Mail: 1002@qq.com  
  5.     > Created Time: 14/11/10 19:38:24 
  6.  ************************************************************************/ 
  7.  
  8. #include<iostream> 
  9. #include<cstring> 
  10. #include <algorithm> 
  11. #include<cstdlib> 
  12. #include<vector> 
  13. #include<cmath> 
  14. #include<stdlib.h> 
  15. #include<iomanip> 
  16. #include<list> 
  17. #include<deque> 
  18. #include<map> 
  19. #include <stdio.h> 
  20. #include <queue> 
  21.  
  22. const int maxn=1000+5
  23.  
  24. #define inf 0x3f3f3f3f 
  25.   #define INF 0x3FFFFFFFFFFFFFFFLL 
  26. #define rep(i,n) for(i=0;i<n;i++) 
  27.  #define reP(i,n) for(i=1;i<=n;i++) 
  28.  
  29. #define ull unsigned long long 
  30.  #define ll long long 
  31.  
  32. #define cle(a) memset(a,0,sizeof(a)) 
  33.  
  34. using namespace std; 
  35. double eps= 0.00000001
  36. struct point  //定义点 
  37.     double x; 
  38.     double y; 
  39. }; 
  40.  
  41.  
  42. point operator -(point a,point b) //向量减法 
  43.     point v; 
  44.     v.x=a.x-b.x; 
  45.     v.y=a.y-b.y; 
  46.     return v; 
  47.  
  48. bool zero(double x) 
  49.     return fabs(x)<eps?true:false
  50.  
  51. double fork_mul(point a,point b) //向量叉积 
  52.     return (a.x*b.y-a.y*b.x); 
  53.  
  54. double min(double x,double y) 
  55.     return x<y?x:y; 
  56.  
  57. double max(double x,double y) 
  58.     return x>y?x:y; 
  59.  
  60. int intersect_sign(point a,point b,point c,point d,point &result) //两线段位置关系的标志 
  61.     double cba=fork_mul(b-c,a-c); 
  62.     double dba=fork_mul(b-d,a-d),v12=fork_mul(b-a,d-c); 
  63.     if(zero(v12)==true//两线段方向相同 
  64.     { 
  65.         if(zero(cba)==true&&zero(dba)==true//两线段共线 
  66.         { 
  67.             if(min(a.x,b.x)<max(c.x,d.x)&&min(c.x,d.x)<max(a.x,b.x)&&min(a.y,b.y)<max(c.y,d.y)&&min(c.y,d.y)<max(a.y,b.y)) 
  68.                 return -3//重叠共线 
  69.             if(min(a.x,b.x)>max(c.x,d.x)||min(c.x,d.x)>max(a.x,b.x)||min(a.y,b.y)>max(c.y,d.y)||min(c.y,d.y)>max(a.y,b.y)) 
  70.                 return -2//分离共线 
  71.             return -1//首尾相接 
  72.         } 
  73.         else 
  74.             return 0//两线段平行 
  75.     } 
  76.     else //两线段方向不同,它们各自所在的直线相交 
  77.     { 
  78.         double bdc=fork_mul(d-b,c-b),adc=fork_mul(d-a,c-a); 
  79.         result.x=(dba*c.x-cba*d.x)/(dba-cba); //求两线段所在直线的交点 
  80.         result.y=(dba*c.y-cba*d.y)/(dba-cba); 
  81.         if(dba*cba<=0&&bdc*adc<=0
  82.             return 1//线段相交 
  83.         else 
  84.             return 2//线段不相交 
  85.     } 
  86. bool getbool(point a,point b,point c)//判断是否在矩形内 
  87.     int minx=min(b.x,c.x); 
  88.     int maxx=max(b.x,c.x); 
  89.     int miny=min(b.y,c.y); 
  90.     int maxy=max(b.y,c.y); 
  91.     if(a.x>=minx&&a.x<=maxx&&a.y>=miny&&a.y<=maxy) 
  92.     { 
  93.         return true
  94.     } 
  95.     return false
  96. int main() 
  97. #ifndef ONLINE_JUDGE 
  98.      freopen("in.txt","r",stdin); 
  99.      //freopen("out.txt","w",stdout); 
  100. #endif 
  101.     int n; 
  102.     cin>>n; 
  103.     while(n--) 
  104.     { 
  105.         point be,en;//线段的起点和终点 
  106.         scanf("%lf%lf%lf%lf",&be.x,&be.y,&en.x,&en.y); 
  107.         point upleft,downright,upright,downleft; 
  108.         scanf("%lf%lf%lf%lf",&upleft.x,&upleft.y,&downright.x,&downright.y); 
  109.         if(getbool(be,upleft,downright)||getbool(en,upleft,downright)) 
  110.         { 
  111.             cout<<"T"<<endl; 
  112.             continue
  113.         } 
  114.         downleft.x=downright.x;downleft.y=upleft.y; 
  115.         upright.x=upleft.x;upright.y=downright.y; 
  116.         point temp; 
  117.         if(intersect_sign(be,en,upleft,upright,temp)%2==1||intersect_sign(be,en,upleft,downleft,temp)%2==1||intersect_sign(be,en,downleft,downright,temp)%2==1||intersect_sign(be,en,upright,downright,temp)%2==1
  118.         { 
  119.             cout<<"T"<<endl; 
  120.         } 
  121.         else
  122.             cout<<"F"<<endl; 
  123.         } 
  124.     } 
  125.     return 0
  126. }