Skip to content

Commit

Permalink
Showed how to go from 4pi rotation to no rotation with spin transform…
Browse files Browse the repository at this point in the history
…ations.
  • Loading branch information
iamazadi committed Oct 30, 2024
1 parent f50a34b commit 945a0cb
Show file tree
Hide file tree
Showing 4 changed files with 219 additions and 8 deletions.
2 changes: 2 additions & 0 deletions docs/src/newsreport.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,8 @@ A spin-vector is named kappa and another spin-vector is named omega. The extra p

![13](./assets/spinspace/13.PNG)

[Dirac's scissors problem](https://github.com/iamazadi/Porta.jl/blob/master/models/newsreport/spacetime/fig113diracsscissors.jl)

```julia
κ = 𝕍(κ)
κ′ = 𝕍(κ′)
Expand Down
5 changes: 2 additions & 3 deletions src/clutchingfunction.jl
Original file line number Diff line number Diff line change
Expand Up @@ -228,12 +228,12 @@ function updateui(chart::Bool, p₁::ℝ⁴,
end

_v = GLMakie.to_value(tangentvector)
# println("_v: ($_v), h: ($h).")
# println("_v: ($_v), p₁: ($p₁).")
if !isapprox(dot(_v, p₁), 0)
perp = dot(_v, p₁) * p₁
_v = normalize(_v - perp)
end
# @assert(isapprox(_v, ℝ⁴(h)) && !isapprox(dot(_v, ℝ⁴(h)), 0), "_v ($_v) is not perpendicular to q ($q).")
# @assert(isapprox(dot(_v, p₁), 0), "_v ($_v) is not perpendicular to p₁ ($p₁).")
tangentvector[] = _v
tail[] = GLMakie.Point3f(r)
g = (tangentvector[])
Expand Down Expand Up @@ -396,7 +396,6 @@ switchcharts(chart::String, charttoggle::GLMakie.Observable{Any}) = begin
end



"""
paralleltransport(path, t, points, chart, p₁, tail,
arrowx¹head, arrowx²head, arrowx³head, ghostps, ghostns,
Expand Down
192 changes: 192 additions & 0 deletions src/spacetime/fig113diracsscissors.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
import FileIO
import GLMakie
import LinearAlgebra
using Porta


figuresize = (4096, 2160)
segments = 360
frames_number = 360
modelname = "fig113diracsscissors"

M = I(4)
= ℝ³([1.0; 0.0; 0.0])
= ℝ³([0.0; 1.0; 0.0])
= ℝ³([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
mask = FileIO.load("data/basemap_mask.png")

makefigure() = GLMakie.Figure(size = figuresize)
fig = GLMakie.with_theme(makefigure, GLMakie.theme_black())
pl = GLMakie.PointLight(GLMakie.Point3f(0), GLMakie.RGBf(0.0862, 0.0862, 0.0862))
al = GLMakie.AmbientLight(GLMakie.RGBf(0.9, 0.9, 0.9))
lscene = GLMakie.LScene(fig[1, 1], show_axis=false, scenekw = (lights = [pl, al], clear=true, backgroundcolor = :white))

T = 1.0
spherematrix = makesphere(M, T, segments = segments)
sphereobservable = buildsurface(lscene, spherematrix, mask, transparency = true)
planematrix = makestereographicprojectionplane(M, T = T, segments = segments)
planeobservable = buildsurface(lscene, planematrix, mask, transparency = true)
ϵ = 0.1
transformation = SpinTransformation+ rand() * 0.1, ϵ + rand() * 0.1, ϵ + rand() * 0.1)

generate() = 2rand() - 1 + im * (2rand() - 1)
κ = SpinVector(generate(), generate(), Int(T))
ζ = Complex(κ)
κ = SpinVector(ζ, Int(T))
ζ′ = ζ - (1.0 / 2) * ϵ * (1.0 / κ.a[2]^2)
κ′ = SpinVector(ζ′, Int(T))

ζ″ = ζ′ - (1.0 / 2) * ϵ * (1.0 / κ′.a[2]^2)
κ″ = transformation * SpinVector(ζ″, Int(T))
κv = 𝕍(κ)
κ′v = 𝕍(κ′)
κ″v = 𝕍(κ″)

linewidth = 20
κlinepoints = []
κlinecolors = []
for (i, scale1) in enumerate(collect(range(0.0, stop = 1.0, length = segments)))
_κlinepoints = GLMakie.Observable(GLMakie.Point3f[])
_κlinecolors = GLMakie.Observable(Int[])
for (j, scale2) in enumerate(collect(range(0.0, stop = 1.0, length = segments)))
κvector = LinearAlgebra.normalize(vec(scale1 * κv + scale2 * κ′v))
κpoint = GLMakie.Point3f(projectnocompression((κvector)))
push!(_κlinepoints[], κpoint)
push!(_κlinecolors[], i + j)
end
push!(κlinepoints, _κlinepoints)
push!(κlinecolors, _κlinecolors)
GLMakie.lines!(lscene, κlinepoints[i], color = κlinecolors[i], linewidth = linewidth, colorrange = (1, 2segments), colormap = :rainbow)
end

arrowsize = GLMakie.Vec3f(0.06, 0.08, 0.1)
linewidth = 0.04
origin = GLMakie.Observable(GLMakie.Point3f(0.0, 0.0, 0.0))
northpole = GLMakie.Observable(GLMakie.Point3f(0.0, 0.0, 1.0))
κobservable = GLMakie.Observable(GLMakie.Point3f(projectnocompression(normalize((vec(κv))))))
κ′observable = GLMakie.Observable(GLMakie.Point3f(projectnocompression(normalize((vec(κ′v))))))
κ″observable = GLMakie.Observable(GLMakie.Point3f(projectnocompression(normalize((vec(κ″v))))))
κprojectionobservable = GLMakie.Observable(GLMakie.Point3f(projectontoplane(κv)))
κ′projectionobservable = GLMakie.Observable(GLMakie.Point3f(projectontoplane(κ′v)))
κ″projectionobservable = GLMakie.Observable(GLMakie.Point3f(projectontoplane(κ″v)))
ps = GLMakie.@lift([$origin, $κobservable, $origin, $κprojectionobservable,
$origin, $κ′observable, $origin, $κ′projectionobservable,
$origin, $κ″observable, $origin, $κ″projectionobservable])
ns = GLMakie.@lift([$κobservable, LinearAlgebra.normalize($κ′observable - $κobservable), $κprojectionobservable, LinearAlgebra.normalize($κ′projectionobservable - $κprojectionobservable),
$κ′observable, LinearAlgebra.normalize($κ″observable - $κ′observable), $κ′projectionobservable, LinearAlgebra.normalize($κ″projectionobservable - $κ′projectionobservable),
$κ″observable, LinearAlgebra.normalize($κobservable - $κ″observable), $κ″projectionobservable, LinearAlgebra.normalize($κprojectionobservable - $κ″projectionobservable)])
colorants = [:red, :green, :blue, :orange]
GLMakie.arrows!(lscene,
ps, ns, fxaa = true, # turn on anti-aliasing
color = [colorants[1], colorants[4], colorants[1], colorants[4], colorants[2], colorants[4], colorants[2], colorants[4], colorants[3], colorants[4], colorants[3], colorants[4]],
linewidth = linewidth, arrowsize = arrowsize,
align = :origin
)

rotation = gettextrotation(lscene)
titles = ["O", "N", "P", "P′", "P″", "P", "P′", "P″"]
GLMakie.text!(lscene,
GLMakie.@lift(map(x -> GLMakie.Point3f(isnan(x) ?: x), [$origin, $northpole, $κobservable, $κ′observable, $κ″observable, $κprojectionobservable, $κ′projectionobservable, $κ″projectionobservable])),
text = titles,
color = [:gold, :black, colorants[1], colorants[2], colorants[3], colorants[1], colorants[2], colorants[3]],
rotation = rotation,
align = (:left, :baseline),
fontsize = 0.25,
markerspace = :data
)

κflagplanematrix = makeflagplane(κv, κ′v - κv, segments = segments)
κflagplanecolor = GLMakie.Observable(fill(GLMakie.RGBAf(0.5, 0.5, 0.5, 0.5), segments, segments))
κflagplaneobservable = buildsurface(lscene, κflagplanematrix, κflagplanecolor, transparency = false)

κsectional = GLMakie.Observable(GLMakie.Point3f(projectnocompression(normalize((vec(κv))))))
κ′sectional = GLMakie.Observable(GLMakie.Point3f(projectnocompression(normalize((vec(κ′v))))))
κ″sectional = GLMakie.Observable(GLMakie.Point3f(projectnocompression(normalize((vec(κ″v))))))

# balls
GLMakie.meshscatter!(lscene, northpole, markersize = 0.05, color = :black)
GLMakie.meshscatter!(lscene, origin, markersize = 0.05, color = :gold)
GLMakie.meshscatter!(lscene, κobservable, markersize = 0.05, color = colorants[1])
GLMakie.meshscatter!(lscene, κ′observable, markersize = 0.05, color = colorants[2])
GLMakie.meshscatter!(lscene, κ″observable, markersize = 0.05, color = colorants[3])
GLMakie.meshscatter!(lscene, κprojectionobservable, markersize = 0.05, color = colorants[1])
GLMakie.meshscatter!(lscene, κ′projectionobservable, markersize = 0.05, color = colorants[2])
GLMakie.meshscatter!(lscene, κ″projectionobservable, markersize = 0.05, color = colorants[3])
GLMakie.meshscatter!(lscene, κsectional, markersize = 0.05, color = colorants[1])
GLMakie.meshscatter!(lscene, κ′sectional, markersize = 0.05, color = colorants[2])
GLMakie.meshscatter!(lscene, κ″sectional, markersize = 0.05, color = colorants[3])

segmentP = GLMakie.@lift([$northpole, $κobservable, $κprojectionobservable])
segmentP′ = GLMakie.@lift([$northpole, $κ′observable, $κ′projectionobservable])
segmentP″ = GLMakie.@lift([$northpole, $κ″observable, $κ″projectionobservable])
segmentcolors = GLMakie.Observable(collect(1:segments))
linewidth = 8.0
GLMakie.lines!(lscene, segmentP, linewidth = 2linewidth, color = segmentcolors, colormap = :plasma, colorrange = (1, segments), transparency = false)
GLMakie.lines!(lscene, segmentP′, linewidth = 2linewidth, color = segmentcolors, colormap = :plasma, colorrange = (1, segments), transparency = false)
GLMakie.lines!(lscene, segmentP″, linewidth = 2linewidth, color = segmentcolors, colormap = :plasma, colorrange = (1, segments), transparency = false)
GLMakie.lines!(lscene, segmentP, linewidth = 2linewidth, color = segmentcolors, colormap = :plasma, colorrange = (1, segments), transparency = false)
GLMakie.lines!(lscene, segmentP′, linewidth = 2linewidth, color = segmentcolors, colormap = :plasma, colorrange = (1, segments), transparency = false)
GLMakie.lines!(lscene, segmentP″, linewidth = 2linewidth, color = segmentcolors, colormap = :plasma, colorrange = (1, segments), transparency = false)


animate(frame::Int) = begin
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")
θ = progress * 4π
ϕ = 0.0
ψ = 0.0
spintransform = SpinTransformation(θ, ϕ, ψ)
spherematrix = makesphere(spintransform, T, segments = segments)
planematrix = makestereographicprojectionplane(spintransform, T = 1.0, segments = segments)
updatesurface!(planematrix, planeobservable)
updatesurface!(spherematrix, sphereobservable)
κtransformed = 𝕍(spintransform * κ)
κ′transformed = 𝕍(spintransform * κ′)
κ″transformed = 𝕍(spintransform * κ″)
κflagplanematrix = makeflagplane(κtransformed, 𝕍(LinearAlgebra.normalize(vec(κ′transformed - κtransformed))), segments = segments)
updatesurface!(κflagplanematrix, κflagplaneobservable)
κflagplanecolor[] = [GLMakie.RGBAf(convert_hsvtorgb([360.0 * progress; 1.0; 1.0])..., 1.0) for i in 1:segments, j in 1:segments]
κobservable[] = GLMakie.Point3f(projectnocompression(normalize((vec(κtransformed)))))
κ′observable[] = GLMakie.Point3f(projectnocompression(normalize((vec(κ′transformed)))))
κ″observable[] = GLMakie.Point3f(projectnocompression(normalize((vec(κ″transformed)))))
κprojectionobservable[] = GLMakie.Point3f(projectontoplane(κtransformed))
κ′projectionobservable[] = GLMakie.Point3f(projectontoplane(κ′transformed))
κ″projectionobservable[] = GLMakie.Point3f(projectontoplane(κ″transformed))
κsectional[] = (κobservable[] + κprojectionobservable[]) * 0.5
κ′sectional[] = (κ′observable[] + κ′projectionobservable[]) * 0.5
κ″sectional[] = (κ″observable[] + κ″projectionobservable[]) * 0.5
for (i, scale1) in enumerate(collect(range(0.0, stop = 1.0, length = segments)))
_κlinepoints = GLMakie.Point3f[]
_κlinecolors = Int[]
for (j, scale2) in enumerate(collect(range(0.0, stop = 1.0, length = segments)))
κvector = normalize((vec(scale1 * κtransformed + scale2 * 𝕍(LinearAlgebra.normalize(vec(κ′transformed - κtransformed))))))
κpoint = GLMakie.Point3f(projectnocompression(κvector))
push!(_κlinepoints, κpoint)
push!(_κlinecolors, i + j)
end
κlinepoints[i][] = _κlinepoints
κlinecolors[i][] = _κlinecolors
GLMakie.notify(κlinepoints[i])
GLMakie.notify(κlinecolors[i])
end
component = normalize(cross(ℝ³(κobservable[]), ℝ³(κprojectionobservable[])))
global lookat = (1.0 / 3.0) * (ℝ³(κsectional[]) + ℝ³(κ′sectional[]) + ℝ³(κ″sectional[]) + component)
global eyeposition = normalize(ℝ³(northpole[]) + float(π) * component) * float(2π)
updatecamera!(lscene, eyeposition, lookat, up)
end


animate(1)


GLMakie.record(fig, joinpath("gallery", "$modelname.mp4"), 1:frames_number) do frame
animate(frame)
end

# GLMakie.save(joinpath("gallery", "$(modelname)01.png"), fig)
28 changes: 23 additions & 5 deletions src/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import GLMakie.Point3f
import GLMakie.Vec3f
export convert_hsvtorgb
export project
export projectnocompression
export updatecamera!
export gettextrotation
export maketwosphere
Expand Down Expand Up @@ -63,6 +64,23 @@ end
project(q::ℝ⁴) = project((q))


"""
project(q)
Take the given point `q` ∈ S³ ⊂ ℂ² into the Euclidean space E³ ⊂ ℝ³ using stereographic projection.
"""
function projectnocompression(q::ℍ)
if isapprox(norm(q), 0.0)
return ℝ³(0.0, 0.0, 0.0)
else
ℝ³(vec(q)[2], vec(q)[3], vec(q)[4]) * (1.0 / (1.0 - vec(q)[1]))
end
end


projectnocompression(q::ℝ⁴) = projectnocompression((q))


"""
project(p)
Expand Down Expand Up @@ -149,7 +167,7 @@ function makesphere(transformation::SpinTransformation, T::Float64; segments::In
surface = map(x -> 𝕍(T, vec(sign(T) * abs(T) * x)...), sphere)
end
surface = map(x -> 𝕍(transformation * SpinVector(x)), surface)
return map(x -> project(normalize((vec(x)))), surface)
return map(x -> projectnocompression(normalize((vec(x)))), surface)
end


Expand All @@ -162,7 +180,7 @@ function makesphere(M::ℍ, T::Float64; segments::Int = 60)
else
surface = map(x -> 𝕍(T, vec(sign(T) * abs(T) * x)...), sphere)
end
return map(x -> project(M * normalize((vec(x)))), surface)
return map(x -> projectnocompression(M * normalize((vec(x)))), surface)
end


Expand All @@ -175,7 +193,7 @@ function makesphere(M::Matrix{Float64}, T::Float64; segments::Int = 60)
else
surface = map(x -> 𝕍(T, vec(sign(T) * abs(T) * x)...), sphere)
end
return map(x -> project(M * normalize((vec(x)))), surface)
return map(x -> projectnocompression(M * normalize((vec(x)))), surface)
end


Expand All @@ -185,7 +203,7 @@ function makespheretminusz(transformation::SpinTransformation; T::Float64 = 1.0,
sphere = [convert_to_cartesian([1.0; θ; ϕ]) for θ in lspace2, ϕ in lspace1]
surface = map(x -> 𝕍(transformation * SpinVector( 𝕍(T, vec(sign(T) * abs(T) * x)...))), sphere)
surface = map(x -> 𝕍(vec(x) .* (1.0 / (1.0 - vec(x)[4]))) , surface)
return map(x -> project((vec(x))), surface)
return map(x -> projectnocompression((vec(x))), surface)
end


Expand Down Expand Up @@ -235,7 +253,7 @@ function makeflagplane(u::𝕍, v::𝕍; segments::Int = 60)
lspace1 = range(-1.0, stop = 1.0, length = segments)
lspace2 = range(0.0, stop = 1.0, length = segments)
matrix = [f * u + s * v for f in lspace1, s in lspace2]
map(x -> project(normalize((vec(x)))), matrix)
map(x -> projectnocompression(normalize((vec(x)))), matrix)
end


Expand Down

0 comments on commit 945a0cb

Please sign in to comment.