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

Commit ea9c24f

Browse files
committed
feat(geometry/euclidean/basic): second intersection of a line and a sphere (#17843)
A very common geometrical construction is taking the second intersection of a line and a sphere (where one intersection point is given); we already have a lemma `dist_smul_vadd_eq_dist` that gives a characterization of that point. Add an explicit definition `sphere.second_inter` for this construction and associated API.
1 parent e8a4525 commit ea9c24f

File tree

1 file changed

+214
-0
lines changed

1 file changed

+214
-0
lines changed

src/geometry/euclidean/basic.lean

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ Copyright (c) 2020 Joseph Myers. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Joseph Myers, Manuel Candales
55
-/
6+
import analysis.convex.strict_convex_between
67
import analysis.inner_product_space.projection
78
import algebra.quadratic_discriminant
89

@@ -892,6 +893,219 @@ lemma eq_of_mem_sphere_of_mem_sphere_of_finrank_eq_two [finite_dimensional ℝ V
892893
eq_of_dist_eq_of_dist_eq_of_finrank_eq_two hd ((sphere.center_ne_iff_ne_of_mem hps₁ hps₂).2 hs)
893894
hp hp₁s₁ hp₂s₁ hps₁ hp₁s₂ hp₂s₂ hps₂
894895

896+
/-- Given a point on a sphere and a point not outside it, the inner product between the
897+
difference of those points and the radius vector is positive unless the points are equal. -/
898+
lemma inner_pos_or_eq_of_dist_le_radius {s : sphere P} {p₁ p₂ : P} (hp₁ : p₁ ∈ s)
899+
(hp₂ : dist p₂ s.center ≤ s.radius) : 0 < ⟪p₁ -ᵥ p₂, p₁ -ᵥ s.center⟫ ∨ p₁ = p₂ :=
900+
begin
901+
by_cases h : p₁ = p₂, { exact or.inr h },
902+
refine or.inl _,
903+
rw mem_sphere at hp₁,
904+
rw [←vsub_sub_vsub_cancel_right p₁ p₂ s.center, inner_sub_left,
905+
real_inner_self_eq_norm_mul_norm/-, ←dist_eq_norm_vsub, hp₁-/, sub_pos],
906+
refine lt_of_le_of_ne
907+
((real_inner_le_norm _ _).trans (mul_le_mul_of_nonneg_right _ (norm_nonneg _)))
908+
_,
909+
{ rwa [←dist_eq_norm_vsub, ←dist_eq_norm_vsub, hp₁] },
910+
{ rcases hp₂.lt_or_eq with hp₂' | hp₂',
911+
{ refine ((real_inner_le_norm _ _).trans_lt (mul_lt_mul_of_pos_right _ _)).ne,
912+
{ rwa [←hp₁, @dist_eq_norm_vsub V, @dist_eq_norm_vsub V] at hp₂' },
913+
{ rw [norm_pos_iff, vsub_ne_zero],
914+
rintro rfl,
915+
rw ←hp₁ at hp₂',
916+
refine (dist_nonneg.not_lt : ¬dist p₂ s.center < 0) _,
917+
simpa using hp₂' } },
918+
{ rw [←hp₁, @dist_eq_norm_vsub V, @dist_eq_norm_vsub V] at hp₂',
919+
nth_rewrite 0 ←hp₂',
920+
rw [ne.def, inner_eq_norm_mul_iff_real, hp₂', ←sub_eq_zero, ←smul_sub,
921+
vsub_sub_vsub_cancel_right, ←ne.def, smul_ne_zero_iff, vsub_ne_zero,
922+
and_iff_left (ne.symm h), norm_ne_zero_iff, vsub_ne_zero],
923+
rintro rfl,
924+
refine h (eq.symm _),
925+
simpa using hp₂' } }
926+
end
927+
928+
/-- Given a point on a sphere and a point not outside it, the inner product between the
929+
difference of those points and the radius vector is nonnegative. -/
930+
lemma inner_nonneg_of_dist_le_radius {s : sphere P} {p₁ p₂ : P} (hp₁ : p₁ ∈ s)
931+
(hp₂ : dist p₂ s.center ≤ s.radius) : 0 ≤ ⟪p₁ -ᵥ p₂, p₁ -ᵥ s.center⟫ :=
932+
begin
933+
rcases inner_pos_or_eq_of_dist_le_radius hp₁ hp₂ with h | rfl,
934+
{ exact h.le },
935+
{ simp }
936+
end
937+
938+
/-- Given a point on a sphere and a point inside it, the inner product between the difference of
939+
those points and the radius vector is positive. -/
940+
lemma inner_pos_of_dist_lt_radius {s : sphere P} {p₁ p₂ : P} (hp₁ : p₁ ∈ s)
941+
(hp₂ : dist p₂ s.center < s.radius) : 0 < ⟪p₁ -ᵥ p₂, p₁ -ᵥ s.center⟫ :=
942+
begin
943+
by_cases h : p₁ = p₂,
944+
{ rw [h, mem_sphere] at hp₁,
945+
exact false.elim (hp₂.ne hp₁) },
946+
exact (inner_pos_or_eq_of_dist_le_radius hp₁ hp₂.le).resolve_right h
947+
end
948+
949+
/-- Given three collinear points, two on a sphere and one not outside it, the one not outside it
950+
is weakly between the other two points. -/
951+
lemma wbtw_of_collinear_of_dist_center_le_radius {s : sphere P} {p₁ p₂ p₃ : P}
952+
(h : collinear ℝ ({p₁, p₂, p₃} : set P)) (hp₁ : p₁ ∈ s) (hp₂ : dist p₂ s.center ≤ s.radius)
953+
(hp₃ : p₃ ∈ s) (hp₁p₃ : p₁ ≠ p₃) : wbtw ℝ p₁ p₂ p₃ :=
954+
h.wbtw_of_dist_eq_of_dist_le hp₁ hp₂ hp₃ hp₁p₃
955+
956+
/-- Given three collinear points, two on a sphere and one inside it, the one inside it is
957+
strictly between the other two points. -/
958+
lemma sbtw_of_collinear_of_dist_center_lt_radius {s : sphere P} {p₁ p₂ p₃ : P}
959+
(h : collinear ℝ ({p₁, p₂, p₃} : set P)) (hp₁ : p₁ ∈ s) (hp₂ : dist p₂ s.center < s.radius)
960+
(hp₃ : p₃ ∈ s) (hp₁p₃ : p₁ ≠ p₃) : sbtw ℝ p₁ p₂ p₃ :=
961+
h.sbtw_of_dist_eq_of_dist_lt hp₁ hp₂ hp₃ hp₁p₃
962+
963+
/-- The second intersection of a sphere with a line through a point on that sphere; that point
964+
if it is the only point of intersection of the line with the sphere. The intended use of this
965+
definition is when `p ∈ s`; the definition does not use `s.radius`, so in general it returns
966+
the second intersection with the sphere through `p` and with center `s.center`. -/
967+
def sphere.second_inter (s : sphere P) (p : P) (v : V) : P :=
968+
(-2 * ⟪v, p -ᵥ s.center⟫ / ⟪v, v⟫) • v +ᵥ p
969+
970+
/-- The distance between `second_inter` and the center equals the distance between the original
971+
point and the center. -/
972+
@[simp] lemma sphere.second_inter_dist (s : sphere P) (p : P) (v : V) :
973+
dist (s.second_inter p v) s.center = dist p s.center :=
974+
begin
975+
rw sphere.second_inter,
976+
by_cases hv : v = 0, { simp [hv] },
977+
rw dist_smul_vadd_eq_dist _ _ hv,
978+
exact or.inr rfl
979+
end
980+
981+
/-- The point given by `second_inter` lies on the sphere. -/
982+
@[simp] lemma sphere.second_inter_mem {s : sphere P} {p : P} (v : V) :
983+
s.second_inter p v ∈ s ↔ p ∈ s :=
984+
by simp_rw [mem_sphere, sphere.second_inter_dist]
985+
986+
variables (V)
987+
988+
/-- If the vector is zero, `second_inter` gives the original point. -/
989+
@[simp] lemma sphere.second_inter_zero (s : sphere P) (p : P) :
990+
s.second_inter p (0 : V) = p :=
991+
by simp [sphere.second_inter]
992+
993+
variables {V}
994+
995+
/-- The point given by `second_inter` equals the original point if and only if the line is
996+
orthogonal to the radius vector. -/
997+
lemma sphere.second_inter_eq_self_iff {s : sphere P} {p : P} {v : V} :
998+
s.second_inter p v = p ↔ ⟪v, p -ᵥ s.center⟫ = 0 :=
999+
begin
1000+
refine ⟨λ hp, _, λ hp, _⟩,
1001+
{ by_cases hv : v = 0, { simp [hv] },
1002+
rwa [sphere.second_inter, eq_comm, eq_vadd_iff_vsub_eq, vsub_self, eq_comm, smul_eq_zero,
1003+
or_iff_left hv, div_eq_zero_iff, inner_self_eq_zero, or_iff_left hv, mul_eq_zero,
1004+
or_iff_right (by norm_num : (-2 : ℝ) ≠ 0)] at hp },
1005+
{ rw [sphere.second_inter, hp, mul_zero, zero_div, zero_smul, zero_vadd] }
1006+
end
1007+
1008+
/-- A point on a line through a point on a sphere equals that point or `second_inter`. -/
1009+
lemma sphere.eq_or_eq_second_inter_of_mem_mk'_span_singleton_iff_mem {s : sphere P} {p : P}
1010+
(hp : p ∈ s) {v : V} {p' : P} (hp' : p' ∈ affine_subspace.mk' p (ℝ ∙ v)) :
1011+
(p' = p ∨ p' = s.second_inter p v) ↔ p' ∈ s :=
1012+
begin
1013+
refine ⟨λ h, _, λ h, _⟩,
1014+
{ rcases h with h | h,
1015+
{ rwa h },
1016+
{ rwa [h, sphere.second_inter_mem] } },
1017+
{ rw [affine_subspace.mem_mk'_iff_vsub_mem, submodule.mem_span_singleton] at hp',
1018+
rcases hp' with ⟨r, hr⟩,
1019+
rw [eq_comm, ←eq_vadd_iff_vsub_eq] at hr,
1020+
subst hr,
1021+
by_cases hv : v = 0, { simp [hv] },
1022+
rw sphere.second_inter,
1023+
rw mem_sphere at h hp,
1024+
rw [←hp, dist_smul_vadd_eq_dist _ _ hv] at h,
1025+
rcases h with h | h;
1026+
simp [h] }
1027+
end
1028+
1029+
/-- `second_inter` is unchanged by multiplying the vector by a nonzero real. -/
1030+
@[simp] lemma sphere.second_inter_smul (s : sphere P) (p : P) (v : V) {r : ℝ}
1031+
(hr : r ≠ 0) : s.second_inter p (r • v) = s.second_inter p v :=
1032+
begin
1033+
simp_rw [sphere.second_inter, real_inner_smul_left, inner_smul_right, smul_smul,
1034+
div_mul_eq_div_div],
1035+
rw [mul_comm, ←mul_div_assoc, ←mul_div_assoc, mul_div_cancel_left _ hr, mul_comm, mul_assoc,
1036+
mul_div_cancel_left _ hr, mul_comm]
1037+
end
1038+
1039+
/-- `second_inter` is unchanged by negating the vector. -/
1040+
@[simp] lemma sphere.second_inter_neg (s : sphere P) (p : P) (v : V) :
1041+
s.second_inter p (-v) = s.second_inter p v :=
1042+
by rw [←neg_one_smul ℝ v, s.second_inter_smul p v (by norm_num : (-1 : ℝ) ≠ 0)]
1043+
1044+
/-- Applying `second_inter` twice returns the original point. -/
1045+
@[simp] lemma sphere.second_inter_second_inter (s : sphere P) (p : P) (v : V) :
1046+
s.second_inter (s.second_inter p v) v = p :=
1047+
begin
1048+
by_cases hv : v = 0, { simp [hv] },
1049+
have hv' : ⟪v, v⟫ ≠ 0 := inner_self_eq_zero.not.2 hv,
1050+
simp only [sphere.second_inter, vadd_vsub_assoc, vadd_vadd, inner_add_right, inner_smul_right,
1051+
div_mul_cancel _ hv'],
1052+
rw [←@vsub_eq_zero_iff_eq V, vadd_vsub, ←add_smul, ←add_div],
1053+
convert zero_smul ℝ _,
1054+
convert zero_div _,
1055+
ring
1056+
end
1057+
1058+
/-- If the vector passed to `second_inter` is given by a subtraction involving the point in
1059+
`second_inter`, the result of `second_inter` may be expressed using `line_map`. -/
1060+
lemma sphere.second_inter_eq_line_map (s : sphere P) (p p' : P) :
1061+
s.second_inter p (p' -ᵥ p) =
1062+
affine_map.line_map p p' (-2 * ⟪p' -ᵥ p, p -ᵥ s.center⟫ / ⟪p' -ᵥ p, p' -ᵥ p⟫) :=
1063+
rfl
1064+
1065+
/-- If the vector passed to `second_inter` is given by a subtraction involving the point in
1066+
`second_inter`, the result lies in the span of the two points. -/
1067+
lemma sphere.second_inter_vsub_mem_affine_span (s : sphere P) (p₁ p₂ : P) :
1068+
s.second_inter p₁ (p₂ -ᵥ p₁) ∈ line[ℝ, p₁, p₂] :=
1069+
smul_vsub_vadd_mem_affine_span_pair _ _ _
1070+
1071+
/-- If the vector passed to `second_inter` is given by a subtraction involving the point in
1072+
`second_inter`, the three points are collinear. -/
1073+
lemma sphere.second_inter_collinear (s : sphere P) (p p' : P) :
1074+
collinear ℝ ({p, p', s.second_inter p (p' -ᵥ p)} : set P) :=
1075+
begin
1076+
rw [set.pair_comm, set.insert_comm],
1077+
exact (collinear_insert_iff_of_mem_affine_span (s.second_inter_vsub_mem_affine_span _ _)).2
1078+
(collinear_pair ℝ _ _)
1079+
end
1080+
1081+
/-- If the vector passed to `second_inter` is given by a subtraction involving the point in
1082+
`second_inter`, and the second point is not outside the sphere, the second point is weakly
1083+
between the first point and the result of `second_inter`. -/
1084+
lemma sphere.wbtw_second_inter {s : sphere P} {p p' : P} (hp : p ∈ s)
1085+
(hp' : dist p' s.center ≤ s.radius) : wbtw ℝ p p' (s.second_inter p (p' -ᵥ p)) :=
1086+
begin
1087+
by_cases h : p' = p, { simp [h] },
1088+
refine wbtw_of_collinear_of_dist_center_le_radius (s.second_inter_collinear p p')
1089+
hp hp' ((sphere.second_inter_mem _).2 hp) _,
1090+
intro he,
1091+
rw [eq_comm, sphere.second_inter_eq_self_iff, ←neg_neg (p' -ᵥ p), inner_neg_left,
1092+
neg_vsub_eq_vsub_rev, neg_eq_zero, eq_comm] at he,
1093+
exact ((inner_pos_or_eq_of_dist_le_radius hp hp').resolve_right (ne.symm h)).ne he
1094+
end
1095+
1096+
/-- If the vector passed to `second_inter` is given by a subtraction involving the point in
1097+
`second_inter`, and the second point is inside the sphere, the second point is strictly between
1098+
the first point and the result of `second_inter`. -/
1099+
lemma sphere.sbtw_second_inter {s : sphere P} {p p' : P} (hp : p ∈ s)
1100+
(hp' : dist p' s.center < s.radius) : sbtw ℝ p p' (s.second_inter p (p' -ᵥ p)) :=
1101+
begin
1102+
refine ⟨sphere.wbtw_second_inter hp hp'.le, _, _⟩,
1103+
{ rintro rfl, rw mem_sphere at hp, simpa [hp] using hp' },
1104+
{ rintro h,
1105+
rw [h, mem_sphere.1 ((sphere.second_inter_mem _).2 hp)] at hp',
1106+
exact lt_irrefl _ hp' }
1107+
end
1108+
8951109
/-- A set of points is concyclic if it is cospherical and coplanar. (Most results are stated
8961110
directly in terms of `cospherical` instead of using `concyclic`.) -/
8971111
structure concyclic (ps : set P) : Prop :=

0 commit comments

Comments
 (0)