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;
}