Skip to content

Commit 061b628

Browse files
authored
Brand new logo (#245)
* add text (Montsserrat) for logo * [wip] logo: integration and backwards time works todo: slowdown! * yeahhhhh slowdown is done, logo looks SICK!!!! * Logo is FINISHED!!! * add final logo :) * bump version
1 parent b254477 commit 061b628

11 files changed

+338
-38
lines changed

.gitignore

+2-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ Manifest.toml
88
*.css
99
*style.jl
1010
*.png
11-
*.mp4
11+
*.mp4
12+
*.gif

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "DynamicalSystems"
22
uuid = "61744808-ddfa-5f27-97ff-6e42cc95d634"
33
repo = "https://github.com/JuliaDynamics/DynamicalSystems.jl.git"
4-
version = "3.3.22"
4+
version = "3.3.23"
55

66
[deps]
77
Attractors = "f3fd9213-ca85-4dba-9dfd-7fc91308fec7"

README.md

+4-5
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
![DynamicalSystems.jl logo: The Double Pendulum](https://i.imgur.com/nFQFdB0.gif)
1+
![DynamicalSystems.jl logo: The Double Pendulum](https://github.com/JuliaDynamics/JuliaDynamics/blob/master/videos/dynamicalsystems/juliadynamics_logo_anim_dark.gif?raw=true)
22

33
[![](https://img.shields.io/badge/docs-online-blue.svg)](https://juliadynamics.github.io/DynamicalSystemsDocs.jl/dynamicalsystems/dev/)
44
[![DocBuild](https://github.com/juliadynamics/DynamicalSystems.jl/workflows/CI/badge.svg)](https://github.com/JuliaDynamics/DynamicalSystems.jl/actions)
55
[![DOI](http://joss.theoj.org/papers/10.21105/joss.00598/status.svg)](https://doi.org/10.21105/joss.00598)
66
[![Textbook](https://img.shields.io/badge/Textbook-10.1007%2F978--3--030--91032--7-purple)](https://link.springer.com/book/10.1007/978-3-030-91032-7)
77
[![Package Downloads](https://img.shields.io/badge/dynamic/json?url=http%3A%2F%2Fjuliapkgstats.com%2Fapi%2Fv1%2Ftotal_downloads%2FDynamicalSystems&query=total_requests&label=Downloads)](http://juliapkgstats.com/pkg/DynamicalSystems)
88

9-
10-
**DynamicalSystems.jl** is an [award-winning](https://dsweb.siam.org/The-Magazine/Article/winners-of-the-dsweb-2018-software-contest) Julia software library for nonlinear dynamics and nonlinear timeseries analysis.
9+
**DynamicalSystems.jl** is an [award-winning](https://dsweb.siam.org/The-Magazine/Article/winners-of-the-dsweb-2018-software-contest) Julia-based general-purpose software library for the whole of nonlinear dynamics and nonlinear timeseries analysis.
1110

1211
To install **DynamicalSystems.jl**, run `import Pkg; Pkg.add("DynamicalSystems")` as a Julia language command.
1312
To learn how to use it and see its contents visit the documentation, which you can either find [online](https://juliadynamics.github.io/DynamicalSystems.jl/dev/) or build locally by running the `docs/make.jl` file.
@@ -23,8 +22,8 @@ Aspects of **DynamicalSystems.jl** that make it stand out among other codebases
2322
- **Open source community project**. Built from the ground up entirely on GitHub, **DynamicalSystems.jl** is 100% open source and based on community contributions. Anyone can be a developer of the library. Everyone is welcomed.
2423
- **Extensive content**. It aims to cover the entire field of nonlinear dynamics and nonlinear timeseries analysis. It has functionality for complexity measures, delay embeddings, periodic orbits, nonlocal stability analysis, continuation, chaos, fractal dimensions, surrogate testing, recurrence quantification analysis, and much more. Furthermore, all algorithms are "general" and work for any dynamical system applicable. Missing functionality that falls under this wide category of content is welcomed to be part of the library!
2524
- **Well tested**. All implemented functionality is extensively tested. Each time any change in the code base is done, the extensive test suite is run and checked before merging the change in.
26-
- **Extendable**. **DynamicalSystems.jl** is a living, evolving project. New contributions can become part of the library and be accessed by all users in the next release. Most importantly, all parts of the library follow professional standards in software design and implement extendable interfaces so that it is easy to contribute new functionality.
27-
- **Active development**. Since the start of the project (May 2017) there has been activity every month: new features, bugfixes, and the developer team answers users questions on official Julia language forums.
25+
- **Extendable**. New contributions can become part of the library and be accessed by all users in the next release. Most importantly, all parts of the library follow professional standards in software design and implement extendable interfaces so that it is easy to contribute new functionality.
26+
- **Active development**. It is a living, evolving project. Since its beginning in May 2017, **DynamicalSystems.jl** has had some activity every single month: new features, bugfixes. The developer team routinely answers users questions on official Julia language forums.
2827
- **Performant**. Written entirely in Julia, heavily optimized and parallelized, and taking advantage of some of the best packages within the language, **DynamicalSystems.jl** is _really fast_.
2928

3029
## Goals

docs/logo.jl docs/logo/logo.jl

+155-30
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
using DynamicalSystems
2-
using OrdinaryDiffEq
2+
using OrdinaryDiffEqVerner
33
using CairoMakie
44
using DataStructures: CircularBuffer
55
desktop() = joinpath(homedir(), "Desktop")
66
desktop(args...) = joinpath(desktop(), args...)
7+
desktop() = @__DIR__
78

89
# double pendulum dynamical system
910
@inbounds function doublependulum_rule(u, p, t)
@@ -61,7 +62,8 @@ ax = Axis(fig[1,1]; backgroundcolor = :transparent, aspect = DataAspect() )
6162
# this is maximum possible limits:
6263
# ax.limits = ((-L1-L2-0.1, L1 + L2+0.1), (-L1-L2-0.1, L1 + L2 + 0.1))
6364
# this is reduced size in height:
64-
ax.limits = ((-L1-L2-0.1, L1 + L2+0.1), (-L1-L2-0.1, (L1 + L2 + 0.1)/2))
65+
lima = 0.1
66+
ax.limits = ((-L1-L2-lima, L1 + L2+lima), (-L1-L2-lima, (L1 + L2 + lima)/2))
6567
ylims!(-0.8660254037844386/2 - 2.1, -0.8660254037844386/2 + 2.1) # center y of axis for equal aspect ratio
6668
# ax.aspect = 1
6769
hidedecorations!(ax)
@@ -106,21 +108,26 @@ trajline = lines!(ax, traj; color = tailcoltransp, linewidth = 4)
106108
# rods that connect the pendulum
107109
rodlines = lines!(ax, balls; linewidth = 12, color = :black)
108110

109-
scatter!(ax, balls; marker = :circle, strokewidth = 10,
111+
juliaballs = scatter!(ax, balls; marker = :circle, strokewidth = 10,
110112
strokecolor = [julia_green, julia_red, julia_purple],
111113
color = [lighter_green, lighter_red, lighter_purple],
112114
markersize = 160,
113115
)
114116

115117
function animstep!(dp)
116118
step!(dp)
117-
x1,x2,y1,y2 = xycoords(current_state(dp))
119+
update!(current_state(dp))
120+
end
121+
122+
function update!(u)
123+
x1,x2,y1,y2 = xycoords(u)
118124
rod[] = [Point2f(0, 0), Point2f(x1, y1), Point2f(x2, y2)]
119125
balls[] = [Point2f(0, 0), Point2f(x1, y1), Point2f(x2, y2)]
120126
push!(traj[], Point2f(x2, y2))
121127
notify(traj)
122128
end
123-
function animstep!(dp, t)
129+
130+
function animstep!(dp::DynamicalSystem, t)
124131
t0 = current_time(dp)
125132
while current_time(dp) < t0 + t
126133
animstep!(dp)
@@ -132,7 +139,7 @@ fig
132139

133140
# %% find initial condition that leads to nice Julia logo:
134141
using DynamicalSystems.StateSpaceSets.Distances
135-
u0 =/2 + 0.1, +2.03, 0.3, +5.412]
142+
u0 = SVector{4}(/2 + 0.1, +2.03, 0.3, +5.412])
136143
reinit!(dp, u0)
137144

138145

@@ -159,58 +166,176 @@ end
159166

160167
d
161168
tf = current_time(dp)
169+
uf = current_state(dp)
162170

163171
# reported final time of evolution from given initial condition:
164172
# 168.38499999991936
165173

166-
# okay, save high quality version:
174+
# Final state
175+
# 5.757958811321035
176+
# -5.924686393536801
177+
# 58.11993236370379
178+
# -2.839077350331716
179+
180+
fig
181+
182+
183+
# %% okay, save high quality version:
167184
ax.backgroundcolor = :transparent
168-
CairoMakie.save(desktop("juliadynamics_logo.png"), fig; px_per_unit = 4)
169-
# and one without tail
170-
trajline.visible = false
171-
save(desktop("juliadynamics_logo_no_tail.png"), fig; px_per_unit = 4)
172-
trajline.visible = true
185+
fig.scene.backgroundcolor = to_color(:transparent)
186+
CairoMakie.save(desktop("juliadynamics_logo_light_transparent.png"), fig; px_per_unit = 4)
173187
# and one more with white background
174188
ax.backgroundcolor = :white
175189
fig.scene.backgroundcolor = to_color(:white)
176-
CairoMakie.save(desktop("juliadynamics_logo_white.png"), fig; px_per_unit = 4)
190+
CairoMakie.save(desktop("juliadynamics_logo_light.png"), fig; px_per_unit = 4)
177191
# and a dark background
178192
rodlines.color = :white
179193
trajline.color = tailcoltransplight
180194
ax.backgroundcolor = "#1e1e20"
181195
fig.scene.backgroundcolor = to_color("#1e1e20")
182196
CairoMakie.save(desktop("juliadynamics_logo_dark.png"), fig; px_per_unit = 4)
197+
# and transparent dark version
198+
ax.backgroundcolor = :transparent
199+
fig.scene.backgroundcolor = to_color(:transparent)
200+
CairoMakie.save(desktop("juliadynamics_logo_dark_transparent.png"), fig; px_per_unit = 4)
201+
202+
# %% add text axis
203+
texax = Axis(fig[:, 0]; backgroundcolor = "#1e1e20")
204+
205+
resize!(fig, 1600, 600)
206+
207+
lima = 0.1
208+
ax.limits = ((-L1-L2-lima, L1 + L2+lima), (-L1-L2-lima, (L1 + L2 + lima)/2))
209+
210+
fig
211+
212+
# %% Add DynamicalSystems.jl font
213+
font = "Montserrat-Medium"
214+
empty!(texax)
215+
hidedecorations!(texax)
216+
hidespines!(texax)
217+
218+
dstext = text!(texax, 1.0, 0.5;
219+
text = "Dynamical\nSystems.jl", font = joinpath(@__DIR__, "montserrat", "$(font).ttf"),
220+
align = (:right, :center), justification = :right, space = :relative,
221+
color = :white, fontsize = 130, offset = (-35.0, 0),
222+
)
223+
224+
# Julia dots over i/j
225+
scatter!(
226+
[0.69, 0.885], [0.725, 0.445]; markersize = 40,
227+
color = julia_blue
228+
)
229+
230+
# add vertical line
231+
vertline = lines!(texax, [0.99, 0.99], [0.1, 0.9]; color = :white, linewidth = 10,)
232+
texax.limits = ((0, 1), (0, 1))
233+
fig
234+
235+
236+
# %% save full logo!
237+
# dark version - solid
238+
trajline.color = tailcoltransplight
239+
ax.backgroundcolor = "#1e1e20"
240+
texax.backgroundcolor = "#1e1e20"
241+
fig.scene.backgroundcolor = to_color("#1e1e20")
242+
rodlines.color = :white
243+
CairoMakie.save(desktop("juliadynamics_full_logo_dark.png"), fig; px_per_unit = 4)
244+
245+
# dark version - transparent
246+
texax.backgroundcolor = :transparent
183247
ax.backgroundcolor = :transparent
184248
fig.scene.backgroundcolor = to_color(:transparent)
185-
CairoMakie.save(desktop("juliadynamics_logo_dark_transp.png"), fig; px_per_unit = 4)
186-
# reset back to standard
249+
250+
CairoMakie.save(desktop("juliadynamics_full_logo_dark_transparent.png"), fig; px_per_unit = 4)
251+
252+
# light version - transparent
187253
trajline.color = tailcoltransp
188254
rodlines.color = :black
255+
dstext.color = :black
256+
vertline.color = :black
257+
258+
CairoMakie.save(desktop("juliadynamics_full_logo_light_transparent.png"), fig; px_per_unit = 4)
259+
260+
# light version - solid
261+
texax.backgroundcolor = :white
262+
ax.backgroundcolor = :white
263+
fig.scene.backgroundcolor = to_color(:white)
264+
265+
CairoMakie.save(desktop("juliadynamics_full_logo_light.png"), fig; px_per_unit = 4)
189266

190267
fig
191268

192-
# %% perform video animation animate from some t start to tf
269+
# %% reset back to solid dark for animation, modify accordingly for light
270+
# don't use transparent background, it doesn't work well with videos!!!
193271
rodlines.color = :white
194272
trajline.color = tailcoltransplight
273+
dstext.color = :white
274+
vertline.color = :white
275+
195276
ax.backgroundcolor = "#1e1e20"
277+
texax.backgroundcolor = "#1e1e20"
196278
fig.scene.backgroundcolor = to_color("#1e1e20")
197279

198-
reinit!(dp, u0)
199-
resize!(fig, 800, 800)
280+
fig
200281

282+
# %% perform video animation animate from some t start to tf
283+
# What I want to do here is the following:
284+
# animate the pendulum motion so that it slows down as it reaches the final
285+
# state, and it stops once it reaches the final state.
286+
287+
# For this, it is better to have a full ODE solution backwards in time,
288+
# it is so much simpler for adjusting time
289+
prob = ODEProblem((u,p,t) -> -doublependulum_rule(u,p,t), uf, (0.0, 100.0), p0)
290+
291+
sol = solve(prob; alg = Vern9(), dt, dense = true, adaptive = false)
292+
293+
# %%
294+
# We need to adjust limits of the pendulum axis and ball size because
295+
# the pendulum goes outside the axis range
296+
lima = 0.25
297+
ax.limits = ((-L1-L2-lima, L1 + L2+lima), (-L1-L2-lima, (L1 + L2 + lima)/2))
298+
juliaballs.markersize = 140
299+
300+
# time
301+
ts1 = 12.0 # time when animation starts
302+
ts2 = 2.0 # time when slowdown function is applied
303+
tf = 0 # final time must be 0 by definition
304+
dtmin = dt/40 # minimum possible slowdown
305+
306+
# we must update a full span first before recording for a smooth tail
201307
span = tail*dt
202-
ts = tf - span
203-
# ts += 20dt # for whatever reason we have to do this correction
204-
animstep!(dp, ts) # initial state
205-
206-
# fig.scene.backgroundcolor = :
207-
dtrecord = dt*10
208-
frames = 1:(Int(span ÷ dtrecord) - 10)
209-
@show length(frames)
210-
211-
record(fig, desktop("juliadynamics_logo_anim.mp4"), frames; framerate = 30) do i # i = frame number
212-
animstep!(dp, dtrecord)
213-
fig
308+
before = (ts1 + span):-dt:ts1
309+
for t in before
310+
update!(sol(t))
311+
end
312+
313+
# now we make the time vector populated more densely at the end
314+
# we just need a function that returns `dt` when `t=ts2` and `dtmin`
315+
# when `t = tf`; it doesn't matter the function.
316+
317+
# linear
318+
decay(t) = dt + (t - ts2)*(dtmin - dt)/(tf - ts2)
319+
# nonlinear 1, extreme slowdown at the end
320+
decay(t) = dtmin + (dt - dtmin)*(t/(ts2 - tf))^(1/2)
321+
322+
# now make the non-equi spaced vector
323+
newtimes = collect(ts1:-dt:ts2)
324+
while newtimes[end] > tf
325+
x = decay(newtimes[end])
326+
push!(newtimes, newtimes[end] - x)
327+
end
328+
pop!(newtimes)
329+
330+
framerate = 30
331+
freq = 10 # this is the animation speed at normal `dt`, decrease it to slow down
332+
@time record(fig, desktop("juliadynamics_logo_anim_dark.gif"); framerate) do io
333+
for (i, t) in enumerate(newtimes)
334+
update!(sol(t))
335+
i % freq == 0 && recordframe!(io)
336+
end
337+
# add a couple of seconds of stillness at the end
338+
for _ in 1:3framerate; recordframe!(io); end
214339
end
215340

216341
fig
193 KB
Binary file not shown.
193 KB
Binary file not shown.
193 KB
Binary file not shown.
193 KB
Binary file not shown.

0 commit comments

Comments
 (0)