1-- turn(t) is a rotation: a plane turn by a point of the unit circle is2-- orthogonal with determinant one, so it lies in SO33-- 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.Absorption.TurnRotation9import Turn10import Rotation.Orthogonal1112-- The transpose of a plane turn is the turn by the conjugate point.13theorem planeTurn.transposed (a b : Real)14shows transpose(planeTurn(a, b)) = planeTurn(a, -b)15proof16have matrix := planeTurn.matrix at a, b17have matrixT : transpose(planeTurn(a, b)) : realRing ^ 3×3:= transpose.matrix with*18have entries : ∀ i ∈3, ∀ j ∈3,19 transpose(planeTurn(a, b))[i, j] = planeTurn(a, -b)[i, j]20intros i hi j hj21have flip := transpose.entry at planeTurn(a, b), i, j with*22rw [flip, planeTurn.graph, planeTurn.graph]23have rows := threeIndex.cases with hi24have columns := threeIndex.cases with hj25rcases rows with rowZero | rowOne | rowTwo26 . rcases columns with columnZero | columnOne | columnTwo27 . rw [rowZero, columnZero]28 matrix3of_entries29 . rw [rowZero, columnOne]30 matrix3of_entries31ring32 . rw [rowZero, columnTwo]33 matrix3of_entries34 . rcases columns with columnZero | columnOne | columnTwo35 . rw [rowOne, columnZero]36 matrix3of_entries37 . rw [rowOne, columnOne]38 matrix3of_entries39 . rw [rowOne, columnTwo]40 matrix3of_entries41 . rcases columns with columnZero | columnOne | columnTwo42 . rw [rowTwo, columnZero]43 matrix3of_entries44 . rw [rowTwo, columnOne]45 matrix3of_entries46 . rw [rowTwo, columnTwo]47 matrix3of_entries48have negReal : -b ∈ ℝ bytypecheck49have conjugateMatrix : planeTurn(a, -b) : realRing ^ 3×3:= planeTurn.matrix with*50have leftTyped : Matrix3(transpose(planeTurn(a, b))) := Matrix3.of_matrix with matrixT51have rightTyped : Matrix3(planeTurn(a, -b)) := Matrix3.of_matrix with conjugateMatrix52exact Matrix3.ext with leftTyped, rightTyped, entries5354-- A plane turn by a point of the unit circle is in SO3.55theorem planeTurn.so3 (a b : Real)56requires circle : a * a + b * b =157shows planeTurn(a, b) ∈ so3Matrices58proof59have matrix := planeTurn.matrix at a, b60have transposed := planeTurn.transposed at a, b61have first : a * a - b * (-b) = (1:R)62rw← circle63ring64have second : a * (-b) + b * a = (0:R)65ring66have third : a * a - (-b) * b = (1:R)67rw← circle68ring69have fourth : a * b + (-b) * a = (0:R)70ring71haveright : call2(Ring.mul(matrixRing(realRing, 3)), planeTurn(a, b),72 transpose(planeTurn(a, b))) = Ring.one(matrixRing(realRing, 3))73rw [← matrixMul3.graph, transposed, planeTurn.mul, first, second]74exact planeTurn.one75haveleft : call2(Ring.mul(matrixRing(realRing, 3)), transpose(planeTurn(a, b)),76 planeTurn(a, b)) = Ring.one(matrixRing(realRing, 3))77rw [← matrixMul3.graph, transposed, planeTurn.mul, third, fourth]78exact planeTurn.one79have orthogonal := Orthogonal.mk withleft, right80have key : determinant3(planeTurn(a, b)) = a * a + b * b81rw [determinant3.value, planeTurn.graph]82 matrix3of_entries83ring84have unit : determinant3(planeTurn(a, b)) = (1:R)85rw key86exact circle87exact so3Matrices.mk with orthogonal, unit8889-- turn(t) is a rotation.90theorem turn.rotation (t : Real)91shows turn(t) ∈ so3Matrices92proof93have circle := turn.circle at t94rw turn.graph95exact planeTurn.so3 with circle9697theorem turn.so3 (t : Real)98shows turn(t) ∈ Group.carrier(SO3)99proof100rw SO3.carrierOf101exact turn.rotation at t102