I assume you defined xreference, yreference, xhead, yhead
as in my post here: GLMakie beginners help: Multiple sliders and an arrow - #3 by fatteneder
As you say the problem is a dimension mismatch: [xy]head
being (an observable of) a vector and [xy]reference
being (an observable of ) a scalar.
Since your vectors [xy]base
only have one component, just use
xdir = lift(xreference, yreference, xhead, yhead) do x, y, u, v
return [ u[1] - x ]
end
ydir = lift(xreference, yreference, xhead, yhead) do x, y, u, v
return [ v[1] - y ]
end
In the other post I did not anticipate that there might be a dimension mismatch.
So perhaps it would be good to re-organize the code a bit. Building on top of @garrek’s MWE from above:
using GLMakie
fig = Figure()
display(fig)
ax1 = Axis(fig[1, 1])
xlims!(-10, 10)
ylims!(-10, 10)
lsgrid = SliderGrid(fig[1, 2],
(label = "scale", range = -10:0.01:10, format = "{:.1f}", startvalue = 1),
(label = "xcoordinate", range = -10:0.01:10, format = "{:.1f}", startvalue = 1),
(label = "ycoordinate", range = -10:0.01:10, format = "{:.1f}", startvalue = 1),
tellheight = false
)
scale = lsgrid.sliders[1].value
xreference = lsgrid.sliders[2].value
yreference = lsgrid.sliders[3].value
# arrow base points
xbase = @lift([$xreference])
ybase = @lift([$yreference])
refpoint = @lift(Point2f($xreference, $yreference))
scatter!(refpoint, color = :red, markersize = 20)
x = -10:0.01:10
m = @lift($scale .* x.^2)
d = @lift(1 ./ (2 .* $scale) .+ (1 ./ (2 .* $scale)) .* cbrt.((13.5) .* $scale.^2 .* x.^2))
line1 = lines!(ax1, x, m, color = :blue, linewidth = 5)
line2 = lines!(ax1, x, d, color = :red, linewidth = 5)
x = -10:0.01:10
p(x, y, scale) = -(2 * scale * y - 1)^2 / (12 * scale^2) #p
q(x, y, scale) = ((2 * scale * y - 1)^3 - (27 * scale^2) * (x^2)) / (108 * scale^3) #q
del(x, y, scale) = ((27 * scale^2 * x^2 - 2((2 * scale * y) - 1)^3) * x^2) / (1728 * scale^4) #delta
r(x, y, scale) = del(x, y, scale) ≥ 0 ? (-(scale * y + 1)/(3* scale) + cbrt(-q(x, y, scale)/2 + sqrt(del(x, y, scale))) + cbrt(-q(x, y, scale) / 2 - sqrt(del(x, y, scale)))) : -(scale * y + 1) / (3 * scale) + (abs(2 * scale * y + 1) / (3 * scale)) * cos((1/3) * acos((-q(x, y, scale) / 2) / (-p(x, y, scale) / 3)^(3/2))) #piecewise expression
# compute base point of arrow
xhead = lift(xreference, yreference, scale) do x, y, s
return x / (1 + 2 * s * r(x, y, s))
end
yhead = lift(xreference, yreference, scale) do x, y, s
return y + r(x, y, s)
end
# compute direction of arrow
xdir = lift(xreference, yreference, xhead, yhead) do x, y, u, v
return [ u - x ]
end
ydir = lift(xreference, yreference, xhead, yhead) do x, y, u, v
return [ v - y ]
end
# promote arrow data to vectors for usage with arrows! below
v_xhead = @lift([$xhead])
v_yhead = @lift([$yhead])
v_xdir = @lift([$xdir])
v_ydir = @lift([$ydir])
arrows!(ax1, xbase, ybase, xdir, ydir)