三点求圆,两点一夹角求圆



一:已知两点坐标和两点之间的夹角,求圆点

1:代数推导

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

2:几何推导

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3:代码部分

Matrix 是一个矩阵类,引入了高等数学库方便计算:Eigen

//保存圆的参数
struct _arcConfig{
    
    
    double raio;//保存半径
    QPointF center;//保存圆心
    QPointF center2;//保存圆心2
};

//获取圆的中心和半径,---两点和两点之间的角度 -- 代数推导
_arcConfig GlobleFunction::get_ArcCenter2(QPointF point1,QPointF point2,double rad)
{
    
    
    /* 存在两个解:
     * 解1:
     * (1-cosβ)a + sinβ*b = x2 - x1*cosβ + y1*sinβ
     * sinβ*a + (cosβ-1)b = -y2 + x1*sinβ + y1*cosβ
     * 解2:
     * * (1-cosβ)a + sinβ*b = x1 - x2*cosβ + y2*sinβ
     * sinβ*a + (cosβ-1)b = -y1 + x2*sinβ + y2*cosβ
     * 利用克拉默法则解行列式
     * 求center(a,b)
     *
     */
    QPointF center,center2;
    _arcConfig config;
    Matrix<double,2,2> matD,matD1,matD2,matD3,matD4;
    matD<<(1 - qCos(rad)),qSin(rad),
            qSin(rad),(qCos(rad)-1);

    matD1<<point2.x() - (point1.x()*qCos(rad))+(point1.y()*qSin(rad)) ,  qSin(rad),
            point1.x()*qSin(rad) + point1.y()*qCos(rad) -point2.y() , (qCos(rad)-1);
    matD2<<(1 - qCos(rad )),point2.x() - (point1.x()*qCos(rad))+(point1.y()*qSin(rad)),
            qSin(rad ),point1.x()*qSin(rad) + point1.y()*qCos(rad) -point2.y() ;

    matD3<<point1.x() - (point2.x()*qCos(rad))+(point2.y()*qSin(rad)) ,  qSin(rad),
            point2.x()*qSin(rad) + point2.y()*qCos(rad) -point1.y() , (qCos(rad)-1);
    matD4<<(1 - qCos(rad )),point1.x() - (point2.x()*qCos(rad))+(point2.y()*qSin(rad)),
            qSin(rad ),point2.x()*qSin(rad) + point2.y()*qCos(rad) -point1.y() ;

    double D = matD.determinant();
    double D1 = matD1.determinant();
    double D2 = matD2.determinant();
    double D3 = matD3.determinant();
    double D4 = matD4.determinant();
    center.setX(D1 / D);
    center.setY(D2 / D);
    center2.setX(D3 / D);
    center2.setY(D4 / D);

    double raio = qSqrt(qPow(point1.x()-center.x(),2)+qPow(point1.y()-center.y(),2));

    config.raio =raio;
    config.center = center;
    config.center2 = center2;

    return config;

}
//获取圆的中心和半径,---两点和两点之间的角度 -- 几何推导
_arcConfig GlobleFunction::get_ArcCenter3(QPointF point1,QPointF point2,double rad)
{
    
    
    /* 存在两个解:
     * 解1:
     * x = (x1+x2)/2 + (y1-y2) / 2tan(β/2)
     * y = (y1+y2)/2 + (x2-x1) / 2tan(β/2)
     * 解2:
     * x = (x1+x2)/2 - (y1-y2) / 2tan(β/2)
     * y = (y1+y2)/2 - (x2-x1) / 2tan(β/2)
     *
     * 直接求解
     *
     */
    QPointF center,center2;
    _arcConfig config;


    center.setX((point1.x() + point2.x()) / 2 + (point1.y()-point2.y()) / (2*qTan(rad/2)));
    center.setY((point1.y() + point2.y()) / 2 + (point2.x()-point1.x()) / (2*qTan(rad/2)));

    center2.setX((point1.x() + point2.x()) / 2 - (point1.y()-point2.y()) / (2*qTan(rad/2)));
    center2.setY((point1.y() + point2.y()) / 2 - (point2.x()-point1.x()) / (2*qTan(rad/2)));
    double raio = qSqrt(qPow(point1.x()-center.x(),2)+qPow(point1.y()-center.y(),2));

    config.raio =raio;
    config.center = center;
    config.center2 = center2;

    return config;
}

二:已知三点坐标,求圆点

1:代数推导

在这里插入图片描述

2:代码部分

//获取圆的中心和半径,---三点拟合圆 -- 代数推导
_arcConfig GlobleAlgorithm::get_ArcCenter3(QPointF point1,QPointF point2,QPointF point3)
{
    
    
    /* 存在两个解:
     * 解1:
     * R² = (x - x0)²  + (y - y0)²
     * 展开可得:
     * R² = x² - 2xx0 + x0² + y² - 2yy0 + y0²
     * 即:x0 = a / 2; y0 = b/2
     * 变换后:x² + y² - ax - by + c = 0   ==>    ax + by - c = x² + y²
     * 利用克拉默法则解行列式 求:a, b, c
     * 求center(x0,y0)
     *
     */
    _arcConfig config;
    QPointF center;

    Matrix<double,3,3> matD,matDa,matDb,matDc;
    matD<<point1.x(),point1.y(),-1,
            point2.x(),point2.y(),-1,
            point3.x(),point3.y(),-1;

    matDa<<qPow(point1.x(),2) + qPow(point1.y(),2),point1.y(),-1,
            qPow(point2.x(),2) + qPow(point2.y(),2),point2.y(),-1,
            qPow(point3.x(),2) + qPow(point3.y(),2),point3.y(),-1;
    matDb<<point1.x(),qPow(point1.x(),2) + qPow(point1.y(),2),-1,
            point2.x(),qPow(point2.x(),2) + qPow(point2.y(),2),-1,
            point3.x(),qPow(point3.x(),2) + qPow(point3.y(),2),-1;

    matDc<<point1.x(),point1.y(),qPow(point1.x(),2) + qPow(point1.y(),2),
            point2.x(),point2.y(),qPow(point2.x(),2) + qPow(point2.y(),2),
            point3.x(),point3.y(),qPow(point3.x(),2) + qPow(point3.y(),2);


    //求行列式解
    double D = matD.determinant();
    double Da = matDa.determinant();
    double Db = matDb.determinant();
    double Dc = matDc.determinant();

    double a =Da / D;
    double b =Db / D;
    double c =Dc / D;
    center.setX(a / 2);
    center.setY(b / 2);


    //半径
    double raio = 0.5 * qSqrt(qPow(a,2)+qPow(b,2) - 4*c);

    config.raio =raio;
    config.center = center;

    return config;
}

三:适用场合

相机做旋转标定求圆心
在这里插入图片描述

四:参考文献

克拉默法则求解
行列式计算

猜你喜欢

转载自blog.csdn.net/weixin_43763292/article/details/127839022