判断两线段是否相交
2014-07-09 00:08
274 查看
今日集训第一日,遇到了判断线段相交问题。跟面积问题一样,这个同样可以用叉积来解决。
数学原理证明:
首先引出计算几何学中一个最基本的问题:如何判断向量
在
的顺时针方向还是逆时针方向?
把p0定为原点,p1的坐标是(x1,y1),p2的坐标是(x2,y2)。向量的叉积(cross product)实际上就是矩阵的行列式:
代码实现:
当叉积为正时,说明
在
的顺时针方向上;叉积为0说明两向量共线(同向或反向)。
当同时满足:
(1)
和
在
的两侧(即一个顺时针方向上,一个在逆时针方向上)
(2)
和
在
的两侧
时可肯定
和
相交。
图1
图1是线段相交的一般情形。
图2只满足第(1)条,不满足第(2)条所以不能证明
和
相交。
图2
图3和图4是一种特殊情况,它不满足第(2)条,因为
和
重合,即
和
的叉积为0。
可见当叉积为0时要分情况讨论,当p3在线段p1p2上时两线段相交;当p3在线段p1p2的延长线上时两线段不相交。
证明部分转自:博客园(华夏35度)http://www.cnblogs.com/zhangchaoyang 作者:Orisun
在我自己学习与做题过程中,发现主要要注意的是关注当一线段的端点落在另一线段上的情况要特殊讨论。
此时叉积为0。只要满足如下条件:
就可以判断此端点在线段上。
由此,我们可以得出判断部分代码。
Vane_Tse On the Road. 2014-07-09 00:08:27
数学原理证明:
首先引出计算几何学中一个最基本的问题:如何判断向量
在
的顺时针方向还是逆时针方向?
把p0定为原点,p1的坐标是(x1,y1),p2的坐标是(x2,y2)。向量的叉积(cross product)实际上就是矩阵的行列式:
代码实现:
int direction(Point p0, Point p1, Point p2) { int px02 = p2.x - p0.x; int py02 = p2.y - p0.y; int px01 = p1.x - p0.x; int py01 = p1.x - p0.y; return px01 * py02 - py01 * px02; }
当叉积为正时,说明
在
的顺时针方向上;叉积为0说明两向量共线(同向或反向)。
当同时满足:
(1)
和
在
的两侧(即一个顺时针方向上,一个在逆时针方向上)
(2)
和
在
的两侧
时可肯定
和
相交。
图1
图1是线段相交的一般情形。
图2只满足第(1)条,不满足第(2)条所以不能证明
和
相交。
图2
图3和图4是一种特殊情况,它不满足第(2)条,因为
和
重合,即
和
的叉积为0。
可见当叉积为0时要分情况讨论,当p3在线段p1p2上时两线段相交;当p3在线段p1p2的延长线上时两线段不相交。
证明部分转自:博客园(华夏35度)http://www.cnblogs.com/zhangchaoyang 作者:Orisun
在我自己学习与做题过程中,发现主要要注意的是关注当一线段的端点落在另一线段上的情况要特殊讨论。
此时叉积为0。只要满足如下条件:
bool on_segment(Point p0, Point p1, Point p2) { int minx, maxx, miny, maxy; minx = min(p0.x, p1.x); maxx = max(p0.x, p1.x); miny = min(p0.y, p1.y); maxy = max(p0.y, p1.y); if (p2.x >= minx && p2.x <= maxx && p2.y >= miny && p2.y <= maxy) return true; else return false; }
就可以判断此端点在线段上。
由此,我们可以得出判断部分代码。
bool segments_intersect(Point p1, Point p2, Point p3, Point p4) { int d1 = direction(p3, p4, p1); int d2 = direction(p3, p4, p2); int d3 = direction(p1, p2, p3); int d4 = direction(p1, p2, p4); if (d1 * d2 < 0 && d3 * d4 < 0) return true; else if (d1 == 0 && on_segment(p3, p4, p1)) return true; else if (d2 == 0 && on_segment(p3, p4, p2)) return true; else if (d3 == 0 && on_segment(p1, p2, p3)) return true; else if (d4 == 0 && on_segment(p1, p2, p4)) return true; else return false; }
Vane_Tse On the Road. 2014-07-09 00:08:27
相关文章推荐
- You can Solve a Geometry Problem too(判断两线段是否相交)
- 计算几何之判断两线段是否相交
- 判断两条线段是否相交
- 判断两条线段是否相交
- Jack Straws(判断线段是否相交 + 并查集)
- poj 1410 Intersection(判断线段是否与实心矩形相交)
- 判断两条线段是否相交
- COJ 1645计算几何:判断线段是否相交
- 使用叉积判断两条线段是否相交
- codeForce-589D Boulevard(判断线段是否相交)
- poj 3304 判断是否存在一条直线与所有线段相交
- hdu 1086 判断两线段是否相交 (线段和直接是否相交)
- Algorithm Design——判断线段是否相交
- 已知两条线段端点,判断是否相交及交点
- POJ 1410 Intersection(判断线段和矩形是否相交)
- nyoj1016德莱联盟【判断两线段是否相交】
- 判断平面上两线段是否相交,顺便解释判断点在直线的位置...
- 判断两条线段是否相交
- POJ_3304_Segments_线段判断是否相交
- 判断直线与线段 是否相交 + 加入误差 故需要判断重点 poj 3304 Segments