已知空间三点(x1,y1,z1), (x2,y2,z2),(x3,y3,z3),求圆心(x0, y0, z0)和半径R。
根据圆的特性我们知道,圆心到任意一点的距离都等于半径R,因此我们得到:
用消元法化简:
另外,根据三点共面方程,得到下述行列式:
通过(4)(5)(6)得到:
最终求得圆心:
半径则可以用圆心与任一点求距离得到,下面是C语言写的代码
uint8_t calc_arc_bypoints3(float* points0, float* points1, float* points2, float* center, float* radius)
{
float x1 = points0[0],
x2 = points1[0],
x3 = points2[0];
float y1 = points0[1],
y2 = points1[1],
y3 = points2[1];
float z1 = points0[2],
z2 = points1[2],
z3 = points2[2];
float a1 = (y1 * z2 - y2 * z1 - y1 * z3 + y3 * z1 + y2 * z3 - y3 * z2),
b1 = -(x1 * z2 - x2 * z1 - x1 * z3 + x3 * z1 + x2 * z3 - x3 * z2),
c1 = (x1 * y2 - x2 * y1 - x1 * y3 + x3 * y1 + x2 * y3 - x3 * y2),
d1 = -(x1 * y2 * z3 - x1 * y3 * z2 - x2 * y1 * z3 + x2 * y3 * z1 + x3 * y1 * z2 - x3 * y2 * z1);
float a2 = 2 * (x2 - x1),
b2 = 2 * (y2 - y1),
c2 = 2 * (z2 - z1),
d2 = x1 * x1 + y1 * y1 + z1 * z1 - x2 * x2 - y2 * y2 - z2 * z2;
float a3 = 2 * (x3 - x1),
b3 = 2 * (y3 - y1),
c3 = 2 * (z3 - z1),
d3 = x1 * x1 + y1 * y1 + z1 * z1 - x3 * x3 - y3 * y3 - z3 * z3;
float xyz_dev = a1 * b2 * c3 - a1 * b3 * c2 - a2 * b1 * c3 + a2 * b3 * c1 + a3 * b1 * c2 - a3 * b2 * c1;
if (xyz_dev < 1e-6f)
{
return 0;
}
center[0] = -(b1 * c2 * d3 - b1 * c3 * d2 - b2 * c1 * d3 + b2 * c3 * d1 + b3 * c1 * d2 - b3 * c2 * d1)
/ xyz_dev;
center[1] = (a1 * c2 * d3 - a1 * c3 * d2 - a2 * c1 * d3 + a2 * c3 * d1 + a3 * c1 * d2 - a3 * c2 * d1)
/ xyz_dev;
center[2] = -(a1 * b2 * d3 - a1 * b3 * d2 - a2 * b1 * d3 + a2 * b3 * d1 + a3 * b1 * d2 - a3 * b2 * d1)
/ xyz_dev;
*radius = sqrt(pow((points0[0] - center[0]), 2) + pow((points0[1] - center[1]), 2) + pow((points0[2] - center[2]), 2));
return 1;
}