Need Help to Create Animation for Tangent Line with Luxor

Here’s a quick version in Luxor.jl of f(x) = sin(2x) * cos(x/2), using Zygote and code from @nilshg’s StackOverflow answer.

slope

Julia code
using Luxor
using Zygote

## mathspace to drawingspace
K = 400/2 / 2π
Pt(x, y) = Point(K * x, -K * y)

f(x) = sin(2x) * cos(x/2)

gradient_line(f, x₀) = (x -> f(x₀) + f'(x₀) * (x - x₀))

function drawcurve(w, h)
    @layer begin
        setopacity(0.25)
        rule(O)
        rule(O, π/2)
    end
    move(Pt(-2π, 0))
    for x in -2π:π/24:2π
        line(Pt(x, f(x)))
    end
    strokepath()
end

function frame(scene, framenumber)
    w, h = scene.movie.width, scene.movie.height
    background("black")
    sethue("gold")
    drawcurve(w, h)
    x = rescale(framenumber, 1, scene.framerange.stop, -2π, 2π)
    pt = Pt(x, f(x))
    circle(pt, 5, :fill)
    δ = 0.1
    y = gradient_line(f, x)(x)
    point_on_curve = Pt(x, y)

    y1 = gradient_line(f, x)(x - δ)
    y2 = gradient_line(f, x)(x + δ)

    sl = slope(Pt(x - δ, y1), Pt(x + δ, y2))
    sethue("white")
    line(point_on_curve - polar(100, sl), 
         point_on_curve + polar(100, sl), :stroke)
end

demo = Movie(400, 300, "slope")
animate(demo, [Scene(demo, frame, 1:100)], framerate=10, creategif=true)

This isn’t to say that this is the best or only way to write it - it’s probably easier in Plots or Makie or Javis, although I’m not familiar enough with those packages to know for sure.

Although most Julia packages usually work well together, I’d recommend using only one of the “graphical output” packages in a session. The least of the problems will be having multiple definitions for common functions; accessing the output ‘channels’ of other modules could require some advanced knowledge of their internals.

6 Likes