Skip to content

Commit 354c44b

Browse files
committed
feat: port Archive.Wiedijk100Theorems.HeronsFormula (#5177)
1 parent 5d8d41f commit 354c44b

File tree

2 files changed

+79
-0
lines changed

2 files changed

+79
-0
lines changed

Archive.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,5 @@ import Archive.Imo.Imo2011Q5
1414
import Archive.Imo.Imo2019Q4
1515
import Archive.Imo.Imo2020Q2
1616
import Archive.Wiedijk100Theorems.AreaOfACircle
17+
import Archive.Wiedijk100Theorems.HeronsFormula
1718
import Archive.Wiedijk100Theorems.InverseTriangleSum
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/-
2+
Copyright (c) 2021 Matt Kempster. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Matt Kempster
5+
6+
! This file was ported from Lean 3 source module wiedijk_100_theorems.herons_formula
7+
! leanprover-community/mathlib commit 5563b1b49e86e135e8c7b556da5ad2f5ff881cad
8+
! Please do not edit these lines, except to modify the commit id
9+
! if you have ported upstream changes.
10+
-/
11+
import Mathlib.Geometry.Euclidean.Triangle
12+
13+
/-!
14+
# Freek № 57: Heron's Formula
15+
16+
This file proves Theorem 57 from the [100 Theorems List](https://www.cs.ru.nl/~freek/100/),
17+
also known as Heron's formula, which gives the area of a triangle based only on its three sides'
18+
lengths.
19+
20+
## References
21+
22+
* https://en.wikipedia.org/wiki/Herons_formula
23+
24+
-/
25+
26+
27+
open Real EuclideanGeometry
28+
29+
open scoped Real EuclideanGeometry
30+
31+
local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue #2220
32+
33+
namespace Theorems100
34+
35+
local notation "√" => Real.sqrt
36+
37+
variable {V : Type _} {P : Type _} [NormedAddCommGroup V] [InnerProductSpace ℝ V] [MetricSpace P]
38+
[NormedAddTorsor V P]
39+
40+
/-- **Heron's formula**: The area of a triangle with side lengths `a`, `b`, and `c` is
41+
`√(s * (s - a) * (s - b) * (s - c))` where `s = (a + b + c) / 2` is the semiperimeter.
42+
We show this by equating this formula to `a * b * sin γ`, where `γ` is the angle opposite
43+
the side `c`.
44+
-/
45+
theorem heron {p1 p2 p3 : P} (h1 : p1 ≠ p2) (h2 : p3 ≠ p2) :
46+
let a := dist p1 p2
47+
let b := dist p3 p2
48+
let c := dist p1 p3
49+
let s := (a + b + c) / 2
50+
1 / 2 * a * b * sin (∠ p1 p2 p3) = √ (s * (s - a) * (s - b) * (s - c)) := by
51+
intro a b c s
52+
let γ := ∠ p1 p2 p3
53+
obtain := (dist_pos.mpr h1).ne', (dist_pos.mpr h2).ne'
54+
have cos_rule : cos γ = (a * a + b * b - c * c) / (2 * a * b) := by
55+
field_simp [mul_comm,
56+
dist_sq_eq_dist_sq_add_dist_sq_sub_two_mul_dist_mul_dist_mul_cos_angle p1 p2 p3]
57+
let numerator := (2 * a * b) ^ 2 - (a * a + b * b - c * c) ^ 2
58+
let denominator := (2 * a * b) ^ 2
59+
have split_to_frac : ↑1 - cos γ ^ 2 = numerator / denominator := by field_simp [cos_rule]
60+
have numerator_nonneg : 0 ≤ numerator := by
61+
have frac_nonneg : 0 ≤ numerator / denominator :=
62+
(sub_nonneg.mpr (cos_sq_le_one γ)).trans_eq split_to_frac
63+
cases' div_nonneg_iff.mp frac_nonneg with h h
64+
· exact h.left
65+
· simpa [h1, h2] using le_antisymm h.right (sq_nonneg _)
66+
have ab2_nonneg : 02 * a * b := by simp [mul_nonneg, dist_nonneg]
67+
calc
68+
1 / 2 * a * b * sin γ = 1 / 2 * a * b * (√ numerator / √ denominator) := by
69+
rw [sin_eq_sqrt_one_sub_cos_sq, split_to_frac, sqrt_div numerator_nonneg] <;>
70+
simp [angle_nonneg, angle_le_pi]
71+
_ = 1 / 4 * √ ((2 * a * b) ^ 2 - (a * a + b * b - c * c) ^ 2) := by
72+
field_simp [ab2_nonneg]; ring
73+
_ = ↑1 / ↑4 * √ (s * (s - a) * (s - b) * (s - c) * ↑4 ^ 2) := by simp only; ring_nf
74+
_ = √ (s * (s - a) * (s - b) * (s - c)) := by
75+
rw [sqrt_mul', sqrt_sq, div_mul_eq_mul_div, one_mul, mul_div_cancel] <;> norm_num
76+
#align theorems_100.heron Theorems100.heron
77+
78+
end Theorems100

0 commit comments

Comments
 (0)