判断两线段是否相交
2011-09-21 10:36
183 查看
转自:http://www.cnblogs.com/dxp498688071/archive/2011/3/2.html
几何题做的很少,以至于一个很简单的题目写了很久
若是判断直线和线段是否有交点,把on_segment去掉就可以了
判断两线段是否相交:
我们分两步确定两条线段是否相交:
(1)快速排斥试验
设以线段
P1P2 为对角线的矩形为R, 设以线段 Q1Q2 为对角线的矩形为T,如果R和T不相交,显然两线段不会相交。
(2)跨立试验
如果两线段相交,则两线段必然相互跨立对方。若P1P2跨立Q1Q2 ,则矢量 (P1 - Q1 ) 和(P2 - Q1 )位于矢量(Q2 - Q1 ) 的两侧,即(P1 - Q1 ) × (Q2 - Q1 ) * (P2 - Q1 ) × (Q2 - Q1 ) < 0。上式可改写成(P1 - Q1 ) × (Q2 - Q1 ) * (Q2 - Q1 ) × (P2 - Q1 ) >
0。当 (P1 - Q1 ) × (Q2 - Q1 ) = 0 时,说明 (P1 - Q1 ) 和 (Q2 - Q1 )共线,但是因为已经通过快速排斥试验,所以 P1 一定在线段 Q1Q2上;同理,(Q2 - Q1 ) ×(P2 - Q1 ) = 0 说明 P2 一定在线段 Q1Q2上。所以判断P1P2跨立Q1Q2的依据是:(P1 - Q1 ) × (Q2 - Q1 ) * (Q2 - Q1 ) × (P2 - Q1 ) >= 0。同理判断Q1Q2跨立P1P2的依据是:(Q1 - P1
) × (P2 - P1 ) * (P2 - P1 ) × (Q2 - P1 ) >= 0。具体情况如下图所示:
![](http://pic002.cnblogs.com/images/2011/223801/2011030319452545.jpg)
在相同的原理下,对此算法的具体的实现细节可能会与此有所不同,除了这种过程外,大家也可以参考《算法导论》上的实现。
关于计算几何算法概述网站 http://dev.gameres.com/Program/Abstract/Geometry.htm 一个挺好的网站
view
sourceprint?
几何题做的很少,以至于一个很简单的题目写了很久
若是判断直线和线段是否有交点,把on_segment去掉就可以了
判断两线段是否相交:
我们分两步确定两条线段是否相交:
(1)快速排斥试验
设以线段
P1P2 为对角线的矩形为R, 设以线段 Q1Q2 为对角线的矩形为T,如果R和T不相交,显然两线段不会相交。
(2)跨立试验
如果两线段相交,则两线段必然相互跨立对方。若P1P2跨立Q1Q2 ,则矢量 (P1 - Q1 ) 和(P2 - Q1 )位于矢量(Q2 - Q1 ) 的两侧,即(P1 - Q1 ) × (Q2 - Q1 ) * (P2 - Q1 ) × (Q2 - Q1 ) < 0。上式可改写成(P1 - Q1 ) × (Q2 - Q1 ) * (Q2 - Q1 ) × (P2 - Q1 ) >
0。当 (P1 - Q1 ) × (Q2 - Q1 ) = 0 时,说明 (P1 - Q1 ) 和 (Q2 - Q1 )共线,但是因为已经通过快速排斥试验,所以 P1 一定在线段 Q1Q2上;同理,(Q2 - Q1 ) ×(P2 - Q1 ) = 0 说明 P2 一定在线段 Q1Q2上。所以判断P1P2跨立Q1Q2的依据是:(P1 - Q1 ) × (Q2 - Q1 ) * (Q2 - Q1 ) × (P2 - Q1 ) >= 0。同理判断Q1Q2跨立P1P2的依据是:(Q1 - P1
) × (P2 - P1 ) * (P2 - P1 ) × (Q2 - P1 ) >= 0。具体情况如下图所示:
![](http://pic002.cnblogs.com/images/2011/223801/2011030319452545.jpg)
在相同的原理下,对此算法的具体的实现细节可能会与此有所不同,除了这种过程外,大家也可以参考《算法导论》上的实现。
关于计算几何算法概述网站 http://dev.gameres.com/Program/Abstract/Geometry.htm 一个挺好的网站
view
sourceprint?
01 | #include<stdio.h> |
02 |
03 | struct point |
04 | { |
05 | double x,y; |
06 | }; |
07 |
08 | double direction( point p1,point p2,point p ) |
09 | { |
10 | return ( p1.x -p.x )*(p2.y-p.y) - (p2.x -p.x )*(p1.y-p.y) ; |
11 | } |
12 |
13 | int on_segment( point p1,point p2 ,point p ) |
14 | { |
15 | double max=p1.x > p2.x ? p1.x : p2.x ; |
16 | double min =p1.x < p2.x ? p1.x : p2.x ; |
17 |
18 | if ( p.x >=min && p.x <=max ) |
19 | return 1; |
20 | else |
21 | return 0; |
22 | } |
23 |
24 | int segments_intersert( point p1,point p2,point p3,point p4 ) |
25 | { |
26 | double d1,d2,d3,d4; |
27 | d1 = direction (p1,p2,p3 ); |
28 | d2 = direction (p1,p2,p4 ); |
29 | d3 = direction (p3,p4,p1 ); |
30 | d4 = direction (p3,p4,p2 ); |
31 | if ( d1*d2<0 && d3*d4<0 ) |
32 | return 1; |
33 | else if ( d1==0 && on_segment(p1,p2,p3 ) ) |
34 | return 1; |
35 | else if ( d2==0 && on_segment(p1,p2,p4 ) ) |
36 | return 1; |
37 | else if ( d3==0 && on_segment(p3,p4,p1 ) ) |
38 | return 1; |
39 | else if ( d4==0 && on_segment(p3,p4,p2 ) ) |
40 | return 1; |
41 |
42 | return 0; |
43 | } |
44 |
45 | int main() |
46 | { |
47 | int n,i,j,num; |
48 | point begin[105],end[105]; |
49 |
50 | while ( scanf ( "%d" ,&n) && n!=0 ) |
51 | { |
52 | num=0; |
53 | for ( i=0;i<n;i++) |
54 | { |
55 | scanf ( "%lf %lf %lf %lf" ,&begin[i].x ,&begin[i].y ,&end[i].x ,&end[i].y ); |
56 | } |
57 | for ( i=0;i<n;i++) |
58 | for (j=i+1;j<n;j++) |
59 | { |
60 | if ( |
61 | num++; |
62 | } |
63 | printf ( "%d\n" ,num); |
64 | } |
65 | return 0; |
66 | } |
相关文章推荐
- B 判断两个线段是否相交
- 判断两条线段是否相交
- 判断两条线段是否相交
- POJ 1066 Treasure Hunt 判断两线段是否相交
- 【算法导论】33.2:判断任意两条线段是否相交
- 成都预赛 Polar intersecting line segments 已知N个线段,判断是否相交 排序+划分区间
- 判断两线段是否相交并计算交点坐标
- poj 1127 判断任意两线段是否相交,叉积+floyd(并查集)@
- 已知两条线段端点,判断是否相交及交点
- 模板—判断两条线段是否相交
- GIS 判断两线段是否相交
- pku 1556 The Doors 计算几何 之 叉积判断线段是否相交
- 判断两条线段是否相交
- 计算几何-判断两线段是否相交
- 判断两线段是否相交
- HDU 1086 You can Solve a Geometry Problem too(判断两线段是否相交)跨立实验
- 在线模板_判断线段与圆是否相交
- 判断两线段是否相交
- You can Solve a Geometry Problem too(判断两线段是否相交)
- 线段是否相交的判断方法