【问题标题】:Detect if line segment intersects square检测线段是否与正方形相交
【发布时间】:2009-08-30 18:03:15
【问题描述】:

有人对此有简单的算法吗?不需要旋转或任何东西。只是找出由两点组成的线段是否与正方形相交

【问题讨论】:

    标签: objective-c line collision intersection


    【解决方案1】:

    这段代码应该可以解决问题。它检查线与边相交的位置,然后检查是否在正方形的宽度内。返回交集数。

    float CalcY(float xval, float x0, float y0, float x1, float y1)
    {
        if(x1 == x0) return NaN;
        return y0 + (xval - x0)*(y1 - y0)/(x1 - x0);
    }
    
    float CalcX(float yval, float x0, float y0, float x1, float y1)
    {
        if(x1 == x0) return NaN;
        return x0 + (yval - y0)*(y1 - y0)/(x1 - x0);
    }
    
    int LineIntersectsSquare(int x0, int y0, int x1, int y1, int left, int top, int right, int bottom)
    {
        int intersections = 0;
        if(CalcX(bottom, x0, y0, x1, y1) < right && CalcX(bottom, x0, y0, x1, y1) > left  ) intersections++;
        if(CalcX(top   , x0, y0, x1, y1) < right && CalcX(top   , x0, y0, x1, y1) > left  ) intersections++;
        if(CalcY(left  , x0, y0, x1, y1) < top   && CalcY(left  , x0, y0, x1, y1) > bottom) intersections++;
        if(CalcY(right , x0, y0, x1, y1) < top   && CalcY(right , x0, y0, x1, y1) > bottom) intersections++;
        return intersections;
    }
    

    注意:此代码是理论上的,可能不正确,因为它尚未经过测试

    【讨论】:

    • 我认为 CalcX 需要返回 x0 + (yval - y0)*(x1 - x0)/(y1 - y0);
    【解决方案2】:

    你可以通过转换一个向量并计算它穿过的边数来做到这一点。

    如果它穿过的边是偶数,它在物体外面,如果它穿过的边是奇数,它在里面。

    这适用于所有封闭的多边形。

    【讨论】:

    • 但是,问题是直线和矩形是否相交,而不是直线是否包含在矩形中。
    • 在这种情况下,您只需要寻找任何边缘。
    • 首先必须做的事情。最初的问题几乎是问“我如何检查线是否与正方形的任何边缘相交?”。而你刚刚说“寻找任何优势”。
    【解决方案3】:

    这是一种方法:
    - 按 x 坐标对正方形的顶点进行排序
    - 按 x 坐标对线的端点进行排序
    - 计算从线的 minX 端到中间两个(按 x 坐标)正方形顶点中的每一个的角度
    - 计算线的角度
    - 如果线条的角度在可能的角度范围内,您所要做的就是检查长度,即线条的 maxX 端 > 正方形的 minX 顶点

    如果正方形直接面向线条,这可能会中断,在这种情况下,我只需通过检查正方形的第一条边来对其进行特殊处理。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-03-21
      • 1970-01-01
      • 2011-01-04
      • 1970-01-01
      • 2016-03-26
      • 2019-01-24
      • 2014-03-15
      相关资源
      最近更新 更多