Sarcone's dynamic Muller-Lyer illusion

Gen Kuroki

2018-03-10, 2018-09-13, 2020-04-26

See

In [1]:
using Base64

using Plots
gr(legend=false)

# 線分を描く函数
segment(A, B; color="black", kwargs...) = plot([A[1], B[1]], [A[2], B[2]]; color=color, kwargs...)
segment!(A, B; color="black", kwargs...) = plot!([A[1], B[1]], [A[2], B[2]]; color=color, kwargs...)
segment!(p, A, B; color="black", kwargs...) = plot!(p, [A[1], B[1]], [A[2], B[2]]; color=color, kwargs...)

# 円周を描く函数
function circle(O, r; a=0, b=2π, color="black", kwargs...)
    t = linspace(a, b, 1001)
    x(t) = O[1] + r*cos(t)
    y(t) = O[1] + r*sin(t)
    plot(x.(t), y.(t); color=color, kwargs...)
end
function circle!(O, r; a=0, b=2π, color="black", kwargs...)
    t = linspace(a, b, 1001)
    x(t) = O[1] + r*cos(t)
    y(t) = O[2] + r*sin(t)
    plot!(x.(t), y.(t); color=color, kwargs...)
end
function circle!(p, O, r; a=0, b=2π, color="black", kwargs...)
    t = linspace(a, b, 1001)
    x(t) = O[1] + r*cos(t)
    y(t) = O[1] + r*sin(t)
    plot!(p, x.(t), y.(t); color=color, kwargs...)
end

# 表示用函数
showimg(mime, fn; tag="img") = open(fn) do f
    base64 = base64encode(f)
    display("text/html", """<$tag src="data:$mime;base64,$base64" />""")
end
Out[1]:
showimg (generic function with 1 method)
In [2]:
A = [1.5, 0]
B = [3.5, 0]
C = [5.5, 0]

N = 10

θ₀ = 2π/(2N)
R = [
    cos(θ₀) -sin(θ₀)
    sin(θ₀)  cos(θ₀)
]

V(θ) = [cos(θ), sin(θ)]
r = 1.55*2π/(2N)

# warm up
@time anim = @animate for a in [0.6]
    θ = a*2π/4
    p = plot(xlim=(-8, 8), ylim=(-8, 8))
    plot!(grid=false, legend=false, xaxis=false, yaxis=false)
    for k in 1:10
        RR = R^(2k-1)
        segment!(RR*A, RR*B, lw=2, color=:black)
        segment!(RR*B, RR*C, lw=2, color=:blue)
        segment!(RR*A, RR*(A+r*V(θ)),   lw=2, color=:black)
        segment!(RR*A, RR*(A+r*V(-θ)),  lw=2, color=:black)
        segment!(RR*B, RR*(B+r*V(π-θ)), lw=2, color=:black)
        segment!(RR*B, RR*(B+r*V(π+θ)), lw=2, color=:black)
        segment!(RR*C, RR*(C+r*V(θ)),   lw=2, color=:black)
        segment!(RR*C, RR*(C+r*V(-θ)),  lw=2, color=:black)
    end
    plot(p, size=(500, 500))
end

@time anim = @animate for a in [0.6:0.025:1.4; 1.375:-0.025:0.625]
    θ = a*2π/4
    p = plot(xlim=(-8, 8), ylim=(-8, 8))
    plot!(grid=false, legend=false, xaxis=false, yaxis=false)
    for k in 1:10
        RR = R^(2k-1)
        segment!(RR*A, RR*B, lw=2, color=:black)
        segment!(RR*B, RR*C, lw=2, color=:blue)
        segment!(RR*A, RR*(A+r*V(θ)),   lw=2, color=:black)
        segment!(RR*A, RR*(A+r*V(-θ)),  lw=2, color=:black)
        segment!(RR*B, RR*(B+r*V(π-θ)), lw=2, color=:black)
        segment!(RR*B, RR*(B+r*V(π+θ)), lw=2, color=:black)
        segment!(RR*C, RR*(C+r*V(θ)),   lw=2, color=:black)
        segment!(RR*C, RR*(C+r*V(-θ)),  lw=2, color=:black)
    end
    plot(p, size=(500, 500))
end

gifname = "dynamic Muller-Lyer.gif"
@time gif(anim, gifname, fps = 15)
 17.149522 seconds (25.51 M allocations: 1.262 GiB, 3.06% gc time)
  4.906286 seconds (13.72 M allocations: 711.934 MiB, 2.87% gc time)
  1.475322 seconds (2.35 M allocations: 109.250 MiB, 3.00% gc time)
┌ Info: Saved animation to 
│   fn = C:\Users\genkuroki\OneDrive\Math\Math0037\dynamic Muller-Lyer.gif
└ @ Plots C:\Users\genkuroki\.julia\packages\Plots\8GUYs\src\animation.jl:102
Out[2]:
In [3]:
lw = 1.0 # 太さ

A = [1.5, 0]
B = [3.5, 0]
C = [5.5, 0]

N = 10

θ₀ = 2π/(2N)
R = [
    cos(θ₀) -sin(θ₀)
    sin(θ₀)  cos(θ₀)
]

V(θ) = [cos(θ), sin(θ)]
r = 1.55*2π/(2N)

@time anim = @animate for a in [0.6:0.025:1.4; 1.375:-0.025:0.625]
    θ = a*2π/4
    p = plot(xlim=(-6.7, 6.7), ylim=(-6.7, 6.7))
    plot!(grid=false, legend=false, xaxis=false, yaxis=false)
    for k in 1:10
        RR = R^(2k-1)
        segment!(RR*A, RR*B,            lw=lw, color=:black)
        segment!(RR*B, RR*C,            lw=lw, color=:blue)
        segment!(RR*A, RR*(A+r*V(θ)),   lw=lw, color=:black)
        segment!(RR*A, RR*(A+r*V(-θ)),  lw=lw, color=:black)
        segment!(RR*B, RR*(B+r*V(π-θ)), lw=lw, color=:black)
        segment!(RR*B, RR*(B+r*V(π+θ)), lw=lw, color=:black)
        segment!(RR*C, RR*(C+r*V(θ)),   lw=lw, color=:black)
        segment!(RR*C, RR*(C+r*V(-θ)),  lw=lw, color=:black)
    end
    plot(p, size=(500, 500))
end

gifname = "dynamic Muller-Lyer $lw.gif"
@time gif(anim, gifname, fps = 15)
  5.215087 seconds (14.04 M allocations: 729.108 MiB, 2.70% gc time)
  0.831446 seconds
┌ Info: Saved animation to 
│   fn = C:\Users\genkuroki\OneDrive\Math\Math0037\dynamic Muller-Lyer 1.0.gif
└ @ Plots C:\Users\genkuroki\.julia\packages\Plots\8GUYs\src\animation.jl:102
 (629 allocations: 125.219 KiB)
Out[3]:
In [4]:
lw = 1.0 # 太さ

A = [1.5, 0]
B = [3.5, 0]
C = [5.5, 0]
D = [7.5, 0]

N = 10

θ₀ = 2π/(2N)
R = [
    cos(θ₀) -sin(θ₀)
    sin(θ₀)  cos(θ₀)
]

V(θ) = [cos(θ), sin(θ)]
r = 1.55*2π/(2N)

@time anim = @animate for a in [0.5:0.025:1.5; 1.475:-0.025:0.525]
    θ = a*2π/4
    p = plot(xlim=(-8.5, 8.5), ylim=(-8.5, 8.5))
    plot!(grid=false, legend=false, xaxis=false, yaxis=false)
    for k in 1:10
        RR = R^(2k-1)
        segment!(RR*A, RR*B,            lw=lw, color=:black)
        segment!(RR*B, RR*C,            lw=lw, color=:blue)
        segment!(RR*C, RR*D,            lw=lw, color=:red)
        segment!(RR*A, RR*(A+r*V(θ)),   lw=lw, color=:black)
        segment!(RR*A, RR*(A+r*V(-θ)),  lw=lw, color=:black)
        segment!(RR*B, RR*(B+1.5r*V(π-θ)), lw=lw, color=:black)
        segment!(RR*B, RR*(B+1.5r*V(π+θ)), lw=lw, color=:black)
        segment!(RR*C, RR*(C+2.0r*V(θ)),   lw=lw, color=:black)
        segment!(RR*C, RR*(C+2.0r*V(-θ)),  lw=lw, color=:black)
        segment!(RR*D, RR*(D+2.5r*V(π-θ)), lw=lw, color=:black)
        segment!(RR*D, RR*(D+2.5r*V(π+θ)), lw=lw, color=:black)
    end
    plot(p, size=(500, 500))
end

gifname = "dynamic Muller-Lyer 2 $lw.gif"
@time gif(anim, gifname, fps = 15)
  7.761749 seconds (24.40 M allocations: 1.198 GiB, 3.03% gc time)
  0.968621 seconds (630 allocations: 124.859 KiB)
┌ Info: Saved animation to 
│   fn = C:\Users\genkuroki\OneDrive\Math\Math0037\dynamic Muller-Lyer 2 1.0.gif
└ @ Plots C:\Users\genkuroki\.julia\packages\Plots\8GUYs\src\animation.jl:102
Out[4]: