已知圆弧的起点、终点、凸度 求圆弧的圆心

C#

csharp 复制代码
/// <summary>
/// 根据圆弧起点、终点和凸度(bulge)计算圆心坐标和半径
/// 无任何结构体依赖,纯 double 输入输出
/// </summary>
/// <param name="x1">起点 X</param>
/// <param name="y1">起点 Y</param>
/// <param name="x2">终点 X</param>
/// <param name="y2">终点 Y</param>
/// <param name="bulge">凸度(可正可负)</param>
/// <param name="centerX">输出:圆心 X</param>
/// <param name="centerY">输出:圆心 Y</param>
/// <param name="radius">输出:半径</param>
/// <returns>是否成功(true=成功,false=退化为点或直线)</returns>
public static bool GetArcCenter(
    double x1, double y1,
    double x2, double y2,
    double bulge,
    out double centerX, out double centerY,
    out double radius)
{
    double dx = x2 - x1;
    double dy = y2 - y1;
    double L = Math.Sqrt(dx * dx + dy * dy); // 弦长

    // 起点与终点重合,无法构成圆弧
    if (L < 1e-12)
    {
        centerX = 0;
        centerY = 0;
        radius = 0;
        return false;
    }

    // 矢高 h = (bulge * chord_length) / 2,带符号!
    double h = bulge * L * 0.5;

    // 凸度为0 → 是直线段,不是圆弧
    if (Math.Abs(h) < 1e-12)
    {
        centerX = 0;
        centerY = 0;
        radius = 0;
        return false;
    }

    // 圆心到弦中点的偏移距离 D(沿法线方向)
    double D = (L * L - 4 * h * h) / (8 * h);

    // 弦中点
    double midX = (x1 + x2) * 0.5;
    double midY = (y1 + y2) * 0.5;

    // 单位法向量(垂直于弦,逆时针方向): (-dy, dx) / L
    double nx = -dy / L;
    double ny = dx / L;

    // 圆心 = 中点 + D * 法向量
    centerX = midX + D * nx;
    centerY = midY + D * ny;

    // 半径 = 圆心到起点的距离
    double dxToCenter = centerX - x1;
    double dyToCenter = centerY - y1;
    radius = Math.Sqrt(dxToCenter * dxToCenter + dyToCenter * dyToCenter);

    return true;
}

C++

cpp 复制代码
#include <cmath>

/**
 * @brief 根据圆弧起点、终点和凸度(bulge)计算圆心和半径
 * @param x1 起点 X
 * @param y1 起点 Y
 * @param x2 终点 X
 * @param y2 终点 Y
 * @param bulge 凸度(可正可负)
 * @param centerX 输出:圆心 X
 * @param centerY 输出:圆心 Y
 * @param radius 输出:半径
 * @return bool 成功返回 true,失败(重合点或直线)返回 false
 */
bool GetArcCenter(
    double x1, double y1,
    double x2, double y2,
    double bulge,
    double& centerX, double& centerY,
    double& radius)
{
    double dx = x2 - x1;
    double dy = y2 - y1;
    double L = std::sqrt(dx * dx + dy * dy); // 弦长

    // 起点与终点重合,无法构成圆弧
    if (L < 1e-12)
    {
        centerX = 0.0;
        centerY = 0.0;
        radius = 0.0;
        return false;
    }

    // 矢高 h = (bulge * chord_length) / 2,带符号!
    double h = bulge * L * 0.5;

    // 凸度为0 → 是直线段,不是圆弧
    if (std::abs(h) < 1e-12)
    {
        centerX = 0.0;
        centerY = 0.0;
        radius = 0.0;
        return false;
    }

    // 圆心到弦中点的偏移距离 D(沿法线方向)
    double D = (L * L - 4 * h * h) / (8 * h);

    // 弦中点
    double midX = (x1 + x2) * 0.5;
    double midY = (y1 + y2) * 0.5;

    // 单位法向量(垂直于弦,逆时针方向): (-dy, dx) / L
    double nx = -dy / L;
    double ny = dx / L;

    // 圆心 = 中点 + D * 法向量
    centerX = midX + D * nx;
    centerY = midY + D * ny;

    // 半径 = 圆心到起点的距离
    double dxToCenter = centerX - x1;
    double dyToCenter = centerY - y1;
    radius = std::sqrt(dxToCenter * dxToCenter + dyToCenter * dyToCenter);

    return true;
}
相关推荐
列星随旋9 分钟前
线段树和树状数组的学习
学习·算法
全糖可乐气泡水2 小时前
Codex适配国产信创环境安装部署与技术适配全解析
开发语言·git·python·算法·百度
h_a_o777oah2 小时前
状态机+划分型 DP :深度解析K-划分问题下 DP 状态的转移逻辑(洛谷P2679 P2331 附C++代码)
c++·算法·动态规划·acm·状态机dp·划分型dp·滚动数组优化
05候补工程师2 小时前
从算法理想向工程现实的跨越:SLAM 核心架构、思维误区与 Nav2 实战避坑指南
人工智能·算法·安全·架构·机器人
手写码匠4 小时前
Android 17 适配实战指南:新特性解读、隐私变更与迁移全攻略
人工智能·深度学习·算法·aigc
珊瑚里的鱼4 小时前
leetcode42雨水
算法·leetcode
水木流年追梦4 小时前
大模型入门-大模型的推理策略
开发语言·python·算法·正则表达式·prompt
生成论实验室4 小时前
用事件关系网络重新理解AI(三):激活函数、微调与元学习
人工智能·学习·算法·语言模型·可信计算技术
Narv工程师4 小时前
嵌入式机器人控制器算力评估:从DMIPS到WCET的完整指南
人工智能·算法·机器学习
蒟蒻的贤4 小时前
实训1227
算法