|
| 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 : 0 ≤ 2 * 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