poj 1410 Intersection

 蒻苣:弱弱很弱,路过的巨巨还不吝赐教!^.^...QAQ

题意:给出一个长方形和一条线段,判断线段是否与长方形相交。

题解:直接叉积就行了。

坑点:线段在长方形内也算相交,与长方形边重合也算相交,给出的长方形并不是一个左上角一个右上角。

由于这个坑点,找了一个高精确的模版:intersect_sign

代码:

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <cstring>
  5 #include <algorithm>
  6 #include <queue>
  7 #include <cmath>
  8 using namespace std;
  9 const double INF  = 1E200;
 10 const double wc = 1E-8;
 11 struct POINT{
 12         double x,y;
 13         POINT( double a = 0,double b = 0 )  { x = a; y = b; }
 14 };
 15 struct LINESEG{
 16         POINT e;
 17         POINT s;
 18         LINESEG( POINT x,POINT y ) { e = x; s = y; }
 19         LINESEG(){}
 20 };
 21 typedef POINT Vector;  //引申为向量
 22 
 23 Vector operator -(Vector a,Vector b) //向量减法
 24 {
 25     POINT v;
 26     v.x=a.x-b.x;
 27     v.y=a.y-b.y;
 28     return v;
 29 }
 30 
 31 double dist(POINT p1,POINT p2)
 32 {
 33  return( sqrt( (p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y) ) );
 34 }
 35 double multiply(POINT sp,POINT ep,POINT op)
 36 {
 37  return((sp.x-op.x)*(ep.y-op.y)-(ep.x-op.x)*(sp.y-op.y));
 38 }
 39 bool online(LINESEG l,POINT p)
 40 {
 41  return( (multiply(l.e,p,l.s)==0) &&( ( (p.x-l.s.x)*(p.x-l.e.x)<=0 )&&( (p.y-l.s.y)*(p.y-l.e.y)<=0 ) ) );
 42 }
 43 bool intersect(LINESEG u,LINESEG v)
 44 {
 45  return( (max(u.s.x,u.e.x)>=min(v.s.x,v.e.x))&&
 46    (max(v.s.x,v.e.x)>=min(u.s.x,u.e.x))&&
 47    (max(u.s.y,u.e.y)>=min(v.s.y,v.e.y))&&
 48    (max(v.s.y,v.e.y)>=min(u.s.y,u.e.y))&&
 49    (multiply(v.s,u.e,u.s)*multiply(u.e,v.e,u.s)>=wc)&&
 50    (multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=wc));
 51 }
 52 bool intersect_A(LINESEG u,LINESEG v)
 53 {
 54  return ((intersect(u,v))&&
 55    (!online(u,v.s))&&
 56    (!online(u,v.e))&&
 57    (!online(v,u.e))&&
 58    (!online(v,u.s)));
 59 }
 60 bool intersect_l(LINESEG u,LINESEG v)
 61 {
 62  return multiply(u.s,v.e,v.s)*multiply(v.e,u.e,v.s)>=wc;
 63 }
 64 bool zero(double x)
 65 {
 66     return fabs(x)<wc?true:false;
 67 }
 68 double fork_mul(Vector a,Vector b) //向量叉积
 69 {
 70     return (a.x*b.y-a.y*b.x);
 71 }
 72 int intersect_sign(LINESEG l1,LINESEG l2,POINT &result) //两线段位置关系的标志
 73 {
 74     POINT a,b,c,d;
 75     a = l1.e;
 76     b = l1.s;
 77     c = l2.e;
 78     d = l2.s;
 79     double cba=fork_mul(b-c,a-c),dba=fork_mul(b-d,a-d),v12=fork_mul(b-a,d-c);
 80     if(zero(v12)==true) //两线段方向相同
 81     {
 82         if(zero(cba)==true&&zero(dba)==true) //两线段共线
 83         {
 84             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))
 85                 return -3; //重叠共线
 86             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))
 87                 return -2; //分离共线
 88             return -1; //首尾相接
 89         }
 90         else
 91             return 0; //两线段平行
 92     }
 93     else //两线段方向不同,它们各自所在的直线相交
 94     {
 95         double bdc=fork_mul(d-b,c-b),adc=fork_mul(d-a,c-a);
 96         result.x=(dba*c.x-cba*d.x)/(dba-cba); //求两线段所在直线的交点
 97         result.y=(dba*c.y-cba*d.y)/(dba-cba);
 98         if(dba*cba<=0&&bdc*adc<=0)
 99             return 1; //线段相交
100         else
101             return 2; //线段不相交
102     }
103 }
104 
105 int vis[100000+50];
106 int main()
107 {
108        // freopen("out.txt","w",stdout);
109         int n;
110         cin>>n;
111         while(n--){
112                 LINESEG l;
113                 LINESEG a,b,c,d;
114                 double x1,x2,y1,y2;
115                 scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&l.e.x,&l.e.y,&l.s.x,&l.s.y,&x1,&y1,&x2,&y2);
116                 if(x1>x2) swap(x1,x2);
117                 if(y1<y2) swap(y1,y2);
118                 a.e.x = d.s.x = x1;
119                 a.e.y = d.s.y = y1;
120                 a.s.x = b.e.x = x2;
121                 a.s.y = b.e.y = y1;
122                 b.s.x = c.e.x = x2;
123                 b.s.y = c.e.y = y2;
124                 c.s.x = d.e.x = x1;
125                 c.s.y = d.e.y = y2;
126                 POINT p;
127                 if(intersect_sign(l,a,p)==1||intersect_sign(l,a,p)==-3||//intersect_sign(l,a,p)==-2||
128                 intersect_sign(l,b,p)==1||intersect_sign(l,b,p)==-3||//intersect_sign(l,b,p)==-2||
129                 intersect_sign(l,c,p)==1||intersect_sign(l,c,p)==-3||//intersect_sign(l,c,p)==-2||
130                 intersect_sign(l,d,p)==1||intersect_sign(l,d,p)==-3//||intersect_sign(l,d,p)==-2
131                 )
132                         puts("T");
133                 else if(l.e.x>=x1&&l.e.x<=x2&&l.e.y>=y2&&l.e.y<=y1&&
134                         l.s.x>=x1&&l.s.x<=x2&&l.s.y>=y2&&l.s.y<=y1
135                 )
136                         puts("T");
137                 else puts("F");
138         }
139 }
View Code

 

posted on 2015-08-21 23:24  小松song  阅读(80)  评论(0)    收藏  举报

导航