1-- The closed unit ball of ℝ³ and the punctured ball, which every rotation2-- carries into itself3-- Part of Cumulus, the Grace17 mathematics library.4-- Copyright (c) 2026 Grant Passmore.5-- Released under the Apache License 2.0. See LICENSE in the repository root.6-- Authors: Grant Passmore78module Grace.Cumulus.Geometry.Euclid.Ball9import Motions1011def unitBall : Set:= { v ∈ ℝ³ | normSq(v) ≤ (1:R) }12def puncturedBall : Set:= unitBall ∖ {zeroVector}1314theorem puncturedBall.graph15shows puncturedBall = unitBall ∖ {zeroVector}16proof17simp [puncturedBall]1819theorem unitBall.subset20shows unitBall ⊆ ℝ³21proof22intros v hv23have parts := unitBall.membership.forward with hv24exact parts.left2526theorem unitBall.function (v : Set)27requires member : v ∈ unitBall28shows v : 3→ ℝ29proof30exact ℝ³.function with (unitBall.subset with v, member)3132theorem puncturedBall.membership (v : Set)33shows v ∈ puncturedBall ↔ v ∈ unitBall ∧ v ≠ zeroVector34proof35rw puncturedBall.graph36constructor37 . intro hv38obtain⟨inBall, notZero⟩:= difference.membership.forward with hv39refine⟨inBall, ?_⟩40intro equal41apply notZero42rw equal43exact singleton.self44 . intro hv45obtain⟨inBall, notZero⟩:= hv46apply difference.membership.backward47refine⟨inBall, ?_⟩48intro inSingleton49exact notZero with (singleton.membership.forward with inSingleton)5051theorem puncturedBall.subset52shows puncturedBall ⊆ unitBall53proof54rw puncturedBall.graph55exact difference.subset_left at unitBall, {zeroVector}5657theorem puncturedBall.subset_space58shows puncturedBall ⊆ ℝ³59proof60exact Subset.transitive with puncturedBall.subset, unitBall.subset6162theorem zeroVector.in_ball63shows zeroVector ∈ unitBall64proof65have zeroIn : zeroVector ∈ ℝ³ := ℝ³.of_function with zeroVector.vector66have bound : normSq(zeroVector) ≤ (1:R)67rw zeroVector.normSq68linarith69exact unitBall.membership.backward with⟨zeroIn, bound⟩7071-- The sphere lies in the punctured ball.72theorem sphere.subset_ball73shows S² ⊆ unitBall74proof75intros v hv76obtain⟨inSpace, unit⟩:= S².membership.forward with hv77have bound : normSq(v) ≤ (1:R)78rw unit79linarith80exact unitBall.membership.backward with⟨inSpace, bound⟩8182theorem sphere.subset_punctured83shows S² ⊆ puncturedBall84proof85intros v hv86obtain⟨inSpace, unit⟩:= S².membership.forward with hv87have inBall := sphere.subset_ball with v, hv88have notZero : v ≠ zeroVector89intro equal90rw [equal, zeroVector.normSq] at unit91linarith92exact puncturedBall.membership.backward with⟨inBall, notZero⟩9394-- A rotation preserves the ball and misses the origin only at the origin.95theorem unitBall.rotate (M : realRing ^ 3×3) (v : Set)96requires hM : M ∈ so3Matrices97requires hv : v ∈ unitBall98shows M · v ∈ unitBall99proof100obtain⟨inSpace, bound⟩:= unitBall.membership.forward with hv101have vector := ℝ³.function with inSpace102have orthogonal := so3Matrices.orthogonal with hM103have image := matrixVector.vector at M, v with*104have imageIn := ℝ³.of_function with image105have norm := Orthogonal.normSq with orthogonal, vector106have imageBound : normSq(M · v) ≤ (1:R)107rw norm108exact bound109exact unitBall.membership.backward with⟨imageIn, imageBound⟩110111theorem matrixVector.eq_zero (M : realRing ^ 3×3) (v : Set)112requires hM : M ∈ so3Matrices113requires vector : v : 3→ ℝ114requires zero : M · v = zeroVector115shows v = zeroVector116proof117have transposed := transpose.matrix at M with*118have orthogonal := so3Matrices.orthogonal with hM119haveleft:= Orthogonal.left with orthogonal120have composed := matrixVector.mul at transpose(M), M, v with vector121have unit := matrixVector.one at v with vector122have killed := matrixVector.zero_vector at transpose(M) with*123rw [left, unit, zero, killed] at composed124exact composed125126theorem puncturedBall.rotate (M : realRing ^ 3×3) (v : Set)127requires hM : M ∈ so3Matrices128requires hv : v ∈ puncturedBall129shows M · v ∈ puncturedBall130proof131obtain⟨inBall, notZero⟩:= puncturedBall.membership.forward with hv132have vector := unitBall.function with inBall133have imageIn := unitBall.rotate with hM, inBall134have imageNotZero : M · v ≠ zeroVector135intro zero136exact notZero with (matrixVector.eq_zero with hM, vector, zero)137exact puncturedBall.membership.backward with⟨imageIn, imageNotZero⟩138139theorem puncturedBall.invariant140shows∀ M ∈ Group.carrier(SO3), ∀ v ∈ puncturedBall, spaceAction(M,141 v) ∈ puncturedBall142proof143intros M hM v hv144rw SO3.carrierOf at hM145have matrixM := so3Matrices.matrix with hM146have inSpace := puncturedBall.subset_space with v, hv147have value := spaceAction.apply with hM, inSpace148rw value149exact puncturedBall.rotate with hM, hv150