lines计算几何

计算几何基础:

计算几何求线段交点

扫除技术提供了对一组几何物体进行排序的方法

动态数据结构

线段端点每遇到一个端点就检查该点是否是相交点

我们简化问题提出两种假设:这在之后证明计算几何的正确性提供了简化

= == = == == = == = = = = == = = == = == = == == = = == == = == = == = = = =

//ccw函数的顺/逆时针的原理

//stl的complex类

计算几何基础:求线段是否相交,特定线段相交

算法导论的实现。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cmath>
  4 #include <algorithm>
  5 
  6 using namespace std;
  7 #define maxn 15
  8 #define eps 1e-10
  9 
 10 double add(double a,double b)
 11 {
 12     if(abs(a+b)<eps*(abs(a)+abs(b))) return 0;
 13     return a+b;
 14 }
 15 
 16 struct node
 17 {
 18     double x,y;
 19     node(){}
 20     node(double x,double y):x(x),y(y){}
 21     
 22     node operator +(node p){  //求和
 23         return node(add(x,p.x),add(y,p.y));
 24     }
 25     
 26     node operator -(node p){//求差
 27         return node(add(x,-p.x),add(y,-p.y));
 28     }
 29     
 30     node operator *(double d){//平行
 31         return node(x*d,y*d);
 32     }
 33     
 34     double dot(node p){//点积,内积
 35         return add(x*p.x,y*p.y);
 36     }
 37     
 38     double det(node p){//叉积,外积
 39         return add(x*p.y,-y*p.x);
 40     }
 41     
 42 };
 43 
 44 
 45 
 46 int direction(node p1,node p2,node p3)//在顺时针或者逆时针方向。
 47 {
 48     return (p3.operator-(p1)).det((p2.operator-(p1)));
 49 }
 50 
 51 
 52 bool on_segment(node p1,node p2,node p3)
 53 {//是否在线段上
 54     if((min(p1.x,p2.x)<=p3.x && p3.x<=max(p1.x,p2.x)) && (min(p1.y,p2.y)<=p3.y && p3.y<=max(p1.y,p2.y)))
 55         return true;
 56     else return false;
 57 }
 58 
 59 bool segment_interset(node p1,node q1,node p2,node q2)
 60 {//是否相交
 61     int d1=direction(p2,q2,p1);
 62     int d2=direction(p2,q2,q1);
 63     int d3=direction(p1,q1,p2);
 64     int d4=direction(p1,q1,q2);
 65     
 66     if(((d1>0 && d2<0)||(d1<0 && d2>0)) && ((d3>0 && d4<0)|| (d3<0 && d4>0)))
 67         return true;
 68     else if(d1==0 && on_segment(p2,q2,p1))
 69         return true;
 70     else if(d2==0 && on_segment(p2,q2,q1))
 71         return true;
 72     else if(d3==0 && on_segment(p1,q1,p2))
 73         return true;
 74     else if(d4==0 && on_segment(p1,q1,q2))
 75         return true;
 76     else return false;
 77 }
 78 
 79 
 80 node p[maxn],q[maxn];
 81 
 82 int main()
 83 {//效率高= = O(1)
 84     int n,m;
 85     int a,b;
 86     scanf("%d",&n);
 87     for(int i=0;i<n;i++)
 88         scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&q[i].x,&q[i].y);
 89     scanf("%d",&m);
 90     while(m--)
 91     {
 92         scanf("%d%d",&a,&b);
 93         if(segment_interset(p[a-1],q[a-1],p[b-1],q[b-1]))
 94             printf("CONNECTED\n");
 95         else
 96             printf("NOT CONNECTED\n");
 97     }
 98     return 0;
 99     
100 }
View Code

 

极限情况考虑,物体撞击。

1.考虑直接撞上猪,然后在撞上的同时,猪上方的障碍物要保证不相撞。在这条路线中途也不能装上其他的障碍物,考虑以这条路径去走的,在走到某个障碍物时考虑与左侧和右侧的相对位置,然后做判断。

2.考虑不直接撞上猪,在飞的过程中以每个障碍物的左上角或者右上角为极限情况考虑然后考虑在这个飞行过程中到达猪x位置时,y是否大于它,且中途不再撞到障碍物。//😢😢😢= =。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <cmath>
 5 #include <algorithm>
 6 
 7 using namespace std;
 8 
 9 #define eps 1e-10
10 #define maxn 55
11 
12 const double g=9.8;
13 
14 int N,V,X,Y;
15 int L[maxn],B[maxn],R[maxn],T[maxn];
16 
17 
18 double calc(double vy,double t)
19 {
20     return vy*t-g*t*t/2;
21 }
22 
23 int cmp(double lb,double ub,double a)
24 {
25     return a<lb+eps ? -1 : a > ub-eps ? 1:0;
26 }
27 
28 bool check(double qx,double qy)
29 {
30     double a=g*g/4,b=g*qy-V*V,c=qx*qx+qy*qy;
31     
32     double D=b*b-4*a*c;
33     
34     if(D<0 && D>-eps) D=0;
35     if(D<0) return false;
36     
37     for(int d=-1;d<=1;d+=2)
38     {
39         double t2=(-b+d*sqrt(D))/(2*a);
40         if(t2<=0) continue;
41         double t=sqrt(t2);
42         
43         double vx=qx/t,vy=(qy+g*t*t/2)/t;
44         
45         double yt=calc(vy,X/vx);
46         if(yt<Y-eps) continue;
47         
48         bool ok=true;
49         for(int i=0;i<N;i++)
50         {
51             if(L[i]>=X) continue;
52             
53             if(R[i]==X && Y<=T[i] && B[i]<=yt) ok=false;
54             
55             int yL=cmp(B[i],T[i],calc(vy,L[i]/vx));
56             int yR=cmp(B[i],T[i],calc(vy,R[i]/vx));
57             int xH=cmp(L[i],R[i],vx*(vy/g));
58             int yH=cmp(B[i],T[i],calc(vy,vy/g));
59             if(xH==0 && yH>=0 && yL<0) ok=false;
60             if(yL*yR<=0) ok=false;
61         }
62         if(ok) return true;
63     }
64     return false;
65 }
66 
67 void solve()
68 {
69     for(int i=0;i<N;i++)
70     {
71         R[i]=min(R[i],X);
72     }
73     
74     bool ok=check(X,Y);
75     for(int i=0;i<N;i++)
76     {
77         ok|=check(L[i],T[i]);
78         ok|=check(R[i],T[i]);
79     }
80     puts(ok?"Yes":"No");
81 }
82 
83 int main()
84 {
85     scanf("%d%d",&N,&V);
86     scanf("%d%d",&X,&Y);
87     
88     for(int i=0;i<N;i++)
89     {
90         scanf("%d%d%d%d",&L[i],&B[i],&R[i],&T[i]);
91     }
92     solve();
93     return 0;
94 }
View Code

 

 

uva,191

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cmath>
  5 
  6 using namespace std;
  7 #define eps 1e-10
  8 
  9 double add(double a,double b)
 10 {
 11     if(fabs(a+b)<eps*(fabs(a)+fabs(b))) return 0;
 12     return a+b;
 13 }
 14 
 15 struct node
 16 {
 17     double x,y;
 18     
 19     node(){}
 20     node(double x,double y):x(x),y(y){}
 21     
 22     node operator+(node p){
 23         return node(add(x,p.x),add(y,p.y));
 24     }
 25     
 26     node operator-(node p){
 27         return node(add(x,-p.x),add(y,-p.y));
 28     }
 29     
 30     double dot(node p){
 31         return add(x*p.x,y*p.y);
 32     }
 33     
 34     double det(node p){
 35         return add(x*p.y,-y*p.x);
 36     }
 37 };
 38 
 39 int direction(node p1,node p2,node p3)
 40 {
 41     return (p3.operator-(p1)).det(p2.operator-(p1));
 42 }
 43 
 44 bool on_segment(node p1,node p2,node p3)
 45 {
 46     if((min(p1.x,p2.x)<=p3.x && p3.x<=max(p1.x,p2.x)) && (min(p1.y,p2.y)<=p3.y && p3.y<=max(p1.y,p2.y)))
 47         return true;
 48     else
 49         return false;
 50 }
 51 
 52 bool segment_intersect(node p1,node p2,node p3,node p4)
 53 {
 54     int d1=direction(p3,p4,p1);
 55     int d2=direction(p3,p4,p2);
 56     int d3=direction(p1,p2,p3);
 57     int d4=direction(p1,p2,p4);
 58     
 59     if(((d1>0 && d2<0)||(d1<0 && d2>0)) && ((d3>0 && d4<0) || (d3<0 && d4>0)))
 60         return true;
 61     else if(d1==0 && on_segment(p3,p4,p1))
 62         return true;
 63     else if(d2==0 && on_segment(p3,p4,p2))
 64         return true;
 65     else if(d3==0 && on_segment(p1,p2,p3))
 66         return true;
 67     else if(d4==0 && on_segment(p1,p2,p4))
 68         return true;
 69     else return false;
 70 }
 71 
 72 bool isinside(node p1,node p2,node p3)
 73 {
 74     return (p2.x<=p1.x)&&(p2.y>=p1.y)&&(p3.x>=p1.x)&&(p3.y<=p1.y);
 75 }
 76 
 77 int main()
 78 {//方法不错,但是一开始可能那个赋值的算法可能有点错误。
 79     int n;
 80     node a,b,c,d,e,f;
 81     while(~scanf("%d",&n))
 82     while(n--)
 83     {//考虑精度,lf能很好的保证精度的缺失。
 84         scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
 85         scanf("%lf%lf%lf%lf",&e.x,&e.y,&f.x,&f.y);
 86 //很明确的说明了左上角
 87 //很明确的说明了右下角。然后建立线段。
 88         c=node(min(e.x,f.x),max(e.y,f.y));
 89         d=node(max(e.x,f.x),min(e.y,f.y));
 90         if(segment_intersect(a,b,c,node(c.x,d.y)) || segment_intersect(a,b,node(c.x,d.y),d)||
 91            segment_intersect(a,b,c,node(d.x,c.y)) || segment_intersect(a,b,node(d.x,c.y),d))
 92         {
 93             printf("T\n");
 94         }
 95         else if(isinside(a,c,d) || isinside(b,c,d))
 96         {
 97             printf("T\n");
 98         }
 99         else printf("F\n");
100     }
101     return 0;
102     
103 }
View Code

uva,11343

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cmath>
  5 
  6 using namespace std;
  7 #define eps 1e-10
  8 
  9 double add(double a,double b)
 10 {
 11     if(fabs(a+b)<eps*(fabs(a)+fabs(b))) return 0;
 12     return a+b;
 13 }
 14 
 15 struct node
 16 {
 17     double x,y;
 18     
 19     node(){}
 20     node(double x,double y):x(x),y(y){}
 21     
 22     node operator+(node p){
 23         return node(add(x,p.x),add(y,p.y));
 24     }
 25     
 26     node operator-(node p){
 27         return node(add(x,-p.x),add(y,-p.y));
 28     }
 29     
 30     double dot(node p){
 31         return add(x*p.x,y*p.y);
 32     }
 33     
 34     double det(node p){
 35         return add(x*p.y,-y*p.x);
 36     }
 37 };
 38 
 39 int direction(node p1,node p2,node p3)
 40 {
 41     return (p3.operator-(p1)).det(p2.operator-(p1));
 42 }
 43 
 44 bool on_segment(node p1,node p2,node p3)
 45 {
 46     if((min(p1.x,p2.x)<=p3.x && p3.x<=max(p1.x,p2.x)) && (min(p1.y,p2.y)<=p3.y && p3.y<=max(p1.y,p2.y)))
 47         return true;
 48     else
 49         return false;
 50 }
 51 
 52 bool segment_intersect(node p1,node p2,node p3,node p4)
 53 {
 54     int d1=direction(p3,p4,p1);
 55     int d2=direction(p3,p4,p2);
 56     int d3=direction(p1,p2,p3);
 57     int d4=direction(p1,p2,p4);
 58     
 59     if(((d1>0 && d2<0)||(d1<0 && d2>0)) && ((d3>0 && d4<0) || (d3<0 && d4>0)))
 60         return true;
 61     else if(d1==0 && on_segment(p3,p4,p1))
 62         return true;
 63     else if(d2==0 && on_segment(p3,p4,p2))
 64         return true;
 65     else if(d3==0 && on_segment(p1,p2,p3))
 66         return true;
 67     else if(d4==0 && on_segment(p1,p2,p4))
 68         return true;
 69     else return false;
 70 }
 71 
 72 
 73 int main()
 74 {
 75     node p[105],q[105];
 76     int n,m;
 77     scanf("%d",&n);
 78     while(n--)
 79     {
 80         scanf("%d",&m);
 81         for(int i=0;i<m;i++)
 82             scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&q[i].x,&q[i].y);
 83         
 84         int cnt=0;
 85         bool vis[105];
 86         memset(vis,false,sizeof(vis));
 87         for(int i=0;i<m;i++)
 88         {
 89             for(int j=0;j<m;j++)
 90             {
 91                 if(j!=i)
 92                 {
 93                     if(segment_intersect(p[i],q[i],p[j],q[j]))
 94                     {
 95                         vis[i]=true;
 96                         break;
 97                     }
 98                 }
 99             }
100         }
101         
102         for(int i=0;i<m;i++)
103         {
104             if(!vis[i])
105                 cnt++;
106         }
107         printf("%d\n",cnt);
108             
109     }
110     return 0;
111 }
View Code

 uva,378

有时候不需要其他的方法其实你知道的就能做,只是注意精度

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cmath>
 5 
 6 using namespace std;
 7 #define eps 1e-10
 8 int flag;
 9 
10 double add(double a,double b)
11 {
12     if(fabs(a+b)<eps*(fabs(a)+fabs(b))) return 0;
13     return a+b;
14 }
15 
16 struct node
17 {
18     double x,y;
19     
20     node(){}
21     node(double x,double y):x(x),y(y){}
22     
23     node operator+(node p){
24         return node(add(x,p.x),add(y,p.y));
25     }
26     
27     node operator-(node p){
28         return node(add(x,-p.x),add(y,-p.y));
29     }
30     
31     node operator*(double d){
32         return node(x*d,y*d);
33     }
34     
35     double dot(node p){
36         return add(x*p.x,y*p.y);
37     }
38     
39     double det(node p){
40         return add(x*p.y,-y*p.x);
41     }
42 };
43 
44 
45 bool gx(node a,node b,node c)
46 {
47     return (b.operator-(a)).det(c.operator-(a))==0;
48 }
49 
50 node calc(node a,node b,node c,node d)
51 {
52     double A1=d.y-c.y,B1=b.y-a.y,C1=d.x-c.x,D1=b.x-a.x;
53     double A2=(b.operator-(a)).det(d.operator-(c));
54     double D2=(d.operator-(c)).det(b.operator-(a));
55     double B2=d.x-b.x,C2=d.y-b.y;
56     
57     double x=(C1*D1*C2+B1*C1*b.x-(A1*D1*d.x))/D2;
58     double y=(B1*A1*B2+D1*A1*b.y-(C1*B1*d.y))/A2;
59     
60     return node(x,y);
61 }
62 int main()
63 {
64     int n;
65     node a,b,c,d;
66     scanf("%d",&n);
67     puts("INTERSECTING LINES OUTPUT");
68     while(n--)
69     {
70         scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y);
71         if((d.y-c.y)*(b.x-a.x)==(d.x-c.x)*(b.y-a.y))
72         {
73             if(gx(a,b,c))
74             printf("LINE\n");
75             else printf("NONE\n");
76         }
77         else
78             printf("POINT %.2lf %.2lf\n",calc(a,b,c,d).x,calc(a,b,c,d).y);
79     }
80     puts("END OF OUTPUT");
81 }
View Code

 uva,10902

注意到n很大了,如果用每次输入就与前面的所有数比较为O(n*n)的复杂度,肯定超时了。

因为有最上面的管子不会超过1000个这个可以枚举,而且从逆向来看的话又能大大削减复杂度,最后弄一个二分查找,时间复杂度O(n*logn)最坏,有些情况下可能找很少的管子就可以了。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <algorithm>
  4 #include <cmath>
  5 
  6 using namespace std;
  7 #define eps 1e-10
  8 #define maxn 100005
  9 
 10 double add(double a,double b)
 11 {
 12     if(fabs(a+b)<eps*(fabs(a)+fabs(b))) return 0;
 13     return a+b;
 14 }
 15 
 16 struct node
 17 {
 18     double x,y;
 19     int state;
 20     
 21     node(){}
 22     node(double x,double y):x(x),y(y){}
 23     
 24     node operator+(node p){
 25         return node(add(x,p.x),add(y,p.y));
 26     }
 27     
 28     node operator-(node p){
 29         return node(add(x,-p.x),add(y,-p.y));
 30     }
 31     
 32     double dot(node p){
 33         return add(x*p.x,y*p.y);
 34     }
 35     
 36     double det(node p){
 37         return add(x*p.y,-y*p.x);
 38     }
 39 };
 40 
 41 int direction(node p1,node p2,node p3)
 42 {
 43     return (p3.operator-(p1)).det(p2.operator-(p1));
 44 }
 45 
 46 bool on_segment(node p1,node p2,node p3)
 47 {
 48     if((min(p1.x,p2.x)<=p3.x && p3.x<=max(p1.x,p2.x)) && (min(p1.y,p2.y)<=p3.y && p3.y<=max(p1.y,p2.y)))
 49         return true;
 50     else
 51         return false;
 52 }
 53 
 54 bool segment_intersect(node p1,node p2,node p3,node p4)
 55 {
 56     int d1=direction(p3,p4,p1);
 57     int d2=direction(p3,p4,p2);
 58     int d3=direction(p1,p2,p3);
 59     int d4=direction(p1,p2,p4);
 60     
 61     if(((d1>0 && d2<0)||(d1<0 && d2>0)) && ((d3>0 && d4<0) || (d3<0 && d4>0)))
 62         return true;
 63     else if(d1==0 && on_segment(p3,p4,p1))
 64         return true;
 65     else if(d2==0 && on_segment(p3,p4,p2))
 66         return true;
 67     else if(d3==0 && on_segment(p1,p2,p3))
 68         return true;
 69     else if(d4==0 && on_segment(p1,p2,p4))
 70         return true;
 71     else return false;
 72 }
 73 node p[maxn],q[maxn];
 74 int flag1;
 75 
 76 void find(int s,int l,int r)
 77 {
 78     if(l>=r || flag1) return;
 79     if(segment_intersect(p[s],q[s],p[l],q[l]) || segment_intersect(p[s],q[s],p[r],q[r]))
 80         flag1=1;
 81     find(s,l,(l+r)/2);
 82     find(s,((l+r)/2)+1,r);
 83 }
 84 
 85 int main()
 86 {
 87     int n;
 88     while(scanf("%d",&n),n)
 89     {
 90         int cnt=1;
 91         for(int i=0;i<n;i++)
 92         {
 93             p[i].state=q[i].state=1;
 94             scanf("%lf%lf%lf%lf",&p[i].x,&p[i].y,&q[i].x,&q[i].y);
 95         }
 96         
 97         for(int i=n-2;i>=0 && cnt<=1000;i--)
 98         {
 99             flag1=0;
100             find(i,i+1,n-1);
101             if(segment_intersect(p[i],q[i],p[n-1],q[n-1]))
102                 flag1=1;
103             if(flag1)
104                 p[i].state=0;
105             else cnt++;
106         }
107         int flag=0;
108         printf("Top sticks:");
109         for(int i=0;i<n;i++)
110             if(p[i].state)
111             {
112                 if(!flag)
113                 {
114                     printf(" %d",i+1);
115                     flag=1;
116                 }
117                 else
118                 {
119                     printf(", %d",i+1);
120                 }
121             }
122         printf(".\n");
123     }
124     return 0;
125 }
View Code

 

posted @ 2016-05-11 20:11  指尖泛出的繁华  阅读(199)  评论(0)    收藏  举报