zoukankan      html  css  js  c++  java
  • 判断两线段是否相交

    今日集训第一日,遇到了判断线段相交问题。跟面积问题一样,这个同样可以用叉积来解决。

    数学原理证明:

    首先引出计算几何学中一个最基本的问题:如何判断向量的顺时针方向还是逆时针方向?

    把p0定为原点,p1的坐标是(x1,y1),p2的坐标是(x2,y2)。向量的叉积(cross product)实际上就是矩阵的行列式:

    代码实现:

    1 int direction(Point p0, Point p1, Point p2) {
    2     int px02 = p2.x - p0.x;
    3     int py02 = p2.y - p0.y;
    4     int px01 = p1.x - p0.x;
    5     int py01 = p1.x - p0.y;
    6     return px01 * py02 - py01 * px02;
    7 }

    当叉积为正时,说明的顺时针方向上;叉积为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。只要满足如下条件:

     1 bool on_segment(Point p0, Point p1, Point p2) {
     2     int minx, maxx, miny, maxy;
     3     minx = min(p0.x, p1.x);
     4     maxx = max(p0.x, p1.x);
     5     miny = min(p0.y, p1.y);
     6     maxy = max(p0.y, p1.y);
     7     if (p2.x >= minx && p2.x <= maxx && p2.y >= miny && p2.y <= maxy)
     8         return true;
     9     else
    10         return false;
    11 }

    就可以判断此端点在线段上。

    由此,我们可以得出判断部分代码。

    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

  • 相关阅读:
    聊聊豆瓣阅读kindle版..顺便悼念一下library.nu…
    PhoneGap+jQm webapp本地化(1)环境搭建以及资源介绍
    尝试分析Q群作为技术群是个不恰当的选择!
    某android平板项目开发笔记计划任务备份
    android 自动化测试的傻瓜实践之旅(UI篇) 小试身手
    latex/Xelatex书籍排版总结顺便附上一本排好的6寸android书…
    某android平板项目开发笔记自定义sharepreference UI
    android ORM框架的性能简单测试(androrm vs ormlite)
    网络管理员必学手册
    PPT插入FLV视频文件的简单方法
  • 原文地址:https://www.cnblogs.com/slimjerk/p/3832738.html
Copyright © 2011-2022 走看看