计算几何(三条高线长求三角形面积) - Height to Area - UVA 10522
题意:
给 定 三 角 形 的 三 条 高 的 长 度 , 计 算 三 角 形 的 面 积 。 给定三角形的三条高的长度,计算三角形的面积。 给定三角形的三条高的长度,计算三角形的面积。
输入:
多 组 测 试 数 据 , 多组测试数据, 多组测试数据,
首 行 包 括 一 个 正 整 数 T , 表 示 不 合 法 数 据 的 组 数 , 首行包括一个正整数T,表示不合法数据的组数, 首行包括一个正整数T,表示不合法数据的组数,
当 不 合 法 输 入 的 数 量 达 到 T 时 , 停 止 输 入 。 当不合法输入的数量达到T时,停止输入。 当不合法输入的数量达到T时,停止输入。
每 组 包 括 三 个 浮 点 数 h a , h b , h c , 分 别 表 示 三 条 边 a , b , c 上 对 应 的 高 线 的 长 度 。 每组包括三个浮点数ha,hb,hc,分别表示三条边a,b,c上对应的高线的长度。 每组包括三个浮点数ha,hb,hc,分别表示三条边a,b,c上对应的高线的长度。
输出:
若 有 解 , 输 出 三 角 形 的 面 积 。 小 数 点 后 保 留 三 位 。 若有解,输出三角形的面积。小数点后保留三位。 若有解,输出三角形的面积。小数点后保留三位。
否 则 输 出 : 否则输出: 否则输出:These are invalid inputs!
Sample Input
1
31.573 22.352 63.448
46.300 50.868 86.683
22.005 24.725 22.914
5.710 25.635 32.805
Sample Output
1517.456
2219.941
311.804
These are invalid inputs!
分析:
结论:
设 三 角 形 的 三 条 高 线 长 为 : h a , h b , h c , 则 三 角 形 的 面 积 为 : 设三角形的三条高线长为:ha,hb,hc,则三角形的面积为: 设三角形的三条高线长为:ha,hb,hc,则三角形的面积为:
S △ A B C = 1 ( 1 h a + 1 h b + 1 h c ) ( 1 h a + 1 h b − 1 h c ) ( 1 h a − 1 h b + 1 h c ) ( − 1 h a + 1 h b + 1 h c ) S_{\triangle ABC}=\frac{1}{\sqrt{(\frac{1}{ha}+\frac{1}{hb}+\frac{1}{hc})(\frac{1}{ha}+\frac{1}{hb}-\frac{1}{hc})(\frac{1}{ha}-\frac{1}{hb}+\frac{1}{hc})(-\frac{1}{ha}+\frac{1}{hb}+\frac{1}{hc})}} S△ABC=(ha1+hb1+hc1)(ha1+hb1−hc1)(ha1−hb1+hc1)(−ha1+hb1+hc1)1
简要证明:
计 算 三 角 形 面 积 , 我 们 知 道 已 知 三 条 边 长 a , b , c 时 , 由 海 伦 公 式 可 求 面 积 S 。 计算三角形面积,我们知道已知三条边长a,b,c时,由海伦公式可求面积S。 计算三角形面积,我们知道已知三条边长a,b,c时,由海伦公式可求面积S。
本 题 中 , 已 知 高 线 长 , 我 们 能 够 进 一 步 得 到 边 长 a = S h a , b = S h b , c = S h c 本题中,已知高线长,我们能够进一步得到边长a=\frac{S}{ha},b=\frac{S}{hb},c=\frac{S}{hc} 本题中,已知高线长,我们能够进一步得到边长a=haS,b=hbS,c=hcS
根 据 海 伦 公 式 : 根据海伦公式: 根据海伦公式:
S = p ( p − a ) ( p − b ) ( p − c ) , p = a + b + c 2 , 得 S=\sqrt{p(p-a)(p-b)(p-c)},p=\frac{a+b+c}{2},得 S=p(p−a)(p−b)(p−c),p=2a+b+c,得
S = S 2 ( 1 h a + 1 h b + 1 h c ) ( 1 h a + 1 h b − 1 h c ) ( 1 h a − 1 h b + 1 h c ) ( − 1 h a + 1 h b + 1 h c ) S=S^2\sqrt{(\frac{1}{ha}+\frac{1}{hb}+\frac{1}{hc})(\frac{1}{ha}+\frac{1}{hb}-\frac{1}{hc})(\frac{1}{ha}-\frac{1}{hb}+\frac{1}{hc})(-\frac{1}{ha}+\frac{1}{hb}+\frac{1}{hc})} S=S2(ha1+hb1+hc1)(ha1+hb1−hc1)(ha1−hb1+hc1)(−ha1+hb1+hc1)
即 : 即: 即:
S = 1 ( 1 h a + 1 h b + 1 h c ) ( 1 h a + 1 h b − 1 h c ) ( 1 h a − 1 h b + 1 h c ) ( − 1 h a + 1 h b + 1 h c ) S=\frac{1}{\sqrt{(\frac{1}{ha}+\frac{1}{hb}+\frac{1}{hc})(\frac{1}{ha}+\frac{1}{hb}-\frac{1}{hc})(\frac{1}{ha}-\frac{1}{hb}+\frac{1}{hc})(-\frac{1}{ha}+\frac{1}{hb}+\frac{1}{hc})}} S=(ha1+hb1+hc1)(ha1+hb1−hc1)(ha1−hb1+hc1)(−ha1+hb1+hc1)1
无解情况:
不 满 足 两 边 之 和 大 于 第 三 边 , 即 : 不满足两边之和大于第三边,即: 不满足两边之和大于第三边,即:
b + c ≤ a 或 a + b ≤ c 或 a + c ≤ b b+c\le a或a+b\le c或a+c\le b b+c≤a或a+b≤c或a+c≤b
对 应 到 高 上 为 : 对应到高上为: 对应到高上为:
S h b + S h c ≤ S h a \frac{S}{hb}+\frac{S}{hc}\le \frac{S}{ha} hbS+hcS≤haS
由 于 S > 0 , 我 们 可 以 把 S 约 掉 由于S>0,我们可以把S约掉 由于S>0,我们可以把S约掉
即:
1 h b + 1 h c ≤ 1 h a 或 1 h a + 1 h b ≤ 1 h c 或 1 h a + 1 h c ≤ 1 h b \frac{1}{hb}+\frac{1}{hc}\le \frac{1}{ha}或\frac{1}{ha}+\frac{1}{hb}\le \frac{1}{hc}或\frac{1}{ha}+\frac{1}{hc}\le \frac{1}{hb} hb1+hc1≤ha1或ha1+hb1≤hc1或ha1+hc1≤hb1
代码:
#define _CRT_SECURE_NO_WARNINGS
#include<cstring>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const double eps = 1e-10;
const double pi = acos(-1.0);
int dcmp(double x)
{
if (fabs(x) < eps) return 0;
else return x < 0 ? -1 : 1;
}
int T;
double ha, hb, hc;
double InverseSum(double a, double b, double c)
{
return 1.0 / a + 1.0 / b + 1.0 / c;
}
double area(double ha, double hb, double hc)
{
if (dcmp(ha) <= 0 || dcmp(hb) <= 0 || dcmp(hc) <= 0) return -1;
if (1.0 / ha >= 1.0 / hb + 1.0 / hc
|| 1.0 / hb >= 1.0 / ha + 1.0 / hc
|| 1.0 / hc >= 1.0 / ha + 1.0 / hb) return -1;
double s1 = InverseSum(ha, hb, hc), s2 = InverseSum(ha, hb, -hc),
s3 = InverseSum(ha, -hb, hc), s4 = InverseSum(-ha, hb, hc);
double S = s1*s2*s3*s4;
return sqrt(1.0/S);
}
int main()
{
scanf("%d", &T);
while (T)
{
scanf("%lf%lf%lf", &ha, &hb, &hc);
double res = area(ha, hb, hc);
if (res < 0)
{
T--;
puts("These are invalid inputs!");
}
else printf("%.3lf\n", res);
}
return 0;
}