initial
This commit is contained in:
102
CwJ/makie-demos/tangent-line.jl
Normal file
102
CwJ/makie-demos/tangent-line.jl
Normal file
@@ -0,0 +1,102 @@
|
||||
using AbstractPlotting
|
||||
using AbstractPlotting.MakieLayout
|
||||
using GLMakie
|
||||
|
||||
using ForwardDiff
|
||||
Base.adjoint(f::Function) = x -> ForwardDiff.derivative(f, float(x))
|
||||
|
||||
|
||||
function tangent_line(f=nothing, a=0, b=pi)
|
||||
|
||||
if f == nothing
|
||||
f = x -> sin(x)
|
||||
end
|
||||
|
||||
descr = """
|
||||
The tangent line has a slope approximated by the slope of secant lines.
|
||||
This demo allows the points c and c+h to be adjusted to see the two lines"""
|
||||
|
||||
## From http://juliaplots.org/MakieReferenceImages/gallery//edit_polygon/index.html:
|
||||
function add_move!(scene, points, pplot)
|
||||
idx = Ref(0); dragstart = Ref(false); startpos = Base.RefValue(Point2f0(0))
|
||||
on(events(scene).mousedrag) do drag
|
||||
if ispressed(scene, Mouse.left)
|
||||
if drag == Mouse.down
|
||||
plot, _idx = mouse_selection(scene)
|
||||
if plot == pplot
|
||||
idx[] = _idx; dragstart[] = true
|
||||
startpos[] = to_world(scene, Point2f0(scene.events.mouseposition[]))
|
||||
end
|
||||
elseif drag == Mouse.pressed && dragstart[] && checkbounds(Bool, points[], idx[])
|
||||
pos = to_world(scene, Point2f0(scene.events.mouseposition[]))
|
||||
|
||||
# we work with components not vector
|
||||
x,y = pos
|
||||
|
||||
x = clamp(x, a, b)
|
||||
y = f(x)
|
||||
|
||||
points[][idx[]] = [x,y]
|
||||
points[] = points[]
|
||||
end
|
||||
else
|
||||
dragstart[] = false
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
c, h = pi/4, .5
|
||||
points = Node(Point2f0[(c, f(c)), (c+h, f(c+h))])
|
||||
|
||||
|
||||
# where we lay our scene:
|
||||
scene, layout = layoutscene()
|
||||
layout.halign = :left
|
||||
layout.valign = :top
|
||||
|
||||
p = layout[1,1:2] = LScene(scene)
|
||||
|
||||
rowsize!(layout, 1, Auto(1))
|
||||
colsize!(layout, 1, Auto(1))
|
||||
|
||||
layout[2,1:2] = LText(scene, descr)
|
||||
|
||||
|
||||
secline = lift(points) do pts
|
||||
c, ch = pts
|
||||
x0, y0 = c
|
||||
x1, y1 = ch
|
||||
m = (y1 - y0)/(x1 - x0)
|
||||
sl = x -> y0 + m * (x - x0)
|
||||
Point2f0[(a, sl(a)), (b, sl(b))]
|
||||
end
|
||||
|
||||
tangentline = lift(points) do pts
|
||||
c, ch = pts
|
||||
x0, y0 = c
|
||||
m = f'(x0)
|
||||
tl = x -> y0 + m * (x - x0)
|
||||
Point2f0[(a, tl(a)), (b, tl(b))]
|
||||
end
|
||||
|
||||
|
||||
lines!(p.scene, a..b, f, strokecolor=:red, strokewidth=15)
|
||||
lines!(p.scene, secline, color = :blue, strokewidth = 10, raw=true)
|
||||
lines!(p.scene, tangentline, color = :red, strokewidth = 10, raw=true)
|
||||
scatter!(p.scene, points, color = :white, strokewidth = 10, markersize = 0.05, strokecolor = :black, raw = true)
|
||||
xlims!(p.scene, (a, b))
|
||||
#ylims!(p.scene, (0, 1.5))
|
||||
|
||||
|
||||
add_move!(p.scene, points, p.scene[end])
|
||||
|
||||
|
||||
|
||||
scene
|
||||
|
||||
end
|
||||
|
||||
|
||||
tangent_line()
|
||||
Reference in New Issue
Block a user