用于寻找两个2D四边形交点的C算法?

时间:2012-08-31 14:28:58

标签: c algorithm geometry computational-geometry

我有一个quad类型,定义为:

typedef struct __point {
    float x;
    float y;
} point_t;

typedef struct __quad {
    point_t p1;
    point_t p2;
    point_t p3;
    point_t p4;
} quad_t;

如果我在同一平面上有两个这样的四边形,我希望能够找出这些四边形的交点。例如,如果我们有 quad A quad B ,如果B的任何一个点落在A之外,那么该算法应该产生一个带有点的四边形,如下图所示( A为红色,B为紫色):

Example

编辑的排序不重要因为我稍后会使用这些点构建一个将在A中绘制的四边形。

4 个答案:

答案 0 :(得分:1)

如果这样做的唯一原因是绘制生成的多边形,为什么不使用GPU为你完成工作 - 毕竟你使用的是OpenGL。因此,不要弄乱如何构建交叉点,而是执行以下操作: -

Set Z values of Polygon A and Polygon B to some constant

Set Z test to no testing (always write Z regardless)

Disable Z test
Enable Z writes
Disable colour writes
Render Polygon A

Set Z test to z equal

Enable Z test
Disable Z write
Enable colour write
Render Polygon B

嘿presto,交叉多边形!

如果你将自己局限于OpenGL 4并使用了各种可用的着色器,你可能会更有效率。

答案 1 :(得分:0)

不是完整的实施,但是:

  1. 编写例程以查找两个线段{(1}}

    的交叉点
    intersect_segment
  2. 在四分例程{@ 1}}

    中写一个点
    bool segments_intersect(
        point_t a0, point_t a1,
        point_t b0, point_t b1,
        /*out*/ point_t* intersection
    )
    
  3. point_in_quad应用于每对片段,其中第一段在红色四边形中,第二段在紫色中(总共16次测试)

    bool point_in_quad(point_t p, quad_t q)
    
  4. segments_intersect应用于测试紫色四边形的红色四边形中的每个点:

    point_t temp;
    if(segments_intersect(red.p1, red.p2, purple.p1, purple.p2, &temp)))
        found_point(temp);
    if(segments_intersect(red.p1, red.p2, purple.p2, purple.p3, &temp))
        found_point(temp);
    if(segments_intersect(red.p1, red.p2, purple.p3, purple.p4, &temp))
        found_point(temp);
    
    //10 more
    
    if(segments_intersect(red.p4, red.p1, purple.p2, purple.p3, &temp))
        found_point(temp);
    if(segments_intersect(red.p4, red.p1, purple.p3, purple.p4, &temp))
        found_point(temp);
    if(segments_intersect(red.p4, red.p1, purple.p4, purple.p1, &temp))
        found_point(temp);
    
  5. point_in_quad应用于测试红色四边形的紫色四边形中的每个点:

    if(point_in_quad(red.p1, purple)) found_point(red.p1);
    if(point_in_quad(red.p2, purple)) found_point(red.p2);
    if(point_in_quad(red.p3, purple)) found_point(red.p3);
    if(point_in_quad(red.p4, purple)) found_point(red.p4);
    

答案 2 :(得分:0)

  • 四边形是否保证非自相交?
  • 四边形是否保证是凸的?

如果它们是凸的,那么我相信任何交点都会产生一个多边形,最多有八个顶点。如果它们可能不是凸的,那么最终可能会有两个分开的多边形作为交点。

假设凸,我相信(但尚未验证)结果中的顶点集将是线交点的集合加上另一个中包含的输入四元组的顶点集。然后,交点将是这些顶点的(凸)船体。

此时,只需要有效地获得这些集合。

答案 3 :(得分:0)

对于凸多边形,我建议:

1:检查与separation axes method(快速)

交叉的事实

2:使用O'Rourke book (C code available)

中的算法查找交集