模板 线段相交

【模板】线段相交

 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

模板 线段相交的相关文章

【TOJ 1288】计算几何练习题――线段相交(模板题)

描述 线段相交测试在计算几何中是经常用到的,给定线段P1P2(P1和P2是线段的两端点,且不重合).P3P4(P3和P4是线段的两端点,且不重合),判断P1P2和P3P4是否相交.P1P2和P3P4不重合,即指只存在一个点P,它既落在P1P2上又落在P3P4上(含线段的端点). 输入 输入数据有多组,第一行为测试数据的组数N,下面包括2N行,每组测试数据含2行,第一行为P1P2的坐标值,第二行为P3P4的坐标值,比如下面的数据10 0 1 12 2 3 3表示P1.P2.P3.P4的坐标分别为:

hdu 1086(判断线段相交)

传送门:You can Solve a Geometry Problem too 题意:给n条线段,判断相交的点数. 分析:判断线段相交模板题,快速排斥实验原理就是每条线段代表的向量和该线段的一个端点与 另一条线段的两个端点构成的两个向量求叉积,如果线段相交那么另一条线段两个端点必定在该线段的两边,则该线段代表的向量必定会顺时针转一遍逆时针转一遍,叉积必定会小于等于0,同样对另一条线段这样判断一次即可. #include <algorithm> #include <cstdio>

[51nod1264]线段相交

给定两个点: typedef  struct { double  x, y; } Point; Point A1,A2,B1,B2; 首先引入两个实验: a.快速排斥实验 设以线段A1A2和线段B1B2为对角线的矩形为M,N; 若M,N 不相交,则两个线段显然不相交: 所以:满足第一个条件时:两个线段可能相交. b.跨立实验 如果两线段相交,则两线段必然相互跨立对方.若A1A2跨立B1B2,则矢量( A1 - B1 ) 和(A2-B1)位于矢量(B2-B1)的两侧, 即(A1-B1) × (B2

poj 1269 线段相交/平行

模板题 注意原题中说的线段其实要当成没有端点的直线.被坑了= = 1 #include <cmath> 2 #include <cstdio> 3 #include <iostream> 4 #include <cstring> 5 using namespace std; 6 7 #define eps 1e-8 8 #define PI acos(-1.0)//3.14159265358979323846 9 //判断一个数是否为0,是则返回true,否

poj 1127 Jack Straws 线段相交+并查集

题意: 有n个木棍,给出木棍的两个端点的x,y坐标,判断其中某两个线段是否连通(可通过其他线段连通) #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <vector> #include <queue> #include <map> #include <

POJ 1127 Jack Straws (线段相交)

题意:给定一堆线段,然后有询问,问这两个线段是不是相交,并且如果间接相交也可以. 析:可以用并查集和线段相交来做,也可以用Floyd来做,相交就是一个模板题. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstdlib> #include <cmath> #includ

【POJ 2653】Pick-up sticks 判断线段相交

一定要注意位运算的优先级!!!我被这个卡了好久 判断线段相交模板题. 叉积,点积,规范相交,非规范相交的简单模板 用了“链表”优化之后还是$O(n^2)$的暴力,可是为什么能过$10^5$的数据? #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define N 100005 using namespace std; struct Point { double x

1264 线段相交

1264 线段相交 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 给出平面上两条线段的两个端点,判断这两条线段是否相交(有一个公共点或有部分重合认为相交). 如果相交,输出"Yes",否则输出"No". Input 第1行:一个数T,表示输入的测试数量(1 <= T <= 1000) 第2 - T + 1行:每行8个数,x1,y1,x2,y2,x3,y3,x4,y4.(-10^8 <= xi, yi <= 10

poj 1127 -- Jack Straws(计算几何判断两线段相交 + 并查集)

Jack Straws In the game of Jack Straws, a number of plastic or wooden "straws" are dumped on the table and players try to remove them one-by-one without disturbing the other straws. Here, we are only concerned with if various pairs of straws are