Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit ea9cd02

Browse files
committed
refactor(geometry/euclidean/basic): adjust Euclidean geometry to use affine isometries for reflections (#8662)
1 parent a9c1300 commit ea9cd02

File tree

3 files changed

+113
-46
lines changed

3 files changed

+113
-46
lines changed

src/analysis/normed_space/inner_product.lean

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,6 +1087,14 @@ begin
10871087
linarith }
10881088
end
10891089

1090+
/-- Given two orthogonal vectors, their sum and difference have equal norms. -/
1091+
lemma norm_sub_eq_norm_add {v w : E} (h : ⟪v, w⟫ = 0) : ∥w - v∥ = ∥w + v∥ :=
1092+
begin
1093+
rw ←mul_self_inj_of_nonneg (norm_nonneg _) (norm_nonneg _),
1094+
simp [h, ←inner_self_eq_norm_sq, inner_add_left, inner_add_right, inner_sub_left,
1095+
inner_sub_right, inner_re_symm]
1096+
end
1097+
10901098
/-- The real inner product of two vectors, divided by the product of their
10911099
norms, has absolute value at most 1. -/
10921100
lemma abs_real_inner_div_norm_mul_norm_le_one (x y : F) : absR (⟪x, y⟫_ℝ / (∥x∥ * ∥y∥)) ≤ 1 :=
@@ -2255,6 +2263,49 @@ by { rw ← smul_orthogonal_projection_singleton 𝕜 w, simp [hv] }
22552263

22562264
end orthogonal_projection
22572265

2266+
section reflection
2267+
variables {𝕜} (K) [complete_space K]
2268+
2269+
/-- Reflection in a complete subspace of an inner product space. The word "reflection" is
2270+
sometimes understood to mean specifically reflection in a codimension-one subspace, and sometimes
2271+
more generally to cover operations such as reflection in a point. The definition here, of
2272+
reflection in a subspace, is a more general sense of the word that includes both those common
2273+
cases. -/
2274+
def reflection : E ≃ₗᵢ[𝕜] E :=
2275+
{ norm_map' := begin
2276+
intros x,
2277+
let w : K := orthogonal_projection K x,
2278+
let v := x - w,
2279+
have : ⟪v, w⟫ = 0 := orthogonal_projection_inner_eq_zero x w w.2,
2280+
convert norm_sub_eq_norm_add this using 2,
2281+
{ simp [bit0],
2282+
dsimp [w, v],
2283+
abel },
2284+
{ simp [bit0] }
2285+
end,
2286+
..linear_equiv.of_involutive
2287+
(bit0 (K.subtype.comp (orthogonal_projection K).to_linear_map) - linear_map.id)
2288+
(λ x, by simp [bit0]) }
2289+
2290+
variables {K}
2291+
2292+
/-- The result of reflecting. -/
2293+
lemma reflection_apply (p : E) : reflection K p = bit0 ↑(orthogonal_projection K p) - p := rfl
2294+
2295+
/-- Reflection is its own inverse. -/
2296+
@[simp] lemma reflection_symm : (reflection K).symm = reflection K := rfl
2297+
2298+
variables (K)
2299+
2300+
/-- Reflecting twice in the same subspace. -/
2301+
@[simp] lemma reflection_reflection (p : E) : reflection K (reflection K p) = p :=
2302+
(reflection K).left_inv p
2303+
2304+
/-- Reflection is involutive. -/
2305+
lemma reflection_involutive : function.involutive (reflection K) := reflection_reflection K
2306+
2307+
end reflection
2308+
22582309
/-- The subspace of vectors orthogonal to a given subspace. -/
22592310
def submodule.orthogonal : submodule 𝕜 E :=
22602311
{ carrier := {v | ∀ u ∈ K, ⟪u, v⟫ = 0},

src/geometry/euclidean/basic.lean

Lines changed: 59 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Authors: Joseph Myers, Manuel Candales
55
-/
66
import analysis.special_functions.trigonometric
77
import algebra.quadratic_discriminant
8-
import analysis.normed_space.add_torsor
8+
import analysis.normed_space.affine_isometry
99
import data.matrix.notation
1010
import linear_algebra.affine_space.finite_dimensional
1111
import tactic.fin_cases
@@ -864,6 +864,15 @@ begin
864864
exact hp }
865865
end
866866

867+
@[simp] lemma orthogonal_projection_mem_subspace_eq_self {s : affine_subspace ℝ P} [nonempty s]
868+
[complete_space s.direction] (p : s) :
869+
orthogonal_projection s p = p :=
870+
begin
871+
ext,
872+
rw orthogonal_projection_eq_self_iff,
873+
exact p.2
874+
end
875+
867876
/-- Orthogonal projection is idempotent. -/
868877
@[simp] lemma orthogonal_projection_orthogonal_projection (s : affine_subspace ℝ P) [nonempty s]
869878
[complete_space s.direction] (p : P) :
@@ -911,6 +920,18 @@ lemma vsub_orthogonal_projection_mem_direction_orthogonal (s : affine_subspace
911920
direction_mk' p s.directionᗮ ▸
912921
vsub_mem_direction (self_mem_mk' _ _) (orthogonal_projection_mem_orthogonal s p)
913922

923+
/-- Subtracting the `orthogonal_projection` from `p` produces a result in the kernel of the linear
924+
part of the orthogonal projection. -/
925+
lemma orthogonal_projection_vsub_orthogonal_projection (s : affine_subspace ℝ P) [nonempty s]
926+
[complete_space s.direction] (p : P) :
927+
_root_.orthogonal_projection s.direction (p -ᵥ orthogonal_projection s p) = 0 :=
928+
begin
929+
apply orthogonal_projection_mem_subspace_orthogonal_complement_eq_zero,
930+
intros c hc,
931+
rw [← neg_vsub_eq_vsub_rev, inner_neg_right,
932+
(orthogonal_projection_vsub_mem_direction_orthogonal s p c hc), neg_zero]
933+
end
934+
914935
/-- Adding a vector to a point in the given subspace, then taking the
915936
orthogonal projection, produces the original point if the vector was
916937
in the orthogonal direction. -/
@@ -981,42 +1002,27 @@ and complete. The word "reflection" is sometimes understood to mean
9811002
specifically reflection in a codimension-one subspace, and sometimes
9821003
more generally to cover operations such as reflection in a point. The
9831004
definition here, of reflection in an affine subspace, is a more
984-
general sense of the word that includes both those common cases. If
985-
the subspace is empty or not complete, `orthogonal_projection` is
986-
defined as the identity map, which results in `reflection` being the
987-
identity map in that case as well. -/
1005+
general sense of the word that includes both those common cases. -/
9881006
def reflection (s : affine_subspace ℝ P) [nonempty s] [complete_space s.direction] :
989-
P ≃ᵢ P :=
990-
{ to_fun := λ p, (↑(orthogonal_projection s p) -ᵥ p) +ᵥ orthogonal_projection s p,
991-
inv_fun := λ p, (↑(orthogonal_projection s p) -ᵥ p) +ᵥ orthogonal_projection s p,
992-
left_inv := λ p, by simp [vsub_vadd_eq_vsub_sub, -orthogonal_projection_linear],
993-
right_inv := λ p, by simp [vsub_vadd_eq_vsub_sub, -orthogonal_projection_linear],
994-
isometry_to_fun := begin
995-
dsimp only,
996-
rw isometry_emetric_iff_metric,
997-
intros p₁ p₂,
998-
rw [←mul_self_inj_of_nonneg dist_nonneg dist_nonneg, dist_eq_norm_vsub V
999-
((↑(orthogonal_projection s p₁) -ᵥ p₁) +ᵥ ↑(orthogonal_projection s p₁)),
1000-
dist_eq_norm_vsub V p₁, ←inner_self_eq_norm_sq, ←inner_self_eq_norm_sq],
1001-
calc
1002-
⟪((orthogonal_projection s p₁ : P) -ᵥ p₁ +ᵥ (orthogonal_projection s p₁ : P) -ᵥ
1003-
((orthogonal_projection s p₂ : P) -ᵥ p₂ +ᵥ orthogonal_projection s p₂)),
1004-
((orthogonal_projection s p₁ : P) -ᵥ p₁ +ᵥ (orthogonal_projection s p₁ : P) -ᵥ
1005-
((orthogonal_projection s p₂ : P) -ᵥ p₂ +ᵥ orthogonal_projection s p₂))⟫
1006-
= ⟪(_root_.orthogonal_projection s.direction (p₁ -ᵥ p₂)) +
1007-
_root_.orthogonal_projection s.direction (p₁ -ᵥ p₂) - (p₁ -ᵥ p₂),
1008-
_root_.orthogonal_projection s.direction (p₁ -ᵥ p₂) +
1009-
_root_.orthogonal_projection s.direction (p₁ -ᵥ p₂) - (p₁ -ᵥ p₂)⟫
1010-
: by { rw [vsub_vadd_eq_vsub_sub, vadd_vsub_assoc, add_comm, add_sub_assoc,
1011-
←vsub_vadd_eq_vsub_sub, vsub_vadd_comm, vsub_vadd_eq_vsub_sub, ←add_sub_assoc, ←coe_vsub,
1012-
←affine_map.linear_map_vsub], simp }
1013-
... = -4 * inner (p₁ -ᵥ p₂ - (_root_.orthogonal_projection s.direction (p₁ -ᵥ p₂) : V))
1014-
(_root_.orthogonal_projection s.direction (p₁ -ᵥ p₂)) +
1015-
⟪p₁ -ᵥ p₂, p₁ -ᵥ p₂⟫
1016-
: by { simp [inner_sub_left, inner_sub_right, inner_add_left, inner_add_right,
1017-
real_inner_comm (p₁ -ᵥ p₂)], ring }
1018-
... = ⟪p₁ -ᵥ p₂, p₁ -ᵥ p₂⟫ : by simp,
1019-
end }
1007+
P ≃ᵃⁱ[ℝ] P :=
1008+
affine_isometry_equiv.mk'
1009+
(λ p, (↑(orthogonal_projection s p) -ᵥ p) +ᵥ orthogonal_projection s p)
1010+
(_root_.reflection s.direction)
1011+
↑(classical.arbitrary s)
1012+
begin
1013+
intros p,
1014+
let v := p -ᵥ ↑(classical.arbitrary s),
1015+
let a : V := _root_.orthogonal_projection s.direction v,
1016+
let b : P := ↑(classical.arbitrary s),
1017+
have key : a +ᵥ b -ᵥ (v +ᵥ b) +ᵥ (a +ᵥ b) = a + a - v +ᵥ (b -ᵥ b +ᵥ b),
1018+
{ rw [← add_vadd, vsub_vadd_eq_vsub_sub, vsub_vadd, vadd_vsub],
1019+
congr' 1,
1020+
abel },
1021+
have : p = v +ᵥ ↑(classical.arbitrary s) := (vsub_vadd p ↑(classical.arbitrary s)).symm,
1022+
simpa only [coe_vadd, reflection_apply, affine_map.map_vadd, orthogonal_projection_linear,
1023+
orthogonal_projection_mem_subspace_eq_self, vadd_vsub, continuous_linear_map.coe_coe,
1024+
continuous_linear_equiv.coe_coe, this] using key,
1025+
end
10201026

10211027
/-- The result of reflecting. -/
10221028
lemma reflection_apply (s : affine_subspace ℝ P) [nonempty s] [complete_space s.direction] (p : P) :
@@ -1028,16 +1034,25 @@ lemma eq_reflection_of_eq_subspace {s s' : affine_subspace ℝ P} [nonempty s]
10281034
(reflection s p : P) = (reflection s' p : P) :=
10291035
by unfreezingI { subst h }
10301036

1031-
/-- Reflection is its own inverse. -/
1032-
@[simp] lemma reflection_symm (s : affine_subspace ℝ P) [nonempty s] [complete_space s.direction] :
1033-
(reflection s).symm = reflection s :=
1034-
rfl
1035-
10361037
/-- Reflecting twice in the same subspace. -/
10371038
@[simp] lemma reflection_reflection (s : affine_subspace ℝ P) [nonempty s]
10381039
[complete_space s.direction] (p : P) :
10391040
reflection s (reflection s p) = p :=
1040-
(reflection s).left_inv p
1041+
begin
1042+
have : ∀ a : s, ∀ b : V, (_root_.orthogonal_projection s.direction) b = 0
1043+
→ reflection s (reflection s (b +ᵥ a)) = b +ᵥ a,
1044+
{ intros a b h,
1045+
have : (a:P) -ᵥ (b +ᵥ a) = - b,
1046+
{ rw [vsub_vadd_eq_vsub_sub, vsub_self, zero_sub] },
1047+
simp [reflection, h, this] },
1048+
rw ← vsub_vadd p (orthogonal_projection s p),
1049+
exact this (orthogonal_projection s p) _ (orthogonal_projection_vsub_orthogonal_projection s p),
1050+
end
1051+
1052+
/-- Reflection is its own inverse. -/
1053+
@[simp] lemma reflection_symm (s : affine_subspace ℝ P) [nonempty s] [complete_space s.direction] :
1054+
(reflection s).symm = reflection s :=
1055+
by { ext, rw ← (reflection s).injective.eq_iff, simp }
10411056

10421057
/-- Reflection is involutive. -/
10431058
lemma reflection_involutive (s : affine_subspace ℝ P) [nonempty s] [complete_space s.direction] :
@@ -1088,7 +1103,7 @@ lemma dist_reflection (s : affine_subspace ℝ P) [nonempty s] [complete_space s
10881103
dist p₁ (reflection s p₂) = dist (reflection s p₁) p₂ :=
10891104
begin
10901105
conv_lhs { rw ←reflection_reflection s p₁ },
1091-
exact (reflection s).dist_eq _ _
1106+
exact (reflection s).dist_map _ _
10921107
end
10931108

10941109
/-- A point in the subspace is equidistant from another point and its
@@ -1098,7 +1113,7 @@ lemma dist_reflection_eq_of_mem (s : affine_subspace ℝ P) [nonempty s] [comple
10981113
dist p₁ (reflection s p₂) = dist p₁ p₂ :=
10991114
begin
11001115
rw ←reflection_eq_self_iff p₁ at hp₁,
1101-
convert (reflection s).dist_eq p₁ p₂,
1116+
convert (reflection s).dist_map p₁ p₂,
11021117
rw hp₁
11031118
end
11041119

src/geometry/euclidean/circumcenter.lean

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -642,8 +642,9 @@ begin
642642
= ↑(orthogonal_projection (affine_span ℝ (set.range (s.face hc).points)) s.circumcenter),
643643
{ apply eq_orthogonal_projection_of_eq_subspace,
644644
simp },
645-
rw [reflection_apply, h_faces, s.orthogonal_projection_circumcenter hc, circumcenter_eq_centroid,
646-
s.face_centroid_eq_centroid hc, centroid_eq_affine_combination_of_points_with_circumcenter,
645+
rw [euclidean_geometry.reflection_apply, h_faces, s.orthogonal_projection_circumcenter hc,
646+
circumcenter_eq_centroid, s.face_centroid_eq_centroid hc,
647+
centroid_eq_affine_combination_of_points_with_circumcenter,
647648
circumcenter_eq_affine_combination_of_points_with_circumcenter, ←@vsub_eq_zero_iff_eq V,
648649
affine_combination_vsub, weighted_vsub_vadd_affine_combination, affine_combination_vsub,
649650
weighted_vsub_apply, sum_points_with_circumcenter],

0 commit comments

Comments
 (0)