1 /**
2 给出线段AB以及线段CD,只要判断A、B两点在直线CD的两端,并且C、D两点在直线AB的两端即可。
3 用叉乘进行判断。
4
5 问题描述
6 下面给出的是一个判断线段相交的次数
7
8 输入:
9 n:线段的个数
10 seg.begin.x,seg.begin.y,seg.end.x,seg.end.y:分别表示线段p1p2的点坐标
11
12 输出:
13 n个线段中两两相交的次数
14
15 样例输入
16 2
17 1 0 0 0
18 0 1 0 0
19 样例输出:
20 1
21 */
22
23 #include<cstdio>
24 using namespace std;
25
26 struct point
27 {
28 double x, y;
29 };
30
31 struct segment
32 {
33 point begin, end;
34 };
35
36 double min(double x, double y)
37 {
38 return (x < y) ? x : y;
39 }
40
41 double max(double x, double y)
42 {
43 return (x > y) ? x : y;
44 }
45
46 //判断pk是否在线段<pi, pj>上
47 bool onsegment(point pi, point pj, point pk)
48 {
49 if(min(pi.x, pj.x) <= pk.x && pk.x <= max(pi.x, pj.x))
50 {
51 if(min(pi.y, pj.y) <= pk.y && pk.y <= max(pi.y, pj.y))
52 {
53 return true;
54 }
55 }
56 return false;
57 }
58
59 //计算向量<pk, pi>与向量<pj, pi>的叉乘
60 double direction(point pi, point pj, point pk)
61 {
62 return (pi.x - pk.x) * (pi.y - pk.y) - (pi.x - pj.x) * (pi.y - pk.y);
63 }
64
65 //判断p1p2以及p3p4是否相交
66 bool judge(point p1, point p2, point p3, point p4)
67 {
68 double d1 = direction(p3, p4, p1);
69 double d2 = direction(p3, p4, p2);
70 double d3 = direction(p1, p2, p3);
71 double d4 = direction(p1, p2, p4);
72
73 if((d1 * d2 < 0) && (d3 * d4 < 0))
74 return true;
75
76 //判断点是否在另一个线段上(包罗万象)
77 if((d1 == 0) && onsegment(p3, p4, p1))
78 return true;
79 if((d2 == 0) && onsegment(p3, p4, p2))
80 return true;
81 if((d3 == 0) && onsegment(p1, p2, p3))
82 return true;
83 if((d4 == 0) && onsegment(p1, p2, p4))
84 return true;
85
86 return false;
87 }
88
89 int main()
90 {
91 int n, count;
92 segment seg[101];
93 while(scanf_s("%d", &n, 1) != EOF && n != 0)
94 {
95 count = 0;
96 for(int i = 1 ; i <= n ; i ++)
97 {
98 scanf_s("%d%d%d%d", &seg[i].begin.x, &seg[i].begin.y, &seg[i].end.x, &seg[i].end.y);
99 }
100
101 for(int i = 1 ; i < n ; i ++)
102 {
103 for(int j = i + 1 ; j <= n ; j ++)
104 {
105 if(judge(seg[i].begin, seg[i].end, seg[j].begin, seg[j].end))
106 count ++;
107 }
108 }
109
110 printf_s("%d\n", count);
111 }
112
113 return 0;
114 }