Last active
April 7, 2022 11:47
-
-
Save jonocarroll/27f9b57332424ea50ec2970e74d8e3b3 to your computer and use it in GitHub Desktop.
Julia interpolation animation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
## Inspired by | |
## https://twitter.com/ted_dunning/status/1435027697386721280?s=20&t=cDVb0XOQRJeOjXoTrOz54w | |
using Plots | |
## These are required to be imported to write methods for them | |
import Base:* | |
import Base:+ | |
## Define an interpolation function between a and b | |
## parameterised by some t | |
interpolate(a, b) = t -> ((1.0-t)*a + t*b) | |
## This can act on anything, but with Julia's dispatch, | |
## that includes functions | |
## The only operations needed for this are | |
+(f::Function, g::Function) = x -> f(x) + g(x) | |
*(t::Number, g::Function) = x -> t * g(x) | |
## Then we can interpolate between two points | |
bz1(p1, p2) = interpolate(p1, p2) | |
## And interpolate between the interpolations | |
bz2(p1, p2, p3) = interpolate(bz1(p1, p2), bz1(p2, p3)) | |
## And interpolate between the interpolations again | |
bz3(p1, p2, p3, p4) = interpolate(bz2(p1, p2, p3), bz2(p2, p3, p4)) | |
### | |
## Defining some points | |
p1 = [0,0] | |
p2 = [1,2] | |
p3 = [2,2] | |
p4 = [1.5,0] | |
## The combined interpolation between pairs then pairs then pairs | |
## will trace out these points | |
dots = map(i -> bz3(p1, p2, p3, p4)(i)(i)(i),collect(0:0.05:1)) | |
dots = hcat(dots...) | |
## Animating the points and the lines between them | |
anim1 = @animate for t in collect(vcat(0:0.01:1,1:-0.01:0)) | |
a = bz3(p1, p2, p3, p4)(t)(t)(t); | |
b1 = bz2(p1, p2, p3)(t)(t); | |
b2 = bz2(p2, p3, p4)(t)(t); | |
c1 = bz1(p1, p2)(t); | |
c2 = bz1(p2, p3)(t); | |
c3 = bz1(p3, p4)(t); | |
stars = hcat(p1, p2, p3, p4); | |
diamond1 = hcat(c1, c2); | |
diamond2 = hcat(c2, c3); | |
square = hcat(b1, b2); | |
plot(xlim = (-0.1,2.5), ylim = (-0.1,2.5), legend = false) | |
scatter!(dots[1,:], dots[2,:], markersize = 2) | |
plot!(diamond1[1,:], diamond1[2,:], markersize = 10, markershape = :diamond, color = :green) | |
plot!(diamond2[1,:], diamond2[2,:], markersize = 10, markershape = :diamond, color = :green) | |
plot!(square[1,:], square[2,:], markersize = 10, markershape = :square, color = :blue) | |
plot!(stars[1,:], stars[2,:], markersize = 10, markershape = :star, color = :purple) | |
scatter!(Tuple(a), markersize = 10, markershape = :circle, markercolor = :red) | |
end | |
gif(anim1, "julia_interpolate_1.gif", fps = 24) | |
### | |
## Again, with some different points! | |
p1 = [0.5,1] | |
p2 = [0.25,2.2] | |
p3 = [1.8,1.8] | |
p4 = [1.5,0.2] | |
dots = map(i -> bz3(p1, p2, p3, p4)(i)(i)(i),collect(0:0.05:1)) | |
dots = hcat(dots...) | |
anim2 = @animate for t in collect(vcat(0:0.01:1,1:-0.01:0)) | |
a = bz3(p1, p2, p3, p4)(t)(t)(t); | |
b1 = bz2(p1, p2, p3)(t)(t); | |
b2 = bz2(p2, p3, p4)(t)(t); | |
c1 = bz1(p1, p2)(t); | |
c2 = bz1(p2, p3)(t); | |
c3 = bz1(p3, p4)(t); | |
stars = hcat(p1, p2, p3, p4); | |
diamond1 = hcat(c1, c2); | |
diamond2 = hcat(c2, c3); | |
square = hcat(b1, b2); | |
plot(xlim = (-0.1,2.5), ylim = (-0.1,2.5), legend = false) | |
scatter!(dots[1,:], dots[2,:], markersize = 2) | |
plot!(diamond1[1,:], diamond1[2,:], markersize = 10, markershape = :diamond, color = :green) | |
plot!(diamond2[1,:], diamond2[2,:], markersize = 10, markershape = :diamond, color = :green) | |
plot!(square[1,:], square[2,:], markersize = 10, markershape = :square, color = :blue) | |
plot!(stars[1,:], stars[2,:], markersize = 10, markershape = :star, color = :purple) | |
scatter!(Tuple(a), markersize = 10, markershape = :circle, markercolor = :red) | |
end | |
gif(anim2, "julia_interpolate_2.gif", fps = 24) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment