三角形面积与形状判定
面积公式在初中只有一条:底乘高除以二。高不是三角形的原始元素,要么另测,要么由已知的边与角算出来。把「算高」这一步合并进公式,就得到几个只用六个元素的表达式。它们在数学上等价,在浮点下不等价,而分歧之大超出直觉。
1 · 由两边与夹角给出的面积
以 为底,高是 到 的距离。由 余弦定理与边角互化 §1 的坐标摆法, 的纵坐标是 ,这就是高。代入底乘高除以二:
三式由字母轮换给出,用哪一式取决于已知的是哪两条边与哪个夹角。 在 上恒为正,所以不必像余弦定理那样操心符号。
配上正弦定理还能换出两个常用形式。把 换成 得 ;用内切圆半径 与半周长 则有 ,后者的来历是把三角形按内心切成三块,每块以一条边为底、以 为高。
2 · 只由三边给出的面积
三边已知时可以先反解一个角再用 ,但有一条直接的路。在 里把 写成 ,再把余弦定理的 代进去,整理即得海伦公式:
这条公式的形式对称,不需要选定哪个角,代价是四个因子里有三个是减法。、、 接近共线时 这类因子是两个相近数之差,有效数字大量抵消。Kahan 给出的稳定写法把三边降序排成 ,再按
逐括号计算,每个括号都避开了「大数减大数」。第四条路径与边长无关:三个顶点的坐标已知时, 只做两次乘法与一次减法。
3 · 四个算法在细长三角形上的分歧
警示 · 「海伦公式在细长三角形上不稳,改用 Kahan 的排序形式即可」这句常见说法只在一小段上成立。顶点取
、、,精确面积是
,实测:
时海伦的相对误差是 3.97e-7、Kahan 是 1.12e-7,只赢
倍;
时两者只差
ulp,相对误差同为 5.29e-6;
时两者一同给出 0。根源不在面积公式:
时两条腰的舍入值之和恰好等于底边(a + b === c 为真),三角不等式在浮点下已不成立,高度那点信息在算边长时就丢光了。要精度就不要绕道边长,直接用坐标叉积——它在同一组数据上仍给出 0.0005。
这条结论改写了本页原先的叙述。落笔时打算写的是「海伦不稳、Kahan 稳」,实测把前半句保留、后半句推翻:Kahan 的排序形式修的是公式内部的相消,而细长三角形的信息损失发生在公式之前。它仍然值得用(同样的输入不会更差),只是不能当作细长三角形的解药。
4 · 形状判定
面积之外,另一类常见问题是判断形状。钝直锐由最大角定,而最大角必是最大边的对角,所以只需一次符号判断:三边排序为 后看 的正负。等腰与等边则只看边长是否相等。两栏互不排斥,等腰直角三角形同时命中。
例 4.1 三边
、、:
判为直角,两条短边相等判为等腰,故为等腰直角三角形。三边
、、:
判为锐角,三边相等判为等边。三边
、、
不满足严格三角不等式,classify 返回 null 而不是给出一个形状。
「边长相等」的判定同样要走相对容差。用绝对容差时,把整个三角形按同一比例放大一千倍,原本判为等腰的可能就不再等腰了——而形状是相似不变量,不该随尺度改变。classify 里两处容差都以最长边为基准,一处按
、一处按
。
5 · 参考文献
- Heron's formula. Wikipedia. 海伦公式的多种证明与数值稳定版本。https://en.wikipedia.org/wiki/Heron%27s_formula
- Miscalculating Area and Angles of a Needle-like Triangle. W. Kahan. 细长三角形上面积与角度的失稳分析,排序形式的出处。https://people.eecs.berkeley.edu/~wkahan/Triangle.pdf
- Triangle Area. Wolfram MathWorld. 面积的多种表达式,含坐标行列式形式。https://mathworld.wolfram.com/TriangleArea.html
- Loss of significance. Wikipedia. 相近数相减导致有效位抵消的一般机制。https://en.wikipedia.org/wiki/Loss_of_significance
- Numerical stability. Wikipedia. 稳定性的口径,以及「稳定算法」为何不能修复已损的输入。https://en.wikipedia.org/wiki/Numerical_stability