已知a,b,c三点求过这三点的圆心坐标

三点确定圆心算法推导_叉积三点确定圆心算法推导_叉积_02三点确定圆心算法推导_算法_03

确认三点是否共线

叉积计算方式
三点确定圆心算法推导_算法_04
使用叉积判断三个点是否共线
三点确定圆心算法推导_算法_05
带入上方可到的:
三点确定圆心算法推导_算法_06
整合后得到
三点确定圆心算法推导_算法_07
三点确定圆心算法推导_算法_08

不共线的三点才可以确认一个圆

三点求解圆心

已知圆的方程为
三点确定圆心算法推导_叉积_09

假设圆心坐标为三点确定圆心算法推导_叉积_10带入三点可以得到下列方程
三点确定圆心算法推导_算法_11
拆解后可得
三点确定圆心算法推导_算法_12
使用①-②②-③。构造两个方程组
三点确定圆心算法推导_叉积_13

我们可以给计算方程简化一下
三点确定圆心算法推导_叉积_14
则可的方程组
三点确定圆心算法推导_算法_15
使用矩阵求解这个方程组
三点确定圆心算法推导_叉积_16
可得
三点确定圆心算法推导_叉积_17

三点确定圆心算法推导_叉积_18

这样我们就得到了圆心三点确定圆心算法推导_叉积_10的坐标,同时我们也发现了一个很奇特的现象
上面再做共线条判断的时候我们求了叉积
三点确定圆心算法推导_算法_07
而我们求解的a,b的分母我带入后会发现
三点确定圆心算法推导_叉积_21

是不是很玄学hhhhh,有知道原理的大佬欢迎评论区解答。

代码实现

typedef struct _GL2_fPoint {
    float x;
    float y;
} GL2_fPoint;

// 计算通过三点的圆的圆心和半径
bool circle_from_three_points(const GL2_fPoint& p1, const GL2_fPoint& p2, const GL2_fPoint& p3, float& cx, float& cy, float& r) {
    float x1 = p1.x, y1 = p1.y;
    float x2 = p2.x, y2 = p2.y;
    float x3 = p3.x, y3 = p3.y;

    float A = x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2);
    if (std::abs(A) < 1e-6f) {
        return false;
    }

    float B = (x1 * x1 + y1 * y1) * (y3 - y2) + (x2 * x2 + y2 * y2) * (y1 - y3) + (x3 * x3 + y3 * y3) * (y2 - y1);
    float C = (x1 * x1 + y1 * y1) * (x2 - x3) + (x2 * x2 + y2 * y2) * (x3 - x1) + (x3 * x3 + y3 * y3) * (x1 - x2);
    float D = (x1 * x1 + y1 * y1) * (x3 * y2 - x2 * y3) + (x2 * x2 + y2 * y2) * (x1 * y3 - x3 * y1) + (x3 * x3 + y3 * y3) * (x2 * y1 - x1 * y2);

    cx = -B / (2 * A);
    cy = -C / (2 * A);
    r = std::sqrt((x1 - cx) * (x1 - cx) + (y1 - cy) * (y1 - cy));
    
    return true;
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.