2D空间中重叠的线段

时间:2013-06-17 13:35:01

标签: language-agnostic geometry line

我需要找出两条线是否相互重叠。如果两条线是并行的,我有一个返回0的交叉码。但后来我需要知道这两条平行线是否重叠。

修改

A                    C       B                D
-----------------------------------------------

第1行:A-B

第2行:C-D

我需要找出第1行是否与第2行重叠,但两行都可以有一个斜率> 0

9 个答案:

答案 0 :(得分:12)

您可以比较以查找是否没有重叠。你将以这种方式进行较少的比较,因此效率很高。进行以下比较

D<甲

B< ç

如果两种情况都为真,则线条不重叠。否则必须有重叠。 您将进行最少数量的比较以确定它们是否不重叠。否则会有更多的比较。

答案 1 :(得分:1)

由于您知道它们都是平行的,因此只需检查线段CD是否包含第一行(A点和B点)的任一端点。

答案 2 :(得分:1)

对于两个不一定是轴对齐的共线线段:

  1. 对原点周围的clockwise order中的顶点进行排序。
  2. 如果有序顶点在两个段之间交替,则行重叠,例如, Line1.Point1,Line2.Point1,Line1.Point2,Line2.Point2。

答案 3 :(得分:1)

计算三角形ACB和CBD的面积就足够了。如果该区域为0,则这些点是共线的,如果两个区域都为零,则这些线重叠。

您可以通过以下公式计算三角形ABC的面积:

2 *面积(ABC)=(bx - ax)(cy - ay) - (cx - ax)(by - ay);

答案 4 :(得分:1)

线方程是无限的线方向,通过找到斜率或截距你不能用它们做任何事情(即使水平线没有斜率),我建议使用点在线。 所以AB是你的线[(x,y),(x,y)]而C是点(x,y)的开,然后你需要检查线上是否有点。
Check Point On a Line

答案 5 :(得分:0)

我们有两个线段

  

AB =从(A x ,A y )到(B x ,B y 的线段)
  CD =从(C x ,C y )到(D x ,D y )的线段

具有相同的斜率。

  • 订购端点E 1 < E 2 < E 3 < E 4 使得E i,x ≤E i + 1,x 和E i,y ≤E i + 1,y 如果E i,x = E i + 1,x
  • 如果E 1 且E 2 来自不同的段,则重叠是从E 2 到E 3的段< /子>

有一些堕落的案例:

  • A&lt; B = C&lt; d
  • A&lt; C = D&lt;乙
  • A&lt; B = C = D
  • A = B = C = D

这导致单点交叉。我不确定你的系统中是否会出现这些问题,但如果是这样,你必须决定是否考虑“重叠”并添加特殊案例检查。

答案 6 :(得分:0)

在同一行中的两个片段的特征称为共线性,并且可以测试计算由一个片段端点和另一个片段的端点形成的2个三角形的面积。如果该区域为零或接近于低于阈值的零,则这些段是共线的。

    public static bool AreSegmentsCollinear(Segment a, Segment b, double epsilon)
    {
        return IsPointCollinear(a, b.Left, epsilon) && IsPointCollinear(a, b.Right, epsilon);
    }

    public static bool IsPointCollinear(Segment a, Vector2D p, double epsilon)
    {
        return Math.Abs(GetSignedTriangleArea2(a, p)) <= epsilon;
    }

    /// <returns>The squared signed area of the triangle formed with endpoints
    /// of segment a and point p</returns>
    public static double GetSignedTriangleArea2(Segment a, Vector2D p)
    {
        return (p - a.Left) ^ (a.Right - a.Left);
    }

   /// <summary>Cross product of vectors in 2D space. NB: it returns a
   /// magnitude (scalar), not a vector</summary>
   /// <returns>The area of the parallelogram formed with u, v as the edges</returns>
   public static Double operator ^(Vector2D u, Vector2D v)
   {
       return u.X * v.Y - u.Y * v.X;
   }

答案 7 :(得分:0)

请明确一点,因为答案似乎有些混乱,所要提出的问题如下。给定两个2D线段A和B,我如何确定以下两个条件是否成立:

  1. A和B是共线的。
  2. A和B相交。

请注意,这两个问题都涉及公差,即A和B之间的平行程度如何?他们需要重叠多少才能被视为重叠?

我认为,要有效地处理此类公差,最好的算法是将线段视为细矩形,其中矩形的厚度是公差参数t1。令t2为被认为是平行的斜率上的另一个公差参数。然后算法变成

  1. 如果A的斜率与B的斜率不在t2之内,则返回false。为了清晰地处理垂直线,可以将斜率表示为单位向量,并且可以对两个单位向量之间的欧几里德距离是否小于t2进行测试。

  2. 将A和B表示为(非轴对齐)矩形R1和R2。 R1以明显的方式包围A,即,它的长度为length(A) + t1个单位,宽度为t1个单位,其中A为中心,R2类似地包围B。

  3. 确定R1和R2是否相交。通过将每个矩形视为两个三角形的并集并测试A三角形和B三角形的所有组合中的三角形与三角形的相交点,可以相对有效地完成此操作。如果有交叉点,则返回true;否则,返回true。否则返回false。

答案 8 :(得分:0)

使用以下形式l1给出的l2[x1, y1, x2, y2]线,以下python代码将给出具有任意斜率的共线线段的交点。

intersection = line_intersect(l1, l2)
def line_intersect(l1, l2):
    """Find the intersection of two line segments"""
    
    x1, y1, x2, y2 = l1
    x3, y3, x4, y4 = l2
    
    x_inter = component_intersect(x1, x2, x3, x4)
    y_inter = component_intersect(y1, y2, y3, y4)
    
    return math.sqrt(x_inter**2 + y_inter**2)
    
def component_intersect(c1, c2, c3, c4):
    """Calculate intersection in one dimension/component"""
    
    # find left endpoints
    cl1 = min(c1, c2)
    cl2 = min(c3, c4)
    
    # find right endpoints
    cr1 = max(c1, c2)
    cr2 = max(c3, c4)
    
    # find endpoints of intersection
    c_inter_l = max(cl1, cl2)
    c_inter_r = min(cr1, cr2)
    # calcuate intersection
    c_inter = c_inter_r - c_inter_l
    c_inter = max(c_inter, 0)
    
    return c_inter