diff --git a/models/newsreport/spacetime/fig119sumofangles.jl b/models/newsreport/spacetime/fig119sumofangles.jl index 16086ad..6759170 100644 --- a/models/newsreport/spacetime/fig119sumofangles.jl +++ b/models/newsreport/spacetime/fig119sumofangles.jl @@ -5,7 +5,7 @@ using Porta figuresize = (4096, 2160) -segments = 60 +segments = 360 frames_number = 360 modelname = "fig119sumofangles" M = Identity(4) @@ -18,7 +18,9 @@ up = normalize(ℝ³(0.0, 0.0, 1.0)) arrowsize = Vec3f(0.06, 0.08, 0.1) arrowlinewidth = 0.04 linewidth = 20 +markersize = 0.05 timesign = 1 +ϵ = 0.01 T = Float64(timesign) mask = load("data/basemap_mask.png") @@ -36,7 +38,6 @@ lscene = LScene(fig[1, 1], show_axis=false, scenekw = (lights = [pl, al], clear= generate() = 2rand() - 1 + im * (2rand() - 1) κ = SpinVector(generate(), generate(), timesign) ω = SpinVector(generate(), generate(), timesign) -ϵ = 0.01 ζ = Complex(κ) ζ′ = ζ - 1.0 / √2 * ϵ / κ.a[2] κ = SpinVector(ζ, timesign) @@ -54,48 +55,17 @@ generate() = 2rand() - 1 + im * (2rand() - 1) w = (Complex(κ + ω) - Complex(κ)) / (Complex(ω) - Complex(κ)) @assert(imag(w) ≤ 0 || isapprox(imag(w), 0.0), "The flagpoles are not collinear: $(Complex(κ)), $(Complex(ω)), $(Complex(κ + ω))") -κv = 𝕍( κ) -κv′ = 𝕍( κ′) -ωv = 𝕍( ω) -ωv′ = 𝕍( ω′) -zero = 𝕍( 0.0, 0.0, 0.0, 0.0) -B = stack([vec(κv), vec(ωv), vec(zero), vec(zero)]) -N = LinearAlgebra.nullspace(B) -a = 𝕍( N[begin:end, 1]) -b = 𝕍( N[begin:end, 2]) - -a = 𝕍( LinearAlgebra.normalize(vec(a - κv - ωv))) -b = 𝕍( LinearAlgebra.normalize(vec(b - κv - ωv))) - -v₁ = κv.a -v₂ = ωv.a -v₃ = a.a -v₄ = b.a - -e₁ = v₁ -ê₁ = normalize(e₁) -e₂ = v₂ - dot(ê₁, v₂) * ê₁ -ê₂ = normalize(e₂) -e₃ = v₃ - dot(ê₁, v₃) * ê₁ - dot(ê₂, v₃) * ê₂ -ê₃ = normalize(e₃) -e₄ = v₄ - dot(ê₁, v₄) * ê₁ - dot(ê₂, v₄) * ê₂ - dot(ê₃, v₄) * ê₃ -ê₄ = normalize(e₄) - -ê₁ = 𝕍( ê₁) -ê₂ = 𝕍( ê₂) -ê₃ = 𝕍( ê₃) -ê₄ = 𝕍( ê₄) - -u = 𝕍( LinearAlgebra.normalize(rand(4))) -v = 𝕍( LinearAlgebra.normalize(rand(4))) -p = 𝕍( LinearAlgebra.normalize(vec(u + v))) +κv = 𝕍( normalize(ℝ⁴(𝕍( κ)))) +κ′v = 𝕍( normalize(ℝ⁴(𝕍( κ′)))) +ωv = 𝕍( normalize(ℝ⁴(𝕍( ω)))) +ω′v = 𝕍( normalize(ℝ⁴(𝕍( ω′)))) northpole = Observable(Point3f(0.0, 0.0, 1.0)) tail = Observable(Point3f(0.0, 0.0, 0.0)) κtail = Observable(Point3f(0.0, 0.0, 0.0)) ωtail = Observable(Point3f(0.0, 0.0, 0.0)) -κhead = Observable(Point3f(vec(project(ℍ(vec(κv))))...)) -ωhead = Observable(Point3f(vec(project(ℍ(vec(ωv))))...)) +κhead = Observable(Point3f(project(ℍ(vec(κv))))) +ωhead = Observable(Point3f(project(ℍ(vec(ωv))))) ps = @lift([$κtail, $ωtail]) ns = @lift([$κhead, $ωhead]) colorants = [:red, :green] @@ -106,9 +76,12 @@ arrows!(lscene, align = :origin ) -circlepoints = Observable(Point3f[]) -circlecolors = Observable(Int[]) -circle = lines!(lscene, circlepoints, color = circlecolors, linewidth = 2linewidth, colorrange = (1, segments), colormap = :Paired_12) +circlepoints1 = Observable(Point3f[]) +circlecolors1 = Observable(Int[]) +circlepoints2 = Observable(Point3f[]) +circlecolors2 = Observable(Int[]) +lines!(lscene, circlepoints1, color = circlecolors1, linewidth = 2linewidth, colorrange = (1, segments), colormap = :Paired_12) +lines!(lscene, circlepoints2, color = circlecolors2, linewidth = 2linewidth, colorrange = (1, segments), colormap = :Dark2_8) titles = ["N", "L", "M", "P", "Q"] rotation = gettextrotation(lscene) @@ -122,17 +95,17 @@ text!(lscene, markerspace = :data ) -κflagplanematrix = makeflagplane(κv, κv′ - κv, T, segments = segments) -κflagplanecolor = Observable(fill(RGBAf(0.5, 0.5, 0.5, 0.5), segments, segments)) +κflagplanematrix = makeflagplane(κv, κ′v - κv, T, segments = segments) +κflagplanecolor = Observable(fill(RGBAf(1.0, 0.0, 0.0, 0.8), segments, segments)) κflagplaneobservable = buildsurface(lscene, κflagplanematrix, κflagplanecolor, transparency = false) -ωflagplanematrix = makeflagplane(ωv, ωv′ - ωv, T, segments = segments) -ωflagplanecolor = Observable(fill(RGBAf(0.5, 0.5, 0.5, 0.5), segments, segments)) +ωflagplanematrix = makeflagplane(ωv, ω′v - ωv, T, segments = segments) +ωflagplanecolor = Observable(fill(RGBAf(0.0, 1.0, 0.0, 0.8), segments, segments)) ωflagplaneobservable = buildsurface(lscene, ωflagplanematrix, ωflagplanecolor, transparency = false) -meshscatter!(lscene, northpole, markersize = 0.05, color = :black) -meshscatter!(lscene, tail, markersize = 0.05, color = :black) -meshscatter!(lscene, κtail, markersize = 0.05, color = colorants[1]) -meshscatter!(lscene, ωtail, markersize = 0.05, color = colorants[2]) +meshscatter!(lscene, northpole, markersize = markersize, color = :black) +meshscatter!(lscene, tail, markersize = markersize, color = :black) +meshscatter!(lscene, κtail, markersize = markersize, color = colorants[1]) +meshscatter!(lscene, ωtail, markersize = markersize, color = colorants[2]) spherematrix = makesphere(M, T, compressedprojection = true, segments = segments) sphereobservable = buildsurface(lscene, spherematrix, mask, transparency = true) @@ -141,50 +114,57 @@ sphereobservable = buildsurface(lscene, spherematrix, mask, transparency = true) animate(frame::Int) = begin progress = Float64(frame / frames_number) println("Frame: $frame, Progress: $progress") - κflagplanedirection = 𝕍( LinearAlgebra.normalize(vec(κv′ - κv))) - ωflagplanedirection = 𝕍( LinearAlgebra.normalize(vec(ωv′ - ωv))) - global u = LinearAlgebra.normalize(vec((-dot(ê₃, κflagplanedirection) * ê₃ + -dot(ê₄, κflagplanedirection) * ê₄))) - global v = LinearAlgebra.normalize(vec((-dot(ê₃, ωflagplanedirection) * ê₃ + -dot(ê₄, ωflagplanedirection) * ê₄))) - p = -𝕍(LinearAlgebra.normalize(u + v)) - global p = dot(ê₃, p) * ê₃ + dot(ê₄, p) * ê₄ - axis = normalize(ℝ³(vec(p)[2:4])) - M = mat4(ℍ(progress * 4π, axis)) - κ_transformed = M * ℍ(vec(κv)) - κ′_transformed = M * ℍ(vec(κv′)) - ω_transformed = M * ℍ(vec(ωv)) - ω′_transformed = M * ℍ(vec(ωv′)) - northpole[] = Point3f(project(M * ℍ(vec(𝕍( SpinVector(Complex(0.0), timesign)))))) - spherematrix = makesphere(M, T, compressedprojection = true, segments = segments) + spintransform = SpinTransformation(progress * 2π, progress * 2π, progress * 2π) + _κ = spintransform * κ + _ω = spintransform * ω + _κ′ = spintransform * κ′ + _ω′ = spintransform * ω′ + _κv = 𝕍( normalize(ℝ⁴(𝕍( _κ)))) + _κ′v = 𝕍( normalize(ℝ⁴(𝕍( _κ′)))) + _ωv = 𝕍( normalize(ℝ⁴(𝕍( _ω)))) + _ω′v = 𝕍( normalize(ℝ⁴(𝕍( _ω′)))) + κflagplane1 = _κv + κflagplane2 = 𝕍(normalize(ℝ⁴(_κ′v - _κv))) + ωflagplane1 = _ωv + ωflagplane2 = 𝕍(normalize(ℝ⁴(_ω′v - _ωv))) + northpole[] = Point3f(project(normalize(ℝ⁴(𝕍( spintransform * SpinVector(Inf, timesign)))))) + spherematrix = makesphere(spintransform, T, compressedprojection = true, segments = segments) updatesurface!(spherematrix, sphereobservable) - _κ = 𝕍( vec(κ_transformed)) - _κ′ = 𝕍( vec(κ′_transformed)) - _ω = 𝕍( vec(ω_transformed)) - _ω′ = 𝕍( vec(ω′_transformed)) - κflagplanematrix = makeflagplane(_κ, 𝕍(LinearAlgebra.normalize(vec(_κ′ - _κ))), T, segments = segments) - ωflagplanematrix = makeflagplane(_ω, 𝕍(LinearAlgebra.normalize(vec(_ω′ - _ω))), T, segments = segments) + κflagplanematrix = makeflagplane(κflagplane1, κflagplane2, T, segments = segments) + ωflagplanematrix = makeflagplane(ωflagplane1, ωflagplane2, T, segments = segments) updatesurface!(κflagplanematrix, κflagplaneobservable) updatesurface!(ωflagplanematrix, ωflagplaneobservable) - κflagplanecolor[] = [RGBAf(1.0, 0.0, 0.0, 0.8) for i in 1:segments, j in 1:segments] - ωflagplanecolor[] = [RGBAf(0.0, 1.0, 0.0, 0.8) for i in 1:segments, j in 1:segments] - κhead[] = Point3f(project(ℍ(LinearAlgebra.normalize(vec(κ_transformed - κ′_transformed))))) - ωhead[] = Point3f(project(ℍ(LinearAlgebra.normalize(vec(ω_transformed - ω′_transformed))))) - κtail[] = Point3f(project(κ_transformed)) - ωtail[] = Point3f(project(ω_transformed)) - _circlepoints = Point3f[] - _circlecolors = Int[] + κtail[] = Point3f(project(normalize(ℝ⁴(_κv)))) + ωtail[] = Point3f(project(normalize(ℝ⁴(_ωv)))) + κhead[] = Point3f(project(normalize(ℝ⁴(_κ′v - _κv)))) + ωhead[] = Point3f(project(normalize(ℝ⁴(_ω′v - _ωv)))) + _circlepoints1 = Point3f[] + _circlecolors1 = Int[] + _circlepoints2 = Point3f[] + _circlecolors2 = Int[] for (i, ϕ) in enumerate(collect(range(-4π, stop = 4π, length = segments))) κζ = Complex(κ) ωζ = Complex(ω) ζ = κζ - ωζ - circlevector = M * ℍ(vec(𝕍( SpinVector(κζ + ϕ * ζ, timesign)))) - circlepoint = Point3f(vec(project(circlevector))...) - push!(_circlepoints, circlepoint) - push!(_circlecolors, i) + circlevector = normalize(ℝ⁴(𝕍(spintransform * SpinVector(κζ + ϕ * ζ, timesign)))) + circlepoint = Point3f(project(circlevector)) + push!(_circlepoints1, circlepoint) + push!(_circlecolors1, i) + κζ = Complex(κ) + ωζ = Complex(ω) + center = κζ + (ωζ - κζ) / 2.0 + radius = abs(ωζ - κζ) / 2.0 + circlevector = normalize(ℝ⁴(𝕍(spintransform * SpinVector(center + radius * exp(im * ϕ / 4.0), timesign)))) + circlepoint = Point3f(project(circlevector)) + push!(_circlepoints2, circlepoint) + push!(_circlecolors2, i) end - circlepoints[] = _circlepoints - circlecolors[] = _circlecolors - notify(circlepoints) - notify(circlecolors) + circlepoints1[] = _circlepoints1 + circlecolors1[] = _circlecolors1 + circlepoints2[] = _circlepoints2 + circlecolors2[] = _circlecolors2 + notify(circlepoints1) + notify(circlecolors1) updatecamera!(lscene, eyeposition, lookat, up) end diff --git a/models/newsreport/spacetime/fig120innerproductphase.jl b/models/newsreport/spacetime/fig120innerproductphase.jl index 8953de3..5466727 100644 --- a/models/newsreport/spacetime/fig120innerproductphase.jl +++ b/models/newsreport/spacetime/fig120innerproductphase.jl @@ -5,7 +5,7 @@ using Porta figuresize = (4096, 2160) -segments = 60 +segments = 360 frames_number = 360 modelname = "fig120innerproductphase" M = Identity(4) @@ -15,6 +15,13 @@ ẑ = ℝ³([0.0; 0.0; 1.0]) eyeposition = normalize(ℝ³(1.0, 1.0, 1.0)) * π lookat = ℝ³(0.0, 0.0, 0.0) up = normalize(ℝ³(0.0, 0.0, 1.0)) +timesign = 1 +T = Float64(timesign) +arrowsize = Vec3f(0.06, 0.08, 0.1) +arrowlinewidth = 0.04 +linewidth = 20 +ϵ = 0.01 +mask = load("data/basemap_mask.png") makefigure() = Figure(size = figuresize) fig = with_theme(makefigure, theme_black()) @@ -22,7 +29,6 @@ pl = PointLight(Point3f(0), RGBf(0.0862, 0.0862, 0.0862)) al = AmbientLight(RGBf(0.9, 0.9, 0.9)) lscene = LScene(fig[1, 1], show_axis=false, scenekw = (lights = [pl, al], clear=true, backgroundcolor = :white)) -timesign = -1 ο = SpinVector([Complex(1.0); Complex(0.0)], timesign) ι = SpinVector([Complex(0.0); Complex(1.0)], timesign) @assert(isapprox(dot(ο, ι), 1.0), "The inner product of spin vectors $ι and $ο is not unity.") @@ -30,7 +36,6 @@ timesign = -1 generate() = 2rand() - 1 + im * (2rand() - 1) κ = SpinVector(generate(), generate(), timesign) -ϵ = 0.01 ζ = Complex(κ) ζ′ = ζ - 1.0 / √2 * ϵ / κ.a[2] κ = SpinVector(ζ, timesign) @@ -45,110 +50,36 @@ generate() = 2rand() - 1 + im * (2rand() - 1) @assert(isapprox(dot(ω, ι), vec(ω)[1]), "The first component of the spin vector $ω is not equal to the inner product of $ω and $ι.") @assert(isapprox(dot(ω, ο), -vec(ω)[2]), "The second component of the spin vector $ω is not equal to minus the inner product of $ω and $ο.") -t = 𝕍(1.0, 0.0, 0.0, 0.0) -x = 𝕍(0.0, 1.0, 0.0, 0.0) -y = 𝕍(0.0, 0.0, 1.0, 0.0) -z = 𝕍(0.0, 0.0, 0.0, 1.0) -ο = √2 * (t + z) -ι = √2 * (t - z) - -κ = 𝕍(κ) -κ′ = 𝕍(κ′) -ω = 𝕍(ω) -ω′ = 𝕍(ω′) -zero = 𝕍(0.0, 0.0, 0.0, 0.0) -B = stack([vec(κ), vec(ω), vec(zero), vec(zero)]) -N = LinearAlgebra.nullspace(B) -a = 𝕍(N[begin:end, 1]) -b = 𝕍(N[begin:end, 2]) -a = 𝕍(LinearAlgebra.normalize(vec(a - κ - ω))) -b = 𝕍(LinearAlgebra.normalize(vec(b - κ - ω))) - -v₁ = κ.a -v₂ = ω.a -v₃ = a.a -v₄ = b.a - -e₁ = v₁ -ê₁ = normalize(e₁) -e₂ = v₂ - dot(ê₁, v₂) * ê₁ -ê₂ = normalize(e₂) -e₃ = v₃ - dot(ê₁, v₃) * ê₁ - dot(ê₂, v₃) * ê₂ -ê₃ = normalize(e₃) -e₄ = v₄ - dot(ê₁, v₄) * ê₁ - dot(ê₂, v₄) * ê₂ - dot(ê₃, v₄) * ê₃ -ê₄ = normalize(e₄) - -ê₁ = 𝕍(ê₁) -ê₂ = 𝕍(ê₂) -ê₃ = 𝕍(ê₃) -ê₄ = 𝕍(ê₄) +κv = 𝕍( normalize(ℝ⁴(𝕍( κ)))) +κ′v = 𝕍( normalize(ℝ⁴(𝕍( κ′)))) +ωv = 𝕍( normalize(ℝ⁴(𝕍( ω)))) +ω′v = 𝕍( normalize(ℝ⁴(𝕍( ω′)))) u = 𝕍(LinearAlgebra.normalize(rand(4))) v = 𝕍(LinearAlgebra.normalize(rand(4))) p = 𝕍(LinearAlgebra.normalize(vec(u + v))) -arrowsize = Vec3f(0.06, 0.08, 0.1) -linewidth = 0.04 tail = Observable(Point3f(0.0, 0.0, 0.0)) -thead = Observable(Point3f(vec(project(ℍ(vec(t))))...)) -xhead = Observable(Point3f(vec(project(ℍ(vec(x))))...)) -yhead = Observable(Point3f(vec(project(ℍ(vec(y))))...)) -zhead = Observable(Point3f(vec(project(ℍ(vec(z))))...)) -οhead = Observable(Point3f(vec(project(ℍ(vec(ο))))...)) -ιhead = Observable(Point3f(vec(project(ℍ(vec(ι))))...)) -κhead = Observable(Point3f(vec(project(ℍ(vec(κ))))...)) -ωhead = Observable(Point3f(vec(project(ℍ(vec(ω))))...)) -uhead = Observable(Point3f(vec(project(ℍ(vec(u))))...)) -vhead = Observable(Point3f(vec(project(ℍ(vec(v))))...)) -phead = Observable(Point3f(vec(project(ℍ(vec(p))))...)) +κhead = Observable(Point3f(project(ℝ⁴(κv)))) +ωhead = Observable(Point3f(project(ℝ⁴(ωv)))) +uhead = Observable(Point3f(project(ℍ(vec(u))))) +vhead = Observable(Point3f(project(ℍ(vec(v))))) +phead = Observable(Point3f(project(ℍ(vec(p))))) ps = @lift([$tail, $tail, $tail, $tail, $tail]) ns = @lift([$κhead, $ωhead, $uhead, $vhead, $phead]) -colorants = [:red, :green, :blue, :orange, :black] +colorants = [:red, :green, :red, :green, :black] arrows!(lscene, ps, ns, fxaa = true, # turn on anti-aliasing color = colorants, - linewidth = linewidth, arrowsize = arrowsize, + linewidth = arrowlinewidth, arrowsize = arrowsize, align = :origin ) -linewidth = 20 -collection = collect(range(0.0, stop = 1.0, length = segments)) -κlinepoints = [] -ωlinepoints = [] -κlinecolors = [] -ωlinecolors = [] -κlines = [] -ωlines = [] -for (i, scale1) in enumerate(collection) - _κlinepoints = Observable(Point3f[]) - _ωlinepoints = Observable(Point3f[]) - _κlinecolors = Observable(Int[]) - _ωlinecolors = Observable(Int[]) - for (j, scale2) in enumerate(collection) - κvector = LinearAlgebra.normalize(vec(scale1 * κ + scale2 * κ′)) - ωvector = LinearAlgebra.normalize(vec(scale1 * ω + scale2 * ω′)) - κpoint = Point3f(vec(project(ℍ(κvector)))...) - ωpoint = Point3f(vec(project(ℍ(ωvector)))...) - push!(_κlinepoints[], κpoint) - push!(_ωlinepoints[], ωpoint) - push!(_κlinecolors[], i + j) - push!(_ωlinecolors[], i + j) - end - push!(κlinepoints, _κlinepoints) - push!(ωlinepoints, _ωlinepoints) - push!(κlinecolors, _κlinecolors) - push!(ωlinecolors, _ωlinecolors) - κline = lines!(lscene, κlinepoints[i], color = κlinecolors[i], linewidth = linewidth, colorrange = (1, 2segments), colormap = :fall) - ωline = lines!(lscene, ωlinepoints[i], color = ωlinecolors[i], linewidth = linewidth, colorrange = (1, 2segments), colormap = :winter) - push!(κlines, κline) - push!(ωlines, ωline) -end - arcpoints = Observable(Point3f[]) arccolors = Observable(Int[]) arc = lines!(lscene, arcpoints, color = arccolors, linewidth = 2linewidth, colorrange = (1, segments), colormap = :prism) -titles = ["L", "M", "U", "V", "p"] +titles = ["κ", "ω", "U", "V", "p"] rotation = gettextrotation(lscene) text!(lscene, @lift(map(x -> Point3f(vec((isnan(x) ? ẑ : x))), [$κhead, $ωhead, $uhead, $vhead, $phead])), @@ -160,62 +91,64 @@ text!(lscene, markerspace = :data ) -planematrix = makeplane(κ, ω, M) +planematrix = makeplane(κv, ωv, M) planecolor = Observable(fill(RGBAf(0.5, 0.5, 0.5, 0.5), segments, segments)) planeobservable = buildsurface(lscene, planematrix, planecolor, transparency = true) - -orthogonalplanematrix = makeplane(a, b, M) +ê₁, ê₂, ê₃, ê₄ = calculatebasisvectors(κ, ω) +orthogonalplanematrix = makeplane(𝕍( ê₃), 𝕍( ê₄), M) orthogonalplanecolor = Observable(fill(RGBAf(0.5, 0.5, 0.5, 0.5), segments, segments)) orthogonalplaneobservable = buildsurface(lscene, orthogonalplanematrix, orthogonalplanecolor, transparency = true) - +κflagplanematrix = makeflagplane(κv, κ′v - κv, T, segments = segments) +κflagplanecolor = Observable(fill(RGBAf(1.0, 0.0, 0.0, 0.8), segments, segments)) +κflagplaneobservable = buildsurface(lscene, κflagplanematrix, κflagplanecolor, transparency = false) +ωflagplanematrix = makeflagplane(ωv, ω′v - ωv, T, segments = segments) +ωflagplanecolor = Observable(fill(RGBAf(0.0, 1.0, 0.0, 0.8), segments, segments)) +ωflagplaneobservable = buildsurface(lscene, ωflagplanematrix, ωflagplanecolor, transparency = false) meshscatter!(lscene, tail, markersize = 0.05, color = :black) animate(frame::Int) = begin progress = frame / frames_number println("Frame: $frame, Progress: $progress") - κflagplanedirection = 𝕍(LinearAlgebra.normalize(vec(κ′ - κ))) - ωflagplanedirection = 𝕍(LinearAlgebra.normalize(vec(ω′ - ω))) - global u = LinearAlgebra.normalize(vec((-dot(ê₃, κflagplanedirection) * ê₃ + -dot(ê₄, κflagplanedirection) * ê₄))) - global v = LinearAlgebra.normalize(vec((-dot(ê₃, ωflagplanedirection) * ê₃ + -dot(ê₄, ωflagplanedirection) * ê₄))) - p = 𝕍(LinearAlgebra.normalize(u + v)) - global p = -dot(ê₃, p) * ê₃ + -dot(ê₄, p) * ê₄ - axis = normalize(ℝ³(vec(p)[2:4])) - M = mat4(ℍ(progress * 4π, axis)) - κ_transformed = M * ℍ(vec(κ)) - ω_transformed = M * ℍ(vec(ω)) - u_transformed = M * ℍ(vec(u)) - v_transformed = M * ℍ(vec(v)) - p_transformed = M * ℍ(vec(p)) - point = project(p_transformed) - point = isnan(vec(point)[1]) ? ẑ : normalize(point) - global lookat = point - point = cross(project(u_transformed), project(v_transformed)) + cross(project(κ_transformed), project(ω_transformed)) - point = isnan(vec(point)[1]) ? ẑ : normalize(point) - global eyeposition = normalize(point) * float(π) - - # the timelike 2-plane spanned by the flagpoles of κ and ω - planematrix = makeplane(ê₁, ê₂, M) - # σ, the spacelike 2-plane through O, - # which is the orthogonal complement of the timelike 2-plane spanned by the flagpoles of κ and ω - orthogonalplanematrix = makeplane(ê₃, ê₄, M) + spintransform = SpinTransformation(progress * 2π, progress * 2π, progress * 2π) + _κ = spintransform * κ + _ω = spintransform * ω + _κ′ = spintransform * κ′ + _ω′ = spintransform * ω′ + _κv = 𝕍( normalize(ℝ⁴(𝕍( _κ)))) + _κ′v = 𝕍( normalize(ℝ⁴(𝕍( _κ′)))) + _ωv = 𝕍( normalize(ℝ⁴(𝕍( _ω)))) + _ω′v = 𝕍( normalize(ℝ⁴(𝕍( _ω′)))) + ê₁, ê₂, ê₃, ê₄ = calculatebasisvectors(_κ, _ω) + κflagplane1 = _κv + κflagplane2 = 𝕍(normalize(ℝ⁴(_κ′v - _κv))) + ωflagplane1 = _ωv + ωflagplane2 = 𝕍(normalize(ℝ⁴(_ω′v - _ωv))) + global u = normalize(dot(ê₃, κflagplane1) * ê₃ + dot(ê₃, κflagplane2) * ê₃ + dot(ê₄, κflagplane1) * ê₄ + dot(ê₄, κflagplane2) * ê₄) + global v = normalize(dot(ê₃, ωflagplane1) * ê₃ + dot(ê₃, ωflagplane2) * ê₃ + dot(ê₄, ωflagplane1) * ê₄ + dot(ê₄, ωflagplane2) * ê₄) + global p = dot(ê₃, normalize(u + v)) * ê₃ + dot(ê₄, normalize(u + v)) * ê₄ + κflagplanematrix = makeflagplane(κflagplane1, κflagplane2, T, segments = segments) + ωflagplanematrix = makeflagplane(ωflagplane1, ωflagplane2, T, segments = segments) + updatesurface!(κflagplanematrix, κflagplaneobservable) + updatesurface!(ωflagplanematrix, ωflagplaneobservable) + planematrix = makeplane(𝕍( ê₁), 𝕍( ê₂), M) # the timelike 2-plane spanned by the flagpoles of κ and ω + # σ, the spacelike 2-plane through O, which is the orthogonal complement of the timelike 2-plane spanned by the flagpoles of κ and ω + orthogonalplanematrix = makeplane(𝕍( ê₃), 𝕍( ê₄), M) updatesurface!(planematrix, planeobservable) updatesurface!(orthogonalplanematrix, orthogonalplaneobservable) hue = Float64(frame) / Float64(frames_number) * 360.0 - planecolor[] = fill(RGBAf(convert_hsvtorgb([hue; 1.0; 1.0])..., 0.5), segments, segments) - orthogonalplanecolor[] = fill(RGBAf(convert_hsvtorgb([360.0 - hue; 1.0; 1.0])..., 0.5), segments, segments) - - κhead[] = Point3f(vec(project(κ_transformed))...) - ωhead[] = Point3f(vec(project(ω_transformed))...) - uhead[] = Point3f(vec(project(u_transformed))...) - vhead[] = Point3f(vec(project(v_transformed))...) - phead[] = Point3f(vec(project(p_transformed))...) - + planecolor[] = fill(RGBAf(convert_hsvtorgb([hue; 0.5; 0.5])..., 0.5), segments, segments) + orthogonalplanecolor[] = fill(RGBAf(convert_hsvtorgb([360.0 - hue; 0.5; 0.5])..., 0.5), segments, segments) + κhead[] = Point3f(project(ℝ⁴(_κv))) + ωhead[] = Point3f(project(ℝ⁴(_ωv))) + uhead[] = Point3f(project(u)) + vhead[] = Point3f(project(v)) + phead[] = Point3f(project(p)) _arcpoints = Point3f[] _arccolors = Int[] - for (i, scale) in enumerate(collection) - vector = M * normalize(ℍ(vec(scale * u + (1.0 - scale) * v))) - point = Point3f(vec(project(vector))...) + for (i, scale) in enumerate(collect(range(0.0, stop = 1.0, length = segments))) + vector = normalize(scale * u + (1.0 - scale) * v) + point = Point3f(project(vector)) push!(_arcpoints, point) push!(_arccolors, i) end @@ -223,40 +156,12 @@ animate(frame::Int) = begin arccolors[] = _arccolors notify(arcpoints) notify(arccolors) - - # the flag planes - for (i, scale1) in enumerate(collection) - _κlinepoints = Point3f[] - _ωlinepoints = Point3f[] - _κlinecolors = Int[] - _ωlinecolors = Int[] - for (j, scale2) in enumerate(collection) - κvector = M * normalize(ℍ(vec(scale1 * κ + scale2 * 𝕍(LinearAlgebra.normalize(vec(κ′ - κ)))))) - ωvector = M * normalize(ℍ(vec(scale1 * ω + scale2 * 𝕍(LinearAlgebra.normalize(vec(ω′ - ω)))))) - κpoint = Point3f(vec(project(κvector))...) - ωpoint = Point3f(vec(project(ωvector))...) - push!(_κlinepoints, κpoint) - push!(_ωlinepoints, ωpoint) - push!(_κlinecolors, i + j) - push!(_ωlinecolors, i + j) - end - κlinepoints[i][] = _κlinepoints - ωlinepoints[i][] = _ωlinepoints - κlinecolors[i][] = _κlinecolors - ωlinecolors[i][] = _ωlinecolors - notify(κlinepoints[i]) - notify(ωlinepoints[i]) - notify(κlinecolors[i]) - notify(ωlinecolors[i]) - end - updatecamera!(lscene, eyeposition, lookat, up) end animate(1) - record(fig, joinpath("gallery", "$modelname.mp4"), 1:frames_number) do frame animate(frame) end \ No newline at end of file diff --git a/models/newsreport/spacetime/fig121spinvectorsum.jl b/models/newsreport/spacetime/fig121spinvectorsum.jl index ca09b24..923db57 100644 --- a/models/newsreport/spacetime/fig121spinvectorsum.jl +++ b/models/newsreport/spacetime/fig121spinvectorsum.jl @@ -5,7 +5,7 @@ using Porta figuresize = (4096, 2160) -segments = 60 +segments = 360 frames_number = 360 modelname = "fig121spinvectorsum" M = Identity(4) @@ -15,7 +15,14 @@ ẑ = ℝ³([0.0; 0.0; 1.0]) eyeposition = normalize(ℝ³(1.0, 1.0, 1.0)) * float(π) lookat = ℝ³(0.0, 0.0, 0.0) up = normalize(ℝ³(0.0, 0.0, 1.0)) -totalstages = 1 +timesign = 1 +T = Float64(timesign) +ϵ = 0.01 +linewidth = 20 +arrowsize = Vec3f(0.06, 0.08, 0.1) +arrowlinewidth = 0.04 +markersize = 0.05 +mask = load("data/basemap_mask.png") makefigure() = Figure(size = figuresize) fig = with_theme(makefigure, theme_black()) @@ -23,8 +30,6 @@ pl = PointLight(Point3f(0), RGBf(0.0862, 0.0862, 0.0862)) al = AmbientLight(RGBf(0.9, 0.9, 0.9)) lscene = LScene(fig[1, 1], show_axis=false, scenekw = (lights = [pl, al], clear=true, backgroundcolor = :white)) -timesign = -1 -T = Float64(timesign) ο = SpinVector([Complex(1.0); Complex(0.0)], timesign) ι = SpinVector([Complex(0.0); Complex(1.0)], timesign) @assert(isapprox(dot(ο, ι), 1.0), "The inner product of spin vectors $ι and $ο is not unity.") @@ -33,7 +38,6 @@ T = Float64(timesign) generate() = 2rand() - 1 + im * (2rand() - 1) κ = SpinVector(generate(), generate(), timesign) ω = SpinVector(generate(), generate(), timesign) -ϵ = 0.01 ζ = Complex(κ) ζ′ = ζ - 1.0 / √2 * ϵ / κ.a[2] κ = SpinVector(ζ, timesign) @@ -44,11 +48,8 @@ generate() = 2rand() - 1 + im * (2rand() - 1) ω′ = SpinVector(ζ′, timesign) ζ = Complex(κ + ω) τ = SpinVector(ζ, timesign) -ζ′ = Complex(κ′ + ω′) +ζ′ = ζ - 1.0 / √2 * ϵ / τ.a[2] τ′ = SpinVector(ζ′, timesign) -gauge1 = -imag(dot(κ, ω)) -gauge2 = -imag(dot(κ, τ)) -gauge3 = float(π) @assert(isapprox(dot(κ, ι), vec(κ)[1]), "The first component of the spin vector $κ is not equal to the inner product of $κ and $ι.") @assert(isapprox(dot(κ, ο), -vec(κ)[2]), "The second component of the spin vector $κ is not equal to minus the inner product of $κ and $ο.") @assert(isapprox(dot(ω, ι), vec(ω)[1]), "The first component of the spin vector $ω is not equal to the inner product of $ω and $ι.") @@ -59,289 +60,111 @@ gauge3 = float(π) w = (Complex(κ + ω) - Complex(κ)) / (Complex(ω) - Complex(κ)) @assert(imag(w) ≤ 0 || isapprox(imag(w), 0.0), "The flagpoles are not collinear: $(Complex(κ)), $(Complex(ω)), $(Complex(κ + ω))") - -center = (Complex(ω) - Complex(κ)) * (w - abs(w)^2) / (2im * imag(w)) + Complex(κ) # Simplified denominator -radius = abs(Complex(κ) - center) - - -t = 𝕍(1.0, 0.0, 0.0, 0.0) -x = 𝕍(0.0, 1.0, 0.0, 0.0) -y = 𝕍(0.0, 0.0, 1.0, 0.0) -z = 𝕍(0.0, 0.0, 0.0, 1.0) -οv = √2 * (t + z) -ιv = √2 * (t - z) -οv = 𝕍( LinearAlgebra.normalize(vec(𝕍(ο)))) -ιv = 𝕍( LinearAlgebra.normalize(vec(𝕍(ι)))) +κv = 𝕍( normalize(ℝ⁴(𝕍( κ)))) +κ′v = 𝕍( normalize(ℝ⁴(𝕍( κ′)))) +ωv = 𝕍( normalize(ℝ⁴(𝕍( ω)))) +ω′v = 𝕍( normalize(ℝ⁴(𝕍( ω′)))) +τv = 𝕍( normalize(ℝ⁴(𝕍(τ)))) +τ′v = 𝕍( normalize(ℝ⁴(𝕍(τ′)))) -κv = 𝕍(κ) -κv′ = 𝕍(κ′) -ωv = 𝕍(ω) -ωv′ = 𝕍(ω′) -τv = 𝕍(τ) -τv′ = 𝕍(τ′) -zero = 𝕍(0.0, 0.0, 0.0, 0.0) -B = stack([vec(κv), vec(ωv), vec(zero), vec(zero)]) -N = LinearAlgebra.nullspace(B) -a = 𝕍(N[begin:end, 1]) -b = 𝕍(N[begin:end, 2]) - -a = 𝕍(LinearAlgebra.normalize(vec(a - κv - ωv))) -b = 𝕍(LinearAlgebra.normalize(vec(b - κv - ωv))) - -v₁ = κv.a -v₂ = ωv.a -v₃ = a.a -v₄ = b.a - -e₁ = v₁ -ê₁ = normalize(e₁) -e₂ = v₂ - dot(ê₁, v₂) * ê₁ -ê₂ = normalize(e₂) -e₃ = v₃ - dot(ê₁, v₃) * ê₁ - dot(ê₂, v₃) * ê₂ -ê₃ = normalize(e₃) -e₄ = v₄ - dot(ê₁, v₄) * ê₁ - dot(ê₂, v₄) * ê₂ - dot(ê₃, v₄) * ê₃ -ê₄ = normalize(e₄) - -ê₁ = 𝕍(ê₁) -ê₂ = 𝕍(ê₂) -ê₃ = 𝕍(ê₃) -ê₄ = 𝕍(ê₄) - -u = 𝕍(LinearAlgebra.normalize(rand(4))) -v = 𝕍(LinearAlgebra.normalize(rand(4))) -p = 𝕍(LinearAlgebra.normalize(vec(u + v))) - -arrowsize = Vec3f(0.06, 0.08, 0.1) -linewidth = 0.04 -tail = Observable(Point3f(0.0, 0.0, 0.0)) -οtail = Observable(Point3f(0.0, 0.0, 0.0)) -ιtail = Observable(Point3f(0.0, 0.0, 0.0)) κtail = Observable(Point3f(0.0, 0.0, 0.0)) ωtail = Observable(Point3f(0.0, 0.0, 0.0)) τtail = Observable(Point3f(0.0, 0.0, 0.0)) -thead = Observable(Point3f(vec(project(ℍ(vec(t))))...)) -xhead = Observable(Point3f(vec(project(ℍ(vec(x))))...)) -yhead = Observable(Point3f(vec(project(ℍ(vec(y))))...)) -zhead = Observable(Point3f(vec(project(ℍ(vec(z))))...)) -οhead = Observable(Point3f(vec(project(ℍ(vec(οv))))...)) -ιhead = Observable(Point3f(vec(project(ℍ(vec(ιv))))...)) -κhead = Observable(Point3f(vec(project(ℍ(vec(κv))))...)) -ωhead = Observable(Point3f(vec(project(ℍ(vec(ωv))))...)) -τhead = Observable(Point3f(vec(project(ℍ(vec(τv))))...)) -uhead = Observable(Point3f(vec(project(ℍ(vec(u))))...)) -vhead = Observable(Point3f(vec(project(ℍ(vec(v))))...)) -phead = Observable(Point3f(vec(project(ℍ(vec(p))))...)) -ps = @lift([$tail, $tail, $tail, $tail, $οtail, $ιtail, $κtail, $ωtail, $τtail, $tail, $tail, $tail]) -ns = @lift([$thead, $xhead, $yhead, $zhead, $οhead, $ιhead, $κhead, $ωhead, $τhead, $uhead, $vhead, $phead]) -colorants = [:red, :blue, :green, :orange, :black, :silver, :purple, :navyblue, :olive, :purple, :navyblue, :gold] +κhead = Observable(Point3f(project(ℍ(vec(κv))))) +ωhead = Observable(Point3f(project(ℍ(vec(ωv))))) +τhead = Observable(Point3f(project(ℍ(vec(τv))))) +ps = @lift([$κtail, $ωtail, $τtail]) +ns = @lift([$κhead, $ωhead, $τhead]) +colorants = [:red, :green, :blue] arrows!(lscene, ps, ns, fxaa = true, # turn on anti-aliasing color = colorants, - linewidth = linewidth, arrowsize = arrowsize, + linewidth = arrowlinewidth, arrowsize = arrowsize, align = :origin ) -linewidth = 20 -collection = collect(range(0.0, stop = 1.0, length = segments)) -κlinepoints = [] -ωlinepoints = [] -τlinepoints = [] -κlinecolors = [] -ωlinecolors = [] -τlinecolors = [] -κlines = [] -ωlines = [] -τlines = [] -for (i, scale1) in enumerate(collection) - _κlinepoints = Observable(Point3f[]) - _ωlinepoints = Observable(Point3f[]) - _τlinepoints = Observable(Point3f[]) - _κlinecolors = Observable(Int[]) - _ωlinecolors = Observable(Int[]) - _τlinecolors = Observable(Int[]) - for (j, scale2) in enumerate(collection) - κvector = LinearAlgebra.normalize(vec(scale1 * κv + scale2 * κv′)) - ωvector = LinearAlgebra.normalize(vec(scale1 * ωv + scale2 * ωv′)) - τvector = LinearAlgebra.normalize(vec(scale1 * τv + scale2 * τv′)) - κpoint = Point3f(vec(project(ℍ(κvector)))...) - ωpoint = Point3f(vec(project(ℍ(ωvector)))...) - τpoint = Point3f(vec(project(ℍ(τvector)))...) - push!(_κlinepoints[], κpoint) - push!(_ωlinepoints[], ωpoint) - push!(_τlinepoints[], τpoint) - push!(_κlinecolors[], i + j) - push!(_ωlinecolors[], i + j) - push!(_τlinecolors[], i + j) - end - push!(κlinepoints, _κlinepoints) - push!(ωlinepoints, _ωlinepoints) - push!(τlinepoints, _τlinepoints) - push!(κlinecolors, _κlinecolors) - push!(ωlinecolors, _ωlinecolors) - push!(τlinecolors, _τlinecolors) - κline = lines!(lscene, κlinepoints[i], color = κlinecolors[i], linewidth = linewidth, colorrange = (1, 2segments), colormap = :fall) - ωline = lines!(lscene, ωlinepoints[i], color = ωlinecolors[i], linewidth = linewidth, colorrange = (1, 2segments), colormap = :winter) - τline = lines!(lscene, τlinepoints[i], color = τlinecolors[i], linewidth = linewidth, colorrange = (1, 2segments), colormap = :rainbow) - push!(κlines, κline) - push!(ωlines, ωline) - push!(τlines, τline) -end - -arcpoints = Observable(Point3f[]) -arccolors = Observable(Int[]) -arc = lines!(lscene, arcpoints, color = arccolors, linewidth = 3linewidth, colorrange = (1, segments), colormap = :prism) - circlepoints = Observable(Point3f[]) circlecolors = Observable(Int[]) -circle = lines!(lscene, circlepoints, color = circlecolors, linewidth = 2linewidth, colorrange = (1, segments), colormap = :Paired_12) +circle = lines!(lscene, circlepoints, color = circlecolors, linewidth = 2linewidth, colorrange = (1, segments), colormap = :rainbow) -titles = ["t", "x", "y", "z", "ο", "ι", "κ", "ω", "κ+ω", "U", "V", "p"] +titles = ["L", "M", "N", "P", "Q", "R"] rotation = gettextrotation(lscene) text!(lscene, - @lift(map(x -> Point3f(vec((isnan(x) ? ẑ : x))), [$thead, $xhead, $yhead, $zhead, $οhead + $οtail, $ιhead + $ιtail, $κhead + $κtail, $ωhead + $ωtail, $τhead + $τtail, $uhead, $vhead, $phead])), + @lift(map(x -> Point3f(vec((isnan(x) ? ẑ : x))), [$κhead + $κtail, $ωhead + $ωtail, $τhead + $τtail, $κtail, $ωtail, $τtail])), text = titles, - color = colorants[begin:end], + color = [colorants..., colorants...], rotation = rotation, align = (:left, :baseline), fontsize = 0.25, markerspace = :data ) -planematrix = makeplane(κv, ωv, M) -planecolor = Observable(fill(RGBAf(0.5, 0.5, 0.5, 0.5), segments, segments)) -planeobservable = buildsurface(lscene, planematrix, planecolor, transparency = true) - -orthogonalplanematrix = makeplane(a, b, M) -orthogonalplanecolor = Observable(fill(RGBAf(0.5, 0.5, 0.5, 0.5), segments, segments)) -orthogonalplaneobservable = buildsurface(lscene, orthogonalplanematrix, orthogonalplanecolor, transparency = true) +spherematrix = makesphere(M, T, compressedprojection = true, segments = segments) +sphereobservable = buildsurface(lscene, spherematrix, mask, transparency = true) -κflagplanematrix = makeflagplane(κv, κv′ - κv, T, segments = segments) -κflagplanecolor = Observable(fill(RGBAf(0.5, 0.5, 0.5, 0.5), segments, segments)) +κflagplanematrix = makeflagplane(κv, κ′v - κv, T, segments = segments) +κflagplanecolor = Observable(fill(RGBAf(1.0, 0.0, 0.0, 0.8), segments, segments)) κflagplaneobservable = buildsurface(lscene, κflagplanematrix, κflagplanecolor, transparency = false) -ωflagplanematrix = makeflagplane(ωv, ωv′ - ωv, T, segments = segments) -ωflagplanecolor = Observable(fill(RGBAf(0.5, 0.5, 0.5, 0.5), segments, segments)) +ωflagplanematrix = makeflagplane(ωv, ω′v - ωv, T, segments = segments) +ωflagplanecolor = Observable(fill(RGBAf(0.0, 1.0, 0.0, 0.8), segments, segments)) ωflagplaneobservable = buildsurface(lscene, ωflagplanematrix, ωflagplanecolor, transparency = false) -τflagplanematrix = makeflagplane(τv, τv′ - τv, T, segments = segments) -τflagplanecolor = Observable(fill(RGBAf(0.5, 0.5, 0.5, 0.5), segments, segments)) +τflagplanematrix = makeflagplane(τv, τ′v - τv, T, segments = segments) +τflagplanecolor = Observable(fill(RGBAf(0.0, 0.0, 1.0, 0.8), segments, segments)) τflagplaneobservable = buildsurface(lscene, τflagplanematrix, τflagplanecolor, transparency = false) -meshscatter!(lscene, tail, markersize = 0.05, color = :black) -meshscatter!(lscene, κtail, markersize = 0.05, color = :purple) -meshscatter!(lscene, ωtail, markersize = 0.05, color = :navyblue) -meshscatter!(lscene, τtail, markersize = 0.05, color = :olive) +meshscatter!(lscene, κtail, markersize = markersize, color = colorants[1]) +meshscatter!(lscene, ωtail, markersize = markersize, color = colorants[2]) +meshscatter!(lscene, τtail, markersize = markersize, color = colorants[3]) -animate1(frame::Int) = begin - κflagplanedirection = 𝕍(LinearAlgebra.normalize(vec(κv′ - κv))) - ωflagplanedirection = 𝕍(LinearAlgebra.normalize(vec(ωv′ - ωv))) - global u = LinearAlgebra.normalize(vec((-dot(ê₃, κflagplanedirection) * ê₃ + -dot(ê₄, κflagplanedirection) * ê₄))) - global v = LinearAlgebra.normalize(vec((-dot(ê₃, ωflagplanedirection) * ê₃ + -dot(ê₄, ωflagplanedirection) * ê₄))) - p = -𝕍(LinearAlgebra.normalize(u + v)) - global p = dot(ê₃, p) * ê₃ + dot(ê₄, p) * ê₄ - axis = normalize(ℝ³(vec(p)[2:4])) +animate(frame::Int) = begin progress = Float64(frame / frames_number) - M = mat4(ℍ(progress * 4π, axis)) - t_transformed = M * ℍ(vec(t)) - x_transformed = M * ℍ(vec(x)) - y_transformed = M * ℍ(vec(y)) - z_transformed = M * ℍ(vec(z)) - ο_transformed = M * ℍ(vec(οv)) - ι_transformed = M * ℍ(vec(ιv)) - κ_transformed = M * ℍ(vec(κv)) - κ′_transformed = M * ℍ(vec(κv′)) - ω_transformed = M * ℍ(vec(ωv)) - ω′_transformed = M * ℍ(vec(ωv′)) - τ_transformed = M * ℍ(vec(τv)) - τ′_transformed = M * ℍ(vec(τv′)) - u_transformed = M * ℍ(vec(u)) - v_transformed = M * ℍ(vec(v)) - p_transformed = M * ℍ(vec(p)) - planematrix = makeplane(ê₁, ê₂, M) # the timelike 2-plane spanned by the flagpoles of κ and ω - orthogonalplanematrix = makeplane(ê₃, ê₄, M) # σ, the spacelike 2-plane through O, which is the orthogonal complement of the timelike 2-plane spanned by the flagpoles of κ and ω - updatesurface!(planematrix, planeobservable) - updatesurface!(orthogonalplanematrix, orthogonalplaneobservable) - hue = Float64(frame) / Float64(frames_number) * 360.0 - planecolor[] = [RGBAf(convert_hsvtorgb([hue; 1.0; 1.0])..., 0.25) for i in 1:segments, j in 1:segments] - orthogonalplanecolor[] = [RGBAf(convert_hsvtorgb([360.0 - hue; 1.0; 1.0])..., 0.25) for i in 1:segments, j in 1:segments] - _κ = 𝕍( vec(κ_transformed)) - _κ′ = 𝕍( vec(κ′_transformed)) - _ω = 𝕍( vec(ω_transformed)) - _ω′ = 𝕍( vec(ω′_transformed)) - _τ = 𝕍( vec(τ_transformed)) - _τ′ = 𝕍( vec(τ′_transformed)) - κflagplanematrix = makeflagplane(𝕍(vec(_κ)), 𝕍(LinearAlgebra.normalize(vec(_κ′ - _κ))), T, segments = segments) - ωflagplanematrix = makeflagplane(𝕍(vec(_ω)), 𝕍(LinearAlgebra.normalize(vec(_ω′ - _ω))), T, segments = segments) - τflagplanematrix = makeflagplane(𝕍(vec(_τ)), 𝕍(LinearAlgebra.normalize(vec(_τ′ - _τ))), T, segments = segments) + println("Frame: $frame, Progress: $progress") + spintransform = SpinTransformation(progress * 2π, progress * 2π, progress * 2π) + _κ = spintransform * κ + _ω = spintransform * ω + _κ′ = spintransform * κ′ + _ω′ = spintransform * ω′ + _κv = 𝕍( normalize(ℝ⁴(𝕍( _κ)))) + _κ′v = 𝕍( normalize(ℝ⁴(𝕍( _κ′)))) + _ωv = 𝕍( normalize(ℝ⁴(𝕍( _ω)))) + _ω′v = 𝕍( normalize(ℝ⁴(𝕍( _ω′)))) + _τ = _κ + _ω + _τ′ = SpinVector(Complex(_τ) - 1.0 / √2 * ϵ / _τ.a[2], timesign) + _τv = 𝕍( normalize(ℝ⁴(𝕍( _τ)))) + _τ′v = 𝕍( normalize(ℝ⁴(𝕍( _τ′)))) + ê₁, ê₂, ê₃, ê₄ = calculatebasisvectors(_κ, _ω) + κflagplane1 = _κv + κflagplane2 = 𝕍(normalize(ℝ⁴(_κ′v - _κv))) + ωflagplane1 = _ωv + ωflagplane2 = 𝕍(normalize(ℝ⁴(_ω′v - _ωv))) + τflagplane1 = _τv + τflagplane2 = 𝕍(normalize(ℝ⁴(_τ′v - _τv))) + global u = normalize(dot(ê₃, κflagplane1) * ê₃ + dot(ê₃, κflagplane2) * ê₃ + dot(ê₄, κflagplane1) * ê₄ + dot(ê₄, κflagplane2) * ê₄) + global v = normalize(dot(ê₃, ωflagplane1) * ê₃ + dot(ê₃, ωflagplane2) * ê₃ + dot(ê₄, ωflagplane1) * ê₄ + dot(ê₄, ωflagplane2) * ê₄) + spherematrix = makesphere(spintransform, T, compressedprojection = true, segments = segments) + updatesurface!(spherematrix, sphereobservable) + κflagplanematrix = makeflagplane(κflagplane1, κflagplane2, T, segments = segments) + ωflagplanematrix = makeflagplane(ωflagplane1, ωflagplane2, T, segments = segments) + τflagplanematrix = makeflagplane(τflagplane1, τflagplane2, T, segments = segments) updatesurface!(κflagplanematrix, κflagplaneobservable) updatesurface!(ωflagplanematrix, ωflagplaneobservable) updatesurface!(τflagplanematrix, τflagplaneobservable) - κflagplanecolor[] = [RGBAf(convert_hsvtorgb([277.0; 0.87; 0.94])..., 0.8) for i in 1:segments, j in 1:segments] - ωflagplanecolor[] = [RGBAf(convert_hsvtorgb([240.0; 1.0; 0.5])..., 0.8) for i in 1:segments, j in 1:segments] - τflagplanecolor[] = [RGBAf(convert_hsvtorgb([58.0; 0.42; 0.73])..., 0.5) for i in 1:segments, j in 1:segments] - κhead[] = Point3f(vec(project(ℍ(LinearAlgebra.normalize(vec(κ_transformed - κ′_transformed)))))...) - ωhead[] = Point3f(vec(project(ℍ(LinearAlgebra.normalize(vec(ω_transformed - ω′_transformed)))))...) - τhead[] = Point3f(vec(project(ℍ(LinearAlgebra.normalize(vec(τ_transformed - τ′_transformed)))))...) - κtail[] = Point3f(vec(project(κ_transformed))...) - ωtail[] = Point3f(vec(project(ω_transformed))...) - τtail[] = Point3f(vec(project(τ_transformed))...) - οtail[] = Point3f(vec(project(κ_transformed))...) - ιtail[] = Point3f(vec(project(κ_transformed))...) - οhead[] = Point3f(vec(project(ℍ(LinearAlgebra.normalize(vec(ο_transformed)))))...) * 0.25 - ιhead[] = Point3f(vec(project(ℍ(LinearAlgebra.normalize(vec(ι_transformed)))))...) * 0.25 - thead[] = Point3f(vec(project(t_transformed))...) * 0.5 - xhead[] = Point3f(vec(project(x_transformed))...) * 0.5 - yhead[] = Point3f(vec(project(y_transformed))...) * 0.5 - zhead[] = Point3f(vec(project(z_transformed))...) * 0.5 - uhead[] = Point3f(vec(project(u_transformed))...) - vhead[] = Point3f(vec(project(v_transformed))...) - phead[] = Point3f(vec(project(p_transformed))...) - point = project(κ_transformed) + project(ω_transformed) + project(τ_transformed) - point = any(isnan.(vec(point))) ? ẑ : normalize(point) - position1 = cross(project(κ_transformed), project(ω_transformed)) - position2 = cross(project(u_transformed), project(v_transformed)) - position1 = any(isnan.(vec(position1))) ? ẑ : normalize(position1) - position2 = any(isnan.(vec(position2))) ? ẑ : normalize(position2) - ratio = frame == 1 ? 1.0 : 0.05 - global lookat = ratio * point + (1 - ratio) * lookat - global eyeposition = ratio * normalize(position1 + position2 + point) * float(π) + (1 - ratio) * eyeposition -end - - -animate(frame::Int) = begin - animate1(frame) - progress = Float64(frame / frames_number) - stage = min(totalstages - 1, Int(floor(totalstages * progress))) + 1 - stageprogress = totalstages * (progress - (stage - 1) * 1.0 / totalstages) - println("Frame: $frame, Stage: $stage, Total Stages: $totalstages, Progress: $stageprogress") - κflagplanedirection = 𝕍(LinearAlgebra.normalize(vec(κv′ - κv))) - ωflagplanedirection = 𝕍(LinearAlgebra.normalize(vec(ωv′ - ωv))) - global u = LinearAlgebra.normalize(vec((-dot(ê₃, κflagplanedirection) * ê₃ + -dot(ê₄, κflagplanedirection) * ê₄))) - global v = LinearAlgebra.normalize(vec((-dot(ê₃, ωflagplanedirection) * ê₃ + -dot(ê₄, ωflagplanedirection) * ê₄))) - p = -𝕍(LinearAlgebra.normalize(u + v)) - global p = dot(ê₃, p) * ê₃ + dot(ê₄, p) * ê₄ - axis = normalize(ℝ³(vec(p)[2:4])) - M = mat4(ℍ(progress * 4π, axis)) - _arcpoints = Point3f[] - _arccolors = Int[] - for (i, scale) in enumerate(collection) - vector = M * normalize(ℍ(vec(scale * u + (1.0 - scale) * v))) - point = Point3f(vec(project(vector))...) - push!(_arcpoints, point) - push!(_arccolors, i) - end - arcpoints[] = _arcpoints - arccolors[] = _arccolors - notify(arcpoints) - notify(arccolors) + κtail[] = Point3f(project(ℝ⁴(_κv))) + ωtail[] = Point3f(project(ℝ⁴(_ωv))) + τtail[] = Point3f(project(ℝ⁴(_τv))) + κhead[] = Point3f(project(normalize(ℝ⁴(_κ′v - _κv)))) + ωhead[] = Point3f(project(normalize(ℝ⁴(_ω′v - _ωv)))) + τhead[] = Point3f(project(normalize(ℝ⁴(_τ′v - _τv)))) _circlepoints = Point3f[] _circlecolors = Int[] for (i, ϕ) in enumerate(collect(range(-4π, stop = 4π, length = segments))) - κζ = Complex(κ) - ωζ = Complex(ω) + κζ = Complex(_κ) + ωζ = Complex(_ω) ζ = κζ - ωζ - circlevector = M * ℍ(vec(𝕍(SpinVector(κζ + ϕ * ζ, timesign)))) - circlepoint = Point3f(vec(project(circlevector))...) + circlevector = normalize(ℝ⁴(𝕍( SpinVector(κζ + ϕ * ζ, timesign)))) + circlepoint = Point3f(project(circlevector)) push!(_circlepoints, circlepoint) push!(_circlecolors, i) end @@ -349,41 +172,6 @@ animate(frame::Int) = begin circlecolors[] = _circlecolors notify(circlepoints) notify(circlecolors) - # the flag planes - for (i, scale1) in enumerate(collection) - _κlinepoints = Point3f[] - _ωlinepoints = Point3f[] - _τlinepoints = Point3f[] - _κlinecolors = Int[] - _ωlinecolors = Int[] - _τlinecolors = Int[] - for (j, scale2) in enumerate(collection) - κvector = M * normalize(ℍ(vec(scale1 * κv + scale2 * 𝕍(LinearAlgebra.normalize(vec(κv - κv′)))))) - ωvector = M * normalize(ℍ(vec(scale1 * ωv + scale2 * 𝕍(LinearAlgebra.normalize(vec(ωv - ωv′)))))) - τvector = M * normalize(ℍ(vec(scale1 * τv + scale2 * 𝕍(LinearAlgebra.normalize(vec(τv - τv′)))))) - κpoint = Point3f(vec(project(κvector))...) - ωpoint = Point3f(vec(project(ωvector))...) - τpoint = Point3f(vec(project(τvector))...) - push!(_κlinepoints, κpoint) - push!(_ωlinepoints, ωpoint) - push!(_τlinepoints, τpoint) - push!(_κlinecolors, i + j) - push!(_ωlinecolors, i + j) - push!(_τlinecolors, i + j) - end - κlinepoints[i][] = _κlinepoints - ωlinepoints[i][] = _ωlinepoints - τlinepoints[i][] = _τlinepoints - κlinecolors[i][] = _κlinecolors - ωlinecolors[i][] = _ωlinecolors - τlinecolors[i][] = _τlinecolors - notify(κlinepoints[i]) - notify(ωlinepoints[i]) - notify(τlinepoints[i]) - notify(κlinecolors[i]) - notify(ωlinecolors[i]) - notify(τlinecolors[i]) - end updatecamera!(lscene, eyeposition, lookat, up) end diff --git a/src/spacetime/minkowskivectorspace.jl b/src/spacetime/minkowskivectorspace.jl index 61c81ae..4248641 100644 --- a/src/spacetime/minkowskivectorspace.jl +++ b/src/spacetime/minkowskivectorspace.jl @@ -58,4 +58,6 @@ lorentznorm(u::𝕍) = dot(u, u, mat(tetrad)) istimelike(u::𝕍) = lorentznorm(u) > 0.0 isspacelike(u::𝕍) = lorentznorm(u) < 0.0 isnull(u::𝕍; atol::Float64 = TOLERANCE) = isapprox(lorentznorm(u), 0.0, atol = atol) -iscausal(u::𝕍) = istimelike(u) || isnull(u) \ No newline at end of file +iscausal(u::𝕍) = istimelike(u) || isnull(u) + +ℝ⁴(v::𝕍) = ℝ⁴(vec(v)) \ No newline at end of file diff --git a/src/utilities.jl b/src/utilities.jl index a89e059..d63d721 100644 --- a/src/utilities.jl +++ b/src/utilities.jl @@ -15,6 +15,7 @@ export makeplane export projectontoplane export constructtorus export constructsphere +export calculatebasisvectors """ @@ -342,4 +343,35 @@ function constructsphere(q::Dualquaternion, end end map(x -> x + gettranslation(q), rotate(array, getrotation(q))) +end + + +""" + calculatebasisvectors(κ, ω) + +Calculate an orthonormal set of basis vectors with the given spin-vectors `κ` and `ω`. +""" +function calculatebasisvectors(κ::SpinVector, ω::SpinVector) + κv = 𝕍( κ) + ωv = 𝕍( ω) + zero = 𝕍( 0.0, 0.0, 0.0, 0.0) + B = stack([vec(κv), vec(ωv), vec(zero), vec(zero)]) + N = LinearAlgebra.nullspace(B) + a = 𝕍(N[begin:end, 1]) + b = 𝕍(N[begin:end, 2]) + a = 𝕍(LinearAlgebra.normalize(vec(a - κv - ωv))) + b = 𝕍(LinearAlgebra.normalize(vec(b - κv - ωv))) + v₁ = ℝ⁴(κv) + v₂ = ℝ⁴(ωv) + v₃ = ℝ⁴(a) + v₄ = ℝ⁴(b) + e₁ = v₁ + ê₁ = normalize(e₁) + e₂ = v₂ - dot(ê₁, v₂) * ê₁ + ê₂ = normalize(e₂) + e₃ = v₃ - dot(ê₁, v₃) * ê₁ - dot(ê₂, v₃) * ê₂ + ê₃ = normalize(e₃) + e₄ = v₄ - dot(ê₁, v₄) * ê₁ - dot(ê₂, v₄) * ê₂ - dot(ê₃, v₄) * ê₃ + ê₄ = normalize(e₄) + ê₁, ê₂, ê₃, ê₄ end \ No newline at end of file