基于opencv计算二维直线交点

0.根据a(x1,y1),b(x2,y2)求直线方程:

根据两点式(x-x1)/(x2-x1)=(y-y1)/(y2-y1),可知
A=y2-y1 ,B=x1-x2 ,
C=(y1-y2)*x1 + (x2-x1)*y1

//已知
double x1=10,y1=10;
double x2=15,y2=20;
//求直线方程
double A=y2-y1;
double B=x1-x2;
double C=(y1-y2)*x1 + (x2-x1)*y1

1.两条直线叉乘,计算交点

二维向量叉乘公式
a ( x 1 , y 1 ) , b ( x 2 , y 2 ) , 则 a × b = ( x 1 y 2 - x 2 y 1 ) a(x_1,y_1),b(x_2,y_2),则a×b=(x_1y_2-x_2y_1) ax1y1bx2y2a×bx1y2x2y1
假设两直线方程为
F 0 ( x ) = a 0 ∗ x + b 0 ∗ y + c 0 = 0 F 1 ( x ) = a 1 ∗ x + b 1 ∗ y + c 1 = 0 F0(x) = a_0*x + b_0*y + c_0 = 0\\ F1(x) = a_1*x + b_1*y + c_1 = 0 F0(x)=a0x+b0y+c0=0F1(x)=a1x+b1y+c1=0
那么两条直线的交点应该满足
a 0 ∗ x + b 0 ∗ y + c 0 = a 1 ∗ x + b 1 ∗ y + c 1 a_0*x + b_0*y +c_0 = a_1*x + b_1*y + c_1 a0x+b0y+c0=a1x+b1y+c1
由此可推出
x = ( b 0 ∗ c 1 – b 1 ∗ c 0 ) / D y = ( a 1 ∗ c 0 – a 0 ∗ c 1 ) / D D = a 0 ∗ b 1 – a 1 ∗ b 0 x = (b_0*c_1 – b_1*c_0)/D \\ y = (a_1*c_0 – a_0*c_1)/D \\ D = a_0*b_1 – a_1*b_0 x=(b0c1b1c0)/Dy=(a1c0a0c1)/DD=a0b1a1b0 (D为0时,表示两直线平行)
实际上就是叉积应用

//得到直线方程
double A1,B1,C1;
double A2,B2,C2;
double D=(A1*B2-A2*B1);
//计算交点
cv::Point crossPoint;
if(D!=0)
{
	crossPoint.x=(B1*C2-B2*C1)/D;
	crossPoint.Y=(A2*C1-A1*C2)/D;
}

2. 根据两条直线的方向向量,以及直线上的两点计算交点

   double deltaX_X1 = endPoint.x - orgin.x;
   double deltaY_X1 = endPoint.y -orgin.y;
   double deltaX_X2 = endPoint.x - orgin.x;
   double deltaY_X2 = endPoint.y - orgin.y;
   double lineLengthX1 = sqrt(deltaX_X1*deltaX_X1+deltaY_X1*deltaY_X1);
   double lineLengthX2 = sqrt(deltaX_X2*deltaX_X2+deltaY_X2*deltaY_X2);
   X1DirectionVector.push_back(deltaX_X1/lineLengthX1);
   X1DirectionVector.push_back(deltaY_X1/lineLengthX1);
   X2DirectionVector.push_back(deltaX_X2/lineLengthX2);
   X2DirectionVector.push_back(deltaY_X2/lineLengthX2);
//交点计算函数
cv::Point intersectionPointCalculate(std::vector<double> X1DirectionVec,cv::Point point1, std::vector<double> X2DirectionVec,cv::Point point2)
{
    cv::Point crossPoint(9999,9999);
    if((X1DirectionVec.at(0)!=0) && X2DirectionVec.at(0)!=0)
    {
        double ka = X1DirectionVec.at(1)/X1DirectionVec.at(0);
        double kb = X2DirectionVec.at(1)/X2DirectionVec.at(0);
        double x = ((-1)*kb*double(point2.x)+double(point2.y)+ka*double(point1.x)-double(point1.y)) / (ka - kb);
        crossPoint.x = int(x);
        crossPoint.y = ka*(x-double(point1.x))+double(point1.y);
        //std::cout<<"point1: "<<point1<<" point2: "<<point2<<" ka: "<<ka<<" kb "<<kb<<" crossPoint: "<<crossPoint<<std::endl;
    }
    if((X1DirectionVec.at(0)==0) && X2DirectionVec.at(0)==0)
    {
        //std::cout<<"tensioner coordinate calculate error!"<<std::endl;
    }
    if((X1DirectionVec.at(0)==0) && X2DirectionVec.at(0)!=0)
    {
         double kb = X2DirectionVec.at(1)/X2DirectionVec.at(0);
         crossPoint.x = point1.x;
         crossPoint.y = kb*(crossPoint.x-point2.x)+point2.y;
    }
    if((X1DirectionVec.at(0)!=0) && X2DirectionVec.at(0)==0)
    {
        double ka = X1DirectionVec.at(1)/X1DirectionVec.at(0);
        crossPoint.x = point2.x;
        crossPoint.y = ka*(crossPoint.x-point1.x)+point1.y;
    }
    return crossPoint;
}


  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值