113 lines
2.8 KiB
Julia
113 lines
2.8 KiB
Julia
|
using AbstractPlotting
|
|||
|
using AbstractPlotting.MakieLayout
|
|||
|
using GLMakie
|
|||
|
|
|||
|
using LinearAlgebra
|
|||
|
|
|||
|
|
|||
|
function bezier()
|
|||
|
descr = """
|
|||
|
Bezier Curves: B(t) = ∑(binomial(n,i) * tⁱ * (1-t)⁽ⁿ⁻¹⁾ * Pᵢ)
|
|||
|
"""
|
|||
|
|
|||
|
## 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[]))
|
|||
|
|
|||
|
# very wierd, but we work with components
|
|||
|
# not vector
|
|||
|
z = zero(eltype(pos))
|
|||
|
x,y = pos
|
|||
|
|
|||
|
ptidx = idx[]
|
|||
|
|
|||
|
x = clamp(x, -1, 1)
|
|||
|
y = clamp(y, -1, 1)
|
|||
|
|
|||
|
points[][idx[]] = [x,y]
|
|||
|
points[] = points[]
|
|||
|
end
|
|||
|
else
|
|||
|
dragstart[] = false
|
|||
|
end
|
|||
|
return
|
|||
|
end
|
|||
|
end
|
|||
|
|
|||
|
upperpoints = Point2f0[(0,0), (5, 0), (5, 5), (0,5)]
|
|||
|
lowerpoints = (Point2f0[(0,0), (5, 0), (5, -5), (0,-5)])
|
|||
|
|
|||
|
points = Node(Point2f0[(1, 4), (3, 0), (4,-4.0)])
|
|||
|
|
|||
|
# 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))
|
|||
|
colsize!(layout, 2, Auto(1))
|
|||
|
|
|||
|
npts = layout[2,1:2] = LSlider(scene, range=3:12, startvalue=4)
|
|||
|
layout[3,1:2] = LText(scene, chomp(descr))
|
|||
|
|
|||
|
# points = Node(Point2f0[(-1/2, -1/2),
|
|||
|
# (-1/2, 1/2),
|
|||
|
# (1/2, 1/2),
|
|||
|
# (1/2, -1/2)])
|
|||
|
|
|||
|
#npts = 6
|
|||
|
#ts = range(3pi/2, -pi/2, length=npts+2)
|
|||
|
#points = Node(Point2f0[(cos(t),sin(t)) for t in ts[2:end-1]])
|
|||
|
|
|||
|
points = lift(npts.value) do val
|
|||
|
ts = range(3pi/2, -pi/2, length=val+2)
|
|||
|
Point2f0[(cos(t),sin(t)) for t in ts[2:end-1]]
|
|||
|
end
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
|
|||
|
bcurve = lift(points) do pts
|
|||
|
n = length(pts) - 1
|
|||
|
B = t -> begin
|
|||
|
tot = 0.0
|
|||
|
for (i′, Pᵢ) in enumerate(pts)
|
|||
|
i = i′ - 1
|
|||
|
tot += binomial(n, i) * t^i * (1-t)^(n-i) * Pᵢ
|
|||
|
end
|
|||
|
tot
|
|||
|
end
|
|||
|
ts = range(0, 1, length=200)
|
|||
|
Point2f0[B(t) for t in ts]
|
|||
|
end
|
|||
|
|
|||
|
|
|||
|
|
|||
|
lines!(p.scene, bcurve, strokecolor=:black, strokewidth=15)
|
|||
|
lines!(p.scene, points, strokecolor=:gray90, strokewidth=5, linestyle=:dash)
|
|||
|
scatter!(p.scene, points)
|
|||
|
xlims!(p.scene, (-1,1))
|
|||
|
ylims!(p.scene, (-1,1))
|
|||
|
add_move!(p.scene, points, p.scene[end])
|
|||
|
|
|||
|
|
|||
|
|
|||
|
scene
|
|||
|
|
|||
|
end
|