@@ -5,6 +5,7 @@ Authors: Joseph Myers
55-/
66module
77
8+ public import Mathlib.Analysis.InnerProductSpace.Projection.FiniteDimensional
89public import Mathlib.Geometry.Euclidean.Projection
910public import Mathlib.Geometry.Euclidean.Sphere.Basic
1011
@@ -58,6 +59,7 @@ namespace EuclideanGeometry
5859namespace Sphere
5960
6061open AffineSubspace RealInnerProductSpace
62+ open scoped Affine
6163
6264variable {V P : Type *}
6365variable [NormedAddCommGroup V] [InnerProductSpace ℝ V] [MetricSpace P] [NormedAddTorsor V P]
@@ -123,6 +125,32 @@ lemma orthRadius_le_orthRadius_iff {s : Sphere P} {p q : P} :
123125 have hqp := orthRadius_le_orthRadius_iff.1 h.symm.le
124126 grind
125127
128+ lemma finrank_orthRadius [FiniteDimensional ℝ V] {s : Sphere P} {p : P} (hp : p ≠ s.center) :
129+ Module.finrank ℝ (s.orthRadius p).direction + 1 = Module.finrank ℝ V := by
130+ rw [orthRadius, add_comm, direction_mk']
131+ convert (ℝ ∙ (p -ᵥ s.center)).finrank_add_finrank_orthogonal
132+ exact (finrank_span_singleton (vsub_ne_zero.2 hp)).symm
133+
134+ lemma orthRadius_map {s : Sphere P} (p : P) {f : P ≃ᵃⁱ[ℝ] P} (h : f s.center = s.center) :
135+ (s.orthRadius p).map f.toAffineMap = s.orthRadius (f p) := by
136+ rw [orthRadius, map_mk', orthRadius]
137+ convert rfl using 2
138+ convert (Submodule.map_orthogonal (ℝ ∙ (p -ᵥ s.center)) f.linearIsometryEquiv).symm
139+ simp [Submodule.map_span, Set.image_singleton, h]
140+
141+ lemma direction_orthRadius_le_iff {s : Sphere P} {p q : P} :
142+ (s.orthRadius p).direction ≤ (s.orthRadius q).direction ↔
143+ ∃ r : ℝ, q -ᵥ s.center = r • (p -ᵥ s.center) := by
144+ simp [Submodule.orthogonal_le_orthogonal_iff, Submodule.mem_span_singleton, eq_comm]
145+
146+ lemma orthRadius_parallel_orthRadius_iff {s : Sphere P} {p q : P} :
147+ s.orthRadius p ∥ s.orthRadius q ↔ ∃ r : ℝ, r ≠ 0 ∧ q -ᵥ s.center = r • (p -ᵥ s.center) := by
148+ simp only [orthRadius, parallel_iff_direction_eq_and_eq_bot_iff_eq_bot, direction_mk',
149+ Submodule.orthogonalComplement_eq_orthogonalComplement,
150+ Submodule.span_singleton_eq_span_singleton, ← coe_eq_bot_iff,
151+ ← Set.not_nonempty_iff_eq_empty, mk'_nonempty, not_true_eq_false, and_true]
152+ exact ⟨fun ⟨r, h⟩ ↦ ⟨r, r.ne_zero, h.symm⟩, fun ⟨r, hr, h⟩ ↦ ⟨.mk0 r hr, h.symm⟩⟩
153+
126154/-- The affine subspace `as` is tangent to the sphere `s` at the point `p`. -/
127155structure IsTangentAt (s : Sphere P) (p : P) (as : AffineSubspace ℝ P) : Prop where
128156 mem_sphere : p ∈ s
@@ -194,6 +222,16 @@ lemma IsTangentAt.dist_eq_of_mem_of_mem {s : Sphere P} {p₁ p₂ q : P}
194222 have h2 := dist_sq_eq_of_mem h₂ hq_mem₂
195223 rwa [h1, add_left_cancel_iff, sq_eq_sq₀ dist_nonneg dist_nonneg] at h2
196224
225+ lemma IsTangentAt.eq_orthRadius_of_finrank_add_one_eq {s : Sphere P} {as : AffineSubspace ℝ P}
226+ {p : P} (ht : s.IsTangentAt p as) (hr : s.radius ≠ 0 )
227+ (hfr : Module.finrank ℝ as.direction + 1 = Module.finrank ℝ V) : as = s.orthRadius p := by
228+ have : FiniteDimensional ℝ V := Module.finite_of_finrank_eq_succ hfr.symm
229+ have hp : p ≠ s.center := fun h ↦ (h ▸ s.center_mem_iff).not.2 hr ht.mem_sphere
230+ rw [← finrank_orthRadius hp, Nat.add_right_cancel_iff] at hfr
231+ exact eq_of_direction_eq_of_nonempty_of_le
232+ (Submodule.eq_of_le_of_finrank_eq (direction_le ht.le_orthRadius) hfr) ⟨p, ht.mem_space⟩
233+ ht.le_orthRadius
234+
197235/-- The affine subspace `as` is tangent to the sphere `s` at some point. -/
198236def IsTangent (s : Sphere P) (as : AffineSubspace ℝ P) : Prop :=
199237 ∃ p, s.IsTangentAt p as
@@ -267,6 +305,40 @@ lemma isTangent_iff_isTangentAt_orthogonalProjection {s : Sphere P} {as : Affine
267305
268306alias ⟨IsTangent.isTangentAt, _⟩ := isTangent_iff_isTangentAt_orthogonalProjection
269307
308+ lemma IsTangent.eq_orthRadius_or_eq_orthRadius_pointReflection_of_parallel_orthRadius {s : Sphere P}
309+ {as : AffineSubspace ℝ P} {p : P} (h : s.IsTangent as) (hpar : as ∥ s.orthRadius p)
310+ (hp : p ∈ s) :
311+ as = s.orthRadius p ∨ as = s.orthRadius (Equiv.pointReflection s.center p) := by
312+ rcases h with ⟨q, hqs, hqas, hqo⟩
313+ have hd := direction_le hqo
314+ rw [hpar.direction_eq, direction_orthRadius_le_iff] at hd
315+ obtain ⟨r, hr⟩ := hd
316+ rcases eq_or_ne s.radius 0 with hrad | hrad
317+ · rw [mem_sphere, hrad, dist_eq_zero] at hp hqs
318+ rw [hp, orthRadius_center] at hpar ⊢
319+ rw [hqs, orthRadius_center] at hqo
320+ exact .inl (eq_of_direction_eq_of_nonempty_of_le hpar.direction_eq ⟨q, hqas⟩ hqo)
321+ obtain rfl : as = s.orthRadius q := by
322+ refine eq_of_direction_eq_of_nonempty_of_le ?_ ⟨q, hqas⟩ hqo
323+ rw [hpar.direction_eq, direction_orthRadius, direction_orthRadius]
324+ congr 1
325+ rcases eq_or_ne r 0 with rfl | hr0
326+ · simp_all
327+ · rw [hr, Submodule.span_singleton_smul_eq hr0.isUnit]
328+ rcases eq_or_ne r 0 with rfl | hr0
329+ · simp_all
330+ · have hr' : ‖q -ᵥ s.center‖ = ‖r • (p -ᵥ s.center)‖ := by
331+ rw [hr]
332+ simp_rw [norm_smul, Real.norm_eq_abs, ← dist_eq_norm_vsub, mem_sphere.1 hp,
333+ mem_sphere.1 hqs, right_eq_mul₀ hrad] at hr'
334+ rcases eq_or_eq_neg_of_abs_eq hr' with rfl | rfl
335+ · simp_all
336+ · right
337+ convert rfl
338+ rw [← eq_vadd_iff_vsub_eq] at hr
339+ rw [hr]
340+ simp [Equiv.pointReflection_apply]
341+
270342lemma IsTangentAt.eq_orthogonalProjection {s : Sphere P} {p : P} {as : AffineSubspace ℝ P}
271343 [Nonempty as] [as.direction.HasOrthogonalProjection] (h : s.IsTangentAt p as) :
272344 p = orthogonalProjection as s.center := by
0 commit comments