根据空间三点求圆心坐标和半径

        已知空间三点(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;
}

 


 

以下是空间三点外接球圆心坐标半径的 Lua 代码: ```lua -- 计算向量长度 function length(v) return math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z) end -- 计算向量点积 function dot(v1, v2) return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z end -- 计算向量叉积 function cross(v1, v2) return { x = v1.y * v2.z - v1.z * v2.y, y = v1.z * v2.x - v1.x * v2.z, z = v1.x * v2.y - v1.y * v2.x } end -- 计算三点外接球圆心坐标半径 function calc_circumsphere(p1, p2, p3) -- 计算向量 v1, v2, v3 local v1 = { x = p2.x - p1.x, y = p2.y - p1.y, z = p2.z - p1.z } local v2 = { x = p3.x - p1.x, y = p3.y - p1.y, z = p3.z - p1.z } local v3 = cross(v1, v2) -- 计算向量长度 local len_v1 = length(v1) local len_v2 = length(v2) local len_v3 = length(v3) -- 计算半径 local r = (len_v1 * len_v2 * len_v3) / (2 * math.abs(dot(v3, v3))) -- 计算圆心坐标 local x = p1.x + (v1.x * (len_v2 * len_v2 + len_v3 * len_v3 - len_v1 * len_v1) + v2.x * (len_v1 * len_v1 + len_v3 * len_v3 - len_v2 * len_v2) + v3.x * (len_v1 * len_v1 + len_v2 * len_v2 - len_v3 * len_v3)) / (2 * dot(v1, cross(v2, v3))) local y = p1.y + (v1.y * (len_v2 * len_v2 + len_v3 * len_v3 - len_v1 * len_v1) + v2.y * (len_v1 * len_v1 + len_v3 * len_v3 - len_v2 * len_v2) + v3.y * (len_v1 * len_v1 + len_v2 * len_v2 - len_v3 * len_v3)) / (2 * dot(v1, cross(v2, v3))) local z = p1.z + (v1.z * (len_v2 * len_v2 + len_v3 * len_v3 - len_v1 * len_v1) + v2.z * (len_v1 * len_v1 + len_v3 * len_v3 - len_v2 * len_v2) + v3.z * (len_v1 * len_v1 + len_v2 * len_v2 - len_v3 * len_v3)) / (2 * dot(v1, cross(v2, v3))) return x, y, z, r end -- 测试 local p1 = {x = 0, y = 0, z = 0} local p2 = {x = 1, y = 0, z = 0} local p3 = {x = 0, y = 1, z = 0} local x, y, z, r = calc_circumsphere(p1, p2, p3) print("圆心坐标:", x, y, z) print("半径:", r) ``` 你可以将三个点的坐标分别赋值给 `p1`、`p2`、`p3`,然后调用 `calc_circumsphere` 函数计算出外接球的圆心坐标半径。注意,这里假设三个点不在同一条直线上。如果三个点在同一条直线上,则无法计算出外接球。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值