C语言基于海伦公式半角正切实现三角形坐标计算面积周长及角度
问题分析与修复方案
核心错误梳理
- 公式参数混用:海伦半角正切公式要求输入半周长
s,你的注释和代码中错误替换为了面积P,这是计算结果异常的核心原因。 - 定义域越界风险来源:
- 输入三点共线时,面积为0,且半周长减边长的结果为0,会出现除以0、根号入参为0/负数的问题
- 浮点计算误差可能导致半周长减边长的结果出现极小负数,触发
sqrt函数非法入参报错
修复要点
- 半角正切公式的参数换回半周长
s - 新增三点共线校验:面积小于
1e-6(浮点误差阈值)时直接提示无法构成三角形,终止计算 - 根号内的运算结果加钳位逻辑,所有可能出现负数/0的参数都限制为不小于
1e-12,避免非法运算
修正后代码
#include <stdio.h> #include <math.h> #define PI (4. * atan(1)) #define EPS 1e-12 #define TRIANGLE_EPS 1e-6 int main() { float xa, ya, xb, yb, xc, yc, s, area, a, b, c, x, y, z, alphadeg, alpharad, betadeg, betarad, gammadeg, gammarad; printf("Insert the first point's coordinates (a space should be between the X and Y coordinate):\n"); scanf("%f %f", &xa, &ya); printf("Insert the second point's coordinates (a space should be between the X and Y coordinate):\n"); scanf("%f %f", &xb, &yb); printf("Insert the third point's coordinates (a space should be between the X and Y coordinate):\n"); scanf("%f %f", &xc, &yc); // 计算三边长度 a = sqrt(pow(xa - xb, 2) + pow(ya - yb, 2)); b = sqrt(pow(xa - xc, 2) + pow(ya - yc, 2)); c = sqrt(pow(xb - xc, 2) + pow(yb - yc, 2)); printf("Distance between point 1 and 2: %f\n", a); printf("Distance between point 1 and 3: %f\n", b); printf("Distance between point 2 and 3: %f\n", c); // 半周长 s = (a + b + c) / 2; // 面积 area = sqrt(s * fmax(s - a, EPS) * fmax(s - b, EPS) * fmax(s - c, EPS)); // 校验是否能构成三角形 if (area < TRIANGLE_EPS) { printf("Input points are collinear, cannot form a triangle\n"); return 0; } printf("The area of your triangle is %f\n", area); printf("The perimeter of your triangle is %f\n", a + b + c); // 半角正切计算,参数使用半周长s,加钳位避免非法入参 x = sqrt((fmax(s - b, EPS) * fmax(s - c, EPS)) / (s * fmax(s - a, EPS))); y = sqrt((fmax(s - a, EPS) * fmax(s - c, EPS)) / (s * fmax(s - b, EPS))); z = sqrt((fmax(s - a, EPS) * fmax(s - b, EPS)) / (s * fmax(s - c, EPS))); alpharad = 2 * atan(x); betarad = 2 * atan(y); gammarad = 2 * atan(z); alphadeg = alpharad * 180.0 / PI; betadeg = betarad * 180.0 / PI; gammadeg = gammarad * 180.0 / PI; printf("The value of the alpha angle is %0.3f degrees\n", alphadeg); printf("The value of the beta angle is %0.3f degrees\n", betadeg); printf("The value of the gamma angle is %0.3f degrees\n", gammadeg); printf("Sum of angles in radians: %f = %f\n", PI, alpharad + betarad + gammarad); return 0; }
关键修改说明
- 将面积变量名从
P改为area,避免和半周长混淆,半角公式全部使用半周长s计算,符合数学定义 - 用
fmax函数对所有参与根号、除法运算的参数做钳位,保证不会出现负数和除以0的问题,彻底解决定义域越界 - 新增三点共线校验,提前拦截非法输入
- 优化了角度转换逻辑,复用弧度计算结果转换为角度,可读性更高
内容的提问来源于stack exchange,提问作者Dylikk
相关产品推荐
相关产品推荐

