[Reserved] determines whether two line segments intersect, the intersection point and seek

First, the schematic diagram.

.Write pictures described here

According to the illustrated, a line a1 represents endpoints and a2, b1 line b represents endpoints and B2. In order to utilize the vector cross product relations, the four ends of the lines as a vector, the vector represented below in bold. The vector operation It found that
A = A2-A1,
. B = B2-B1

line segment parameter equation is expressed as:
A = A1 + TA
B = B1 + UB

wherein the parameters t, u values [0,1]

Intersection of two line segments have the following relationship:
A1 = B1 + TA + UB
will simultaneously on both sides of the cross product of formula b, to give:
(A1 + TA) XB = (B1 + UB) XB
since bxb = 0, can be obtained
a1 xb + taxb = b1 xb
solve for the parameters T
T = (A1-B1) XB / (AXB)
Similarly, solving for the parameter U
U = AX (A1-B1) / (AXB)

When 0 <= t <= 1, and 0 <= u <= 1, two line segments have an intersection.
Substituting a segment of a parameter equation, to obtain a line segment intersection coordinates:
A1 + TA
intermediate variables in the above formula by the original segment end points, said point of intersection can be represented by a line segment according to the endpoint.

code 1

// Returns 1 if the lines intersect, otherwise 0. In addition, if the lines 
// intersect the intersection point may be stored in the floats i_x and i_y.
char get_line_intersection(float p0_x, float p0_y, float p1_x, float p1_y, 
    float p2_x, float p2_y, float p3_x, float p3_y, float *i_x, float *i_y)
{
    float s1_x, s1_y, s2_x, s2_y;
    s1_x = p1_x - p0_x;     s1_y = p1_y - p0_y;
    s2_x = p3_x - p2_x;     s2_y = p3_y - p2_y;

    float s, t;
    s = (-s1_y * (p0_x - p2_x) + s1_x * (p0_y - p2_y)) / (-s2_x * s1_y + s1_x * s2_y);
    t = ( s2_x * (p0_y - p2_y) - s2_y * (p0_x - p2_x)) / (-s2_x * s1_y + s1_x * s2_y);

    if (s >= 0 && s <= 1 && t >= 0 && t <= 1)
    {
        // Collision detected
        if (i_x != NULL)
            *i_x = p0_x + (t * s1_x);
        if (i_y != NULL)
            *i_y = p0_y + (t * s1_y);
        return 1;
    }

    return 0; // No collision
}



code 2

Optimized version, excluding the case of parallel line segments, to avoid the accuracy error

int get_line_intersection(float p0_x, float p0_y, float p1_x, float p1_y, 
    float p2_x, float p2_y, float p3_x, float p3_y, float *i_x, float *i_y)
{
    float s02_x, s02_y, s10_x, s10_y, s32_x, s32_y, s_numer, t_numer, denom, t;
    s10_x = p1_x - p0_x;
    s10_y = p1_y - p0_y;
    s32_x = p3_x - p2_x;
    s32_y = p3_y - p2_y;

    denom = s10_x * s32_y - s32_x * s10_y;
    if (denom == 0)//平行或共线
        return 0; // Collinear
    bool denomPositive = denom > 0;

    s02_x = p0_x - p2_x;
    s02_y = p0_y - p2_y;
    s_numer = s10_x * s02_y - s10_y * s02_x;
    if ((s_numer < 0) == denomPositive)//参数是大于等于0且小于等于1的,分子分母必须同号且分子小于等于分母
        return 0; // No collision

    t_numer = s32_x * s02_y - s32_y * s02_x;
    if ((t_numer < 0) == denomPositive)
        return 0; // No collision

    if (fabs(s_numer) > fabs(denom) || fabs(t_numer) > fabs(denom))
        return 0; // No collision
    // Collision detected
    t = t_numer / denom;
    if (i_x != NULL)
        *i_x = p0_x + (t * s10_x);
    if (i_y != NULL)
        *i_y = p0_y + (t * s10_y);

    return 1;
}



Methods from stack overflow posts: the Geometry - How do you Detect the WHERE TWO Line Segments
INTERSECT? ----------------
Disclaimer: This article is CSDN blogger "Away-Far" in original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
Original link: https: //blog.csdn.net/wcl0617/article/details/78654944

Published 27 original articles · won praise 53 · views 160 000 +

Guess you like

Origin blog.csdn.net/auspi12341/article/details/103514241