Skip to content
This repository has been archived by the owner on Jun 21, 2024. It is now read-only.

Commit

Permalink
Complete re-write of billiard plotting and animations (#89)
Browse files Browse the repository at this point in the history
* sketch of particle stepper

* more sketches and todos for new way of plotting

* remove `visible` variable

* almost done with the stepping function

* update to makie 0.16

* [wip billairds just bring to master]

* [WIP] Almost there perfect plotting!!!!!!!

* amazing progress continues

* almost there!!!

* working realtime stepping!!

* reset totally working

* select line works

* todo bmap and documentation

* adding another plot works (didn't test resetting)

* boundary map DONE!

* video function finished

* Video and all stuff done. Only docs left

* docs finished; TODO: periodic billiard / update files

* periodic billiards plots work

* add Cairo to doc project

* transform billiards into literate format

* move colors to org theme

* finish everything

* lower framerate
  • Loading branch information
Datseris committed Feb 27, 2022
1 parent 72ee103 commit 1fb35af
Show file tree
Hide file tree
Showing 15 changed files with 877 additions and 243 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ Manifest.toml
*.scss
*.css
*.code-workspace
billiards.md
4 changes: 4 additions & 0 deletions docs/Project.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
[deps]
Agents = "46ada45e-f475-11e8-01d0-f70cc89e6671"
CairoMakie = "13f3f980-e62b-5c42-98c6-ff1f3baf88f0"
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
DocumenterTools = "35a29f4d-8980-5a13-9543-d66fff28ecb8"
DynamicalBilliards = "4986ee89-4ee5-5cef-b6b8-e49ba721d7a5"
DynamicalSystems = "61744808-ddfa-5f27-97ff-6e42cc95d634"
InteractiveDynamics = "ec714cd0-5f51-11eb-0b6e-452e7367ff84"
Literate = "98b081ad-f1c9-55d3-8b20-4c87d4299306"
libsass_jll = "47bcb7c8-5119-555a-9eeb-0afcc36cd728"

[compat]
Documenter = "0.24.6"
libsass_jll = "~3.5"
15 changes: 13 additions & 2 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
cd(@__DIR__)
using Pkg
Pkg.activate(@__DIR__)
CI = get(ENV, "CI", nothing) == "true" || get(ENV, "GITHUB_TOKEN", nothing) !== nothing
CI && Pkg.activate(@__DIR__)
CI && Pkg.instantiate()

using InteractiveDynamics
using DynamicalSystems, DynamicalBilliards, Agents
using Documenter
using DocumenterTools: Themes
using CairoMakie

# %%
# download the themes
for file in ("juliadynamics-lightdefs.scss", "juliadynamics-darkdefs.scss", "juliadynamics-style.scss")
download("https://raw.githubusercontent.com/JuliaDynamics/doctheme/master/$file", joinpath(@__DIR__, file))
Expand All @@ -24,6 +24,17 @@ end
Themes.compile(joinpath(@__DIR__, "juliadynamics-light.scss"), joinpath(@__DIR__, "src/assets/themes/documenter-light.css"))
Themes.compile(joinpath(@__DIR__, "juliadynamics-dark.scss"), joinpath(@__DIR__, "src/assets/themes/documenter-dark.css"))

# Use literate to transform files
using Literate
indir = joinpath(@__DIR__, "src")
outdir = indir
files = ("billiards.jl", )
for file in files
Literate.markdown(joinpath(indir, file), outdir; credit = false)
end

# %%

makedocs(
modules=[InteractiveDynamics, DynamicalSystems, DynamicalBilliards, Agents],
doctest=false,
Expand Down
172 changes: 172 additions & 0 deletions docs/src/billiards.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
# # Visualizations and Animations for Billiards

# All plotting and animating for [DynamicalBilliards.jl](https://juliadynamics.github.io/DynamicalBilliards.jl/dev/) lies within a few well-defined functions from [InteractiveDynamics.jl](https://juliadynamics.github.io/InteractiveDynamics.jl/dev/) that use the [Makie](https://makie.juliaplots.org/stable/) ecosystem.

# - For static plotting, you can use the function [`bdplot`](@ref).
# - For interacting/animating, you can use the function [`bdplot_interactive`](@ref).
# This function also allows you to create custom animations, see [Custom Billiards Animations](@ref).
# - For producing videos of time evolution of particles in a billiard, use [`bdplot_video`](@ref).

# ## Plotting
# ```@docs
# bdplot
# ```
# ### Plotting an obstacle with keywords
using DynamicalBilliards, InteractiveDynamics, CairoMakie

bd = billiard_sinai()

fig, ax = bdplot(bd[2])
bdplot!(ax, bd[4]; color = "blue", linestyle = :dot, linewidth = 5.0)
bdplot!(ax, bd[1]; color = "yellow", strokecolor = "black")
fig

# ### Plotting a billiard
# %% #src
using DynamicalBilliards, InteractiveDynamics, CairoMakie
bd = billiard_logo()[1]
fig, ax = bdplot(bd)
fig

# ### Plotting some particle trajectories
# %% #src
using DynamicalBilliards, InteractiveDynamics, CairoMakie

bd = billiard_hexagonal_sinai()
p1 = randominside(bd)
p2 = randominside(bd, 1.0)
colors = [:red, JULIADYNAMICS_COLORS[1]]
markers = [:circle, :rect]
fig, ax = bdplot(bd)
for (p, c) in zip([p1, p2], colors)
x, y = DynamicalBilliards.timeseries!(p, bd, 20)
lines!(ax, x, y; color = c)
end
bdplot!(ax, [p1, p2]; colors, particle_size = 10, marker = markers)
fig

# ### Periodic billiard plot
# Rectangle periodicity:
# %% #src
using DynamicalBilliards, InteractiveDynamics, CairoMakie

r = 0.25
bd = billiard_rectangle(2, 1; setting = "periodic")
d = Disk([0.5, 0.5], r)
d2 = Ellipse([1.5, 0.5], 1.5r, 2r/3)
bd = Billiard(bd.obstacles..., d, d2)
p = Particle(1.0, 0.5, 0.1)
xt, yt, vxt, vyt, t = DynamicalBilliards.timeseries!(p, bd, 10)
fig, ax = bdplot(bd, extrema(xt)..., extrema(yt)...)
lines!(ax, xt, yt)
bdplot!(ax, p; velocity_size = 0.1)
fig

# Hexagonal periodicity:
# %% #src
using DynamicalBilliards, InteractiveDynamics, CairoMakie

bd = billiard_hexagonal_sinai(0.3, 1.50; setting = "periodic")
d = Disk([0.7, 0], 0.2)
d2 = Antidot([0.7/2, 0.65], 0.35)
bd = Billiard(bd..., d, d2)

p = MagneticParticle(-0.5, 0.5, π/5, 1.0)

xt, yt = DynamicalBilliards.timeseries(p, bd, 10)
fig, ax = bdplot(bd, extrema(xt)..., extrema(yt)...)
lines!(ax, xt, yt)
bdplot!(ax, p; velocity_size = 0.1)
fig

# ## Interactive GUI
# ```@docs
# bdplot_interactive
# ```

# ## Custom Billiards Animations
# %% #src
# To do custom animations you need to have a good idea of how Makie's animation system works.
# Have a look [at this tutorial](https://www.youtube.com/watch?v=L-gyDvhjzGQ) if you are
# not familiar yet.

# Following the docstring of [`bdplot_interactive`](@ref) let's add a couple of
# new plots that animate some properties of the particles.
# We start with creating the billiard plot and obtaining the observables:
using DynamicalBilliards, InteractiveDynamics, CairoMakie

bd = billiard_stadium(1, 1)
N = 100
ps = particlebeam(1.0, 0.6, 0, N, 0.001)
fig, phs, chs = bdplot_interactive(bd, ps; playback_controls=false, resolution = (800, 800));
# Then, we add some axis
layout = fig[2,1] = GridLayout()
axd = Axis(layout[1,1]; ylabel = "log(⟨d⟩)", align = Outside())
axs = Axis(layout[2,1]; ylabel = "std", xlabel = "time", align = Outside())
hidexdecorations!(axd; grid = false)
rowsize!(fig.layout, 1, Auto(2))
fig
# Our next step is to create new observables to plot in the new axis,
# by lifting `phs, chs`. Let's plot the distance between two particles and the
# std of the particle y position.
using Statistics: std
## Define observables
d_p(phs) = log(sum(sqrt(sum(phs[1].p.pos .- phs[j].p.pos).^2) for j in 2:N)/N)
std_p(phs) = std(p.p.pos[1] for p in phs)
t = Observable([0.0]) # Time axis
d = Observable([d_p(phs[])])
s = Observable([std_p(phs[])])
## Trigger observable updates
on(phs) do phs
push!(t[], phs[1].T)
push!(d[], d_p(phs))
push!(s[], std_p(phs))
notify.((t, d))
autolimits!(axd); autolimits!(axs)
end
## Plot observables
lines!(axd, t, d; color = JULIADYNAMICS_COLORS[1])
lines!(axs, t, s; color = JULIADYNAMICS_COLORS[2])
nothing

# The figure hasn't changed yet of course, but after we step the animation, it does:
dt = 0.001
for j in 1:1000
for i in 1:9
bdplot_animstep!(phs, chs, bd, dt; update = false)
end
bdplot_animstep!(phs, chs, bd, dt; update = true)
end
fig

# Of course, you can produce a video of this using Makie's `record` function.

# ## Video output
# ```@docs
# bdplot_video
# ```
# Here is an example that changes plotting defaults to make an animation in
# the style of [3Blue1Brown](https://www.3blue1brown.com/).
# %% #src
using DynamicalBilliards, InteractiveDynamics, CairoMakie

BLUE = "#7BC3DC"
BROWN = "#8D6238"
colors = [BLUE, BROWN]
## Overwrite default color of obstacles to white (to fit with black background)
InteractiveDynamics.obcolor(::Obstacle) = RGBf(1,1,1)
bd = billiard_stadium(1, 1)
ps = particlebeam(1.0, 0.6, 0, 200, 0.01)

bdplot_video(
"3b1billiard.mp4", bd, ps;
frames = 120, colors, dt = 0.01, tail_length = 100,
backgroundcolor = :black, framerate = 10,
)
nothing

# ```@raw html
# <video width="auto" controls autoplay loop>
# <source src="../3b1billiard.mp4" type="video/mp4">
# </video>
# ```
104 changes: 0 additions & 104 deletions docs/src/billiards.md

This file was deleted.

2 changes: 1 addition & 1 deletion examples/billiards/billiard.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ colors = [GLMakie.RGBAf(i/N, 0, 1 - i/N, 0.25) for i in 1:N]

# Uncomment any of the following to get the billiard you want:
bd = billiard_stadium()
bd = billiard_mushroom()
# bd = billiard_mushroom()
# bd = billiard_hexagonal_sinai(0.5, 1.0)
# bd = billiard_sinai(0.25f0, 1f0, 1f0)
# bd = Billiard(Antidot(Float32[0, 0], 0.5f0, false))
Expand Down
Loading

0 comments on commit 1fb35af

Please sign in to comment.