【模板】线段相交
1 #include <stdio.h> 2 #include <iostream> 3 #include <math.h> 4 #include <algorithm> 5 using namespace std; 6 struct point 7 { 8 double x,y; 9 }; 10 point a[105][2];//a[i][0]代表第i条线段的头,a[i][1]代表尾 11 double fan(double x,double y) 12 { 13 return x>y?x:y; 14 } 15 16 double fin(double c,double d) 17 { 18 return c<d?c:d; 19 } 20 21 double cnt(point a,point b) 22 { 23 return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)); 24 } 25 26 int is(point a,point b,point c,point d) 27 { 28 if(a.x==b.x&&c.x==d.x) 29 { 30 return 0; 31 } 32 if(a.x==b.x&&c.x!=d.x) 33 { 34 double m1=a.x; 35 double m2=(a.x-c.x)*(d.y-c.y)/(d.x-c.x)+c.y; 36 if(m1<=fan(a.x,b.x)&&m1>=fin(a.x,b.x)&&m2>=fin(a.y,b.y)&&m2<=fan(a.y,b.y)&&m1<=fan(c.x,d.x)&&m1>=fin(c.x,d.x)&&m2>=fin(c.y,d.y)&&m2<=fan(c.y,d.y)) 37 return 1; 38 } 39 if(c.x==d.x&&a.x!=b.x) 40 { 41 double m1=c.x; 42 double m2=a.y+(b.y-a.y)*(c.x-a.x)/(b.x-a.x); 43 if(m1<=fan(a.x,b.x)&&m1>=fin(a.x,b.x)&&m2>=fin(a.y,b.y)&&m2<=fan(a.y,b.y)&&m1<=fan(c.x,d.x)&&m1>=fin(c.x,d.x)&&m2>=fin(c.y,d.y)&&m2<=fan(c.y,d.y)) 44 return 1; 45 } 46 double k1=(b.y-a.y)/(b.x-a.x); 47 double k2=(d.y-c.y)/(d.x-c.x); 48 double m1,m2,x,y; 49 if(k1==k2) return 0; 50 else 51 { 52 m1=a.y-k1*a.x; 53 m2=c.y-k2*c.x; 54 x=(m1-m2)/(k2-k1); 55 y=k1*x+m1; 56 if(x<=fan(a.x,b.x)&&x>=fin(a.x,b.x)&&y>=fin(a.y,b.y)&&y<=fan(a.y,b.y)&&x<=fan(c.x,d.x)&&x>=fin(c.x,d.x)&&y>=fin(c.y,d.y)&&y<=fan(c.y,d.y)) 57 return 1; 58 } 59 return 0; 60 } 61 62 int main() 63 { 64 int cas = 1; 65 int n,i,j; 66 while(~scanf("%d",&n),n) 67 { 68 int cnt = 0; 69 for(i = 0;i<n;i++) 70 scanf("%lf%lf%lf%lf",&a[i][0].x,&a[i][0].y,&a[i][1].x,&a[i][1].y);//线段的首尾坐标 71 for(i = 0;i<n;i++) 72 { 73 for(j = i+1;j<n;j++) 74 { 75 if(is(a[i][0],a[i][1],a[j][0],a[j][1])) 76 cnt++; 77 } 78 } 79 printf("%d\n",cnt); 80 } 81 return 0; 82 }
时间: 2024-10-14 11:13:12