由四个点求两条线段交点代码实现

设已知的一条线段的起点和终点为(x1,y1),(x2,y2),另一条为 (x3,y3),(x4,y4);首先求出两条线段的一次函数,再联立求出交点坐标

交点公式:
x=(y3x4x2-y4x3x2-y3x4x1+y4x3x1-y1x2x4+y2x1x4+y1x2x3-y2x1x3)/x4y2-x4y1-x3y2+x3y1-x2y4+x2y3+x1y4-x1y3

y=(-y3x4y2+y4x3y2+y3x4y1-y4x3y1+y1x2y4-y1x2y3-y2x1y4+y2x1y3)/y4x2-y4x1-y3x2+x1y3-y2x4+y2x3+y1x4-y1x3

代码实现:

CvPoint CrossPoint(const CvPoint line1, const CvPoint line2, const CvPoint line3, const CvPoint line4) //交点
{
    double x_member, x_denominator, y_member, y_denominator;
    CvPoint cross_point;
    x_denominator = line4.x*line2.y - line4.x*line1.y - line3.x*line2.y + line3.x*line1.y 
        - line2.x*line4.y + line2.x*line3.y + line1.x*line4.y - line1.x*line3.y;

    x_member = line3.y*line4.x*line2.x - line4.y*line3.x*line2.x - line3.y*line4.x*line1.x + line4.y*line3.x*line1.x
        - line1.y*line2.x*line4.x + line2.y*line1.x*line4.x + line1.y*line2.x*line3.x - line2.y*line1.x*line3.x;

    if (x_denominator == 0)
        cross_point.x = 0;
    else
        cross_point.x = x_member / x_denominator;

    y_denominator = line4.y*line2.x - line4.y*line1.x - line3.y*line2.x + line1.x*line3.y 
        - line2.y*line4.x + line2.y*line3.x + line1.y*line4.x - line1.y*line3.x;

    y_member = -line3.y*line4.x*line2.y + line4.y*line3.x*line2.y + line3.y*line4.x*line1.y - line4.y*line3.x*line1.y
        + line1.y*line2.x*line4.y - line1.y*line2.x*line3.y - line2.y*line1.x*line4.y + line2.y*line1.x*line3.y;

    if (y_denominator == 0)
        cross_point.y = 0;
    else
        cross_point.y = y_member / y_denominator;

    return cross_point;  //平行返回(0,0)
}
在VB.NET中,如果要判断两条线段是否相交,并且知道这两条线段分别由四个点定义,那么可以首先定义一个方法来确定两个点之间的线段是否相交。线段相交的判断涉及到向量的叉乘以及线段的端点比较。 以下是判断线段相交的逻辑步骤: 1. 首先,我们定义两条线段线段A由点P1和P2定义,线段B由点P3和P4定义。 2. 判断两条线段是否平行或共线,如果平行或共线,则需要额外的逻辑来处理这种情况,因为它们可能重合或者根本不相交。 3. 如果线段不平行,可以使用叉乘来判断线段A上的点是否在B线段的两侧,同理判断线段B上的点是否在A线段的两侧。如果这两个条件都满足,则线段A和线段B相交。 4. 在VB.NET中,可以使用`Math.Sign()`方法来获取叉乘的结果,从而判断点的位置。 以下是一个简单的VB.NET代码示例,用于判断两条线段是否相交: ```vb.net Public Class LineSegment Public P1 As Point Public P2 As Point Public Sub New(p1 As Point, p2 As Point) Me.P1 = p1 Me.P2 = p2 End Sub End Class Public Function DoSegmentsIntersect(line1 As LineSegment, line2 As LineSegment) As Boolean Dim a1 = line1.P1.Y - line1.P2.Y Dim b1 = line1.P2.X - line1.P1.X Dim c1 = a1 * line1.P1.X + b1 * line1.P1.Y Dim a2 = line2.P1.Y - line2.P2.Y Dim b2 = line2.P2.X - line2.P1.X Dim c2 = a2 * line2.P1.X + b2 * line2.P1.Y Dim determinant = a1 * b2 - a2 * b1 ' 线段相交 If determinant <> 0 Then Dim x = (b2 * c1 - b1 * c2) / determinant Dim y = (a1 * c2 - a2 * c1) / determinant ' 确保交点两条线段上 If Math.Min(line1.P1.X, line1.P2.X) <= x <= Math.Max(line1.P1.X, line1.P2.X) AndAlso _ Math.Min(line1.P1.Y, line1.P2.Y) <= y <= Math.Max(line1.P1.Y, line1.P2.Y) AndAlso _ Math.Min(line2.P1.X, line2.P2.X) <= x <= Math.Max(line2.P1.X, line2.P2.X) AndAlso _ Math.Min(line2.P1.Y, line2.P2.Y) <= y <= Math.Max(line2.P1.Y, line2.P2.Y) Then Return True End If ' 线段重合或共线(可能相交或不相交) ElseIf a1 * b2 = a2 * b1 Then ' 这里需要额外的逻辑来处理平行或共线的情况 End If Return False End Function ``` 注意:上述代码是一个简化的示例,没有处理所有可能的边界情况,例如端点相交的情况。在实际应用中,还需要考虑这些情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值