-
-
Save ffreyer/4008c0aec6bd5b62884e9bdab545e939 to your computer and use it in GitHub Desktop.
Debug Examples
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GLMakie.closeall() | |
scene = Scene() | |
xs = Observable([0.8, -0.8, -0.8, -0.4, 0.8, 0.1, NaN, 0.0, -0.6]) | |
ys = Observable([0.9, 0.9, 0.1, 0.3, 0.1, 0.7, NaN, 0.7, 0.5]) | |
lines!(scene, xs, ys, linestyle = nothing, linewidth = 20, color = :orange) | |
lines!(scene, xs, ys, linestyle = :dot, linewidth = 20) | |
lines!(scene, xs, map(y -> y .- 0.9, ys), linestyle = nothing, linewidth = 20, color = :orange) | |
lines!(scene, xs, map(y -> y .- 0.9, ys), linestyle = :dash, linewidth = 20) | |
# scatter!(scene, xs, map(y -> y .- 0.9, ys), color = :red) | |
screen = display(scene) | |
# Makie.record(scene, "prototype.mp4", vcat(0:120, 119:-1:1), fps = 30) do i | |
# xs[][1] = 0.8 - i/200 | |
# notify(ys) | |
# end | |
robj = screen.renderlist[1][3] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
GLMakie.closeall() | |
scene = Scene(resolution = (600, 600)) | |
ps = [0.8 * Point2f(cos(x), sin(x)) for x in range(0, pi, length=21)] | |
push!(ps, | |
Point2f(-0.3, 0), | |
Point2f(-0.3, 0.4), | |
Point2f(-0.05, 0.4), | |
Point2f(0.0, 0.0), | |
Point2f(0.05, 0.4), | |
Point2f(0.3, 0.4), | |
Point2f(0.3, 0.0), | |
Point2f(0.8, 0.0) | |
) | |
p = lines!( | |
scene, | |
ps, | |
linestyle = :dash, | |
linewidth = 25, | |
color = (:black, 1.0) | |
) | |
s = scatterlines!(scene, p.converted[1], color = :blue, markersize = 10) | |
screen = display(scene) | |
robj = screen.renderlist[1][3] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fig = Figure() | |
ax = Axis(fig[1, 1], aspect = DataAspect()) | |
xlims!(ax, -3, 6) | |
ylims!(ax, -4, 2) | |
# line points | |
ls = Observable(Point2f[(-2, -2), (0, 0), (5, -3)]) | |
lw = Observable(50) | |
# constants | |
AA_THICKNESS = 4 | |
MITER_LIMIT = -0.4 | |
# Semi constants | |
pattern = GLMakie.ticks([0, 50, 150], 100) | |
pattern_length = 150 | |
line_data = map(ls, lw, ax.scene.camera.projectionview, ax.scene.camera.resolution | |
) do ps, lw, pv, res | |
lw = 0.5lw | |
screen_pos = map(ps) do p | |
p4 = to_ndim(Point4f, to_ndim(Point3f, p, 0), 1) | |
p4_clip = pv * p4 | |
return Point2f(0.5 .* res .* (1 .+ p4_clip[Vec(1,2)]) / p4_clip[4]) | |
end | |
lastlen = GLMakie.sumlengths(screen_pos) | |
indices = [1, eachindex(screen_pos)..., length(screen_pos)] | |
# Triangle definitions | |
v_pos = Point2f[] | |
v_idx = Vec3{Int}[] | |
v_uv = Point2f[] | |
# Metadata | |
line_vecs = Vec2f[] | |
normals = Vec2f[] | |
miter_vecs = Vec2f[] | |
miter_lengths = Float32[] | |
# geom shader | |
for i in 2:length(indices)-2 | |
# match 0, 1, 2, 3 in shader | |
i0, i1, i2, i3 = idx_range = indices[i-1:i+2] | |
# simplified to not include NaN | |
isvalid = [i0 != i1, true, true, i2 != i3] | |
# can skip NaN skip | |
p0, p1, p2, p3 = screen_pos[idx_range] | |
# don't consider per vertex linewidth | |
thickness_aa2 = thickness_aa1 = lw + AA_THICKNESS | |
v0 = (p0 != p1 && isvalid[1]) ? normalize(p1 - p0) : normalize(p2 - p1) | |
v1 = normalize(p2 - p1) | |
v2 = (p2 != p3 && isvalid[4]) ? normalize(p3 - p2) : normalize(p2 - p1) | |
push!(line_vecs, v1) | |
n0 = Vec2f(-v0[2], v0[1]) | |
n1 = Vec2f(-v1[2], v1[1]) | |
n2 = Vec2f(-v2[2], v2[1]) | |
push!(normals, n1) | |
miter_a = normalize(n0 + n1) | |
miter_b = normalize(n1 + n2) | |
push!(miter_vecs, miter_a) | |
length_a = thickness_aa1 / dot(miter_a, n1) | |
length_b = thickness_aa2 / dot(miter_b, n1) | |
push!(miter_lengths, length_a) | |
# insert triangle | |
if dot(v0, v1) < MITER_LIMIT | |
@info "MITER" | |
N = length(v_pos)+1 | |
if dot(v0, n1) > 0 | |
push!(v_pos, p1 + thickness_aa1 * n0, p1 + thickness_aa1 * n1, p1) | |
push!(v_uv, | |
Point2(lastlen[i1] * 0.5 / pattern_length, -thickness_aa1), | |
Point2(lastlen[i1] * 0.5 / pattern_length, -thickness_aa1), | |
Point2(lastlen[i1] * 0.5 / pattern_length, 0.0) | |
) | |
push!(v_idx, Vec3(N, N+1, N+2)) | |
else | |
push!(v_pos, p1 - thickness_aa1 * n0, p1, p1 - thickness_aa1 * n1) | |
push!(v_uv, | |
Point2(lastlen[i1] * 0.5 / pattern_length, thickness_aa1), | |
Point2(lastlen[i1] * 0.5 / pattern_length, 0.0), | |
Point2(lastlen[i1] * 0.5 / pattern_length, thickness_aa1), | |
) | |
push!(v_idx, Vec3(N, N+1, N+2)) | |
end | |
miter_a = n1 | |
length_a = thickness_aa1 | |
else | |
nothing | |
end | |
if dot(v1, v2) < MITER_LIMIT | |
miter_b = n1 | |
length_b = thickness_aa2 | |
else | |
nothing | |
end | |
N = length(v_pos)+1 | |
push!(v_pos, | |
p1 + length_a * miter_a, p1 - length_a * miter_a, | |
p2 + length_b * miter_b, p2 - length_b * miter_b | |
) | |
push!(v_uv, | |
Point2((lastlen[i1] + length_a * dot(miter_a, v1)) * 0.5 / pattern_length, -thickness_aa1), | |
Point2((lastlen[i1] - length_a * dot(miter_a, v1)) * 0.5 / pattern_length, thickness_aa1), | |
Point2((lastlen[i2] + length_b * dot(miter_b, v1)) * 0.5 / pattern_length, -thickness_aa2), | |
Point2((lastlen[i2] - length_b * dot(miter_b, v1)) * 0.5 / pattern_length, thickness_aa2), | |
) | |
push!(v_idx, Vec3(N, N+1, N+2), Vec3(N+1, N+2, N+3)) | |
end | |
# Let's just dump information | |
return ( | |
v_pos, v_idx, v_uv, | |
screen_pos, line_vecs, normals, miter_vecs, miter_lengths, | |
(0.5 / pattern_length) .* lastlen | |
) | |
end | |
# draw actual lines | |
lines!(ax, ls, linewidth = 50, linestyle = :dot, linecap = nothing) | |
# visualize expanded line | |
_mesh = map(line_data) do (v_pos, v_idx, v_uv, _, _, _, _) | |
GeometryBasics.Mesh(meta(v_pos), GLTriangleFace.(v_idx)) | |
end | |
mesh!(ax, _mesh, color = (:lightblue, 0.3), space = :pixel, shading = false, fxaa = false) | |
wireframe!(ax, _mesh, color = :black, space = :pixel) | |
# # line vectors and normals | |
# line_vecs = map(line_data, lw) do data, lw | |
# origins = getindex(data, 4) | |
# vecs = lw * getindex(data, 5) | |
# ps = [origins[div(1+i, 2)] for i in 1:2length(vecs)] | |
# ps[2:2:end] .+= vecs | |
# ps | |
# end | |
# line_normals = map(line_data, lw) do data, lw | |
# origins = getindex(data, 4) | |
# vecs = lw * getindex(data, 6) | |
# ps = [origins[div(1+i, 2)] for i in 1:2length(vecs)] | |
# ps[2:2:end] .+= vecs | |
# ps | |
# end | |
# linesegments!(ax, line_vecs, color = :blue, space = :pixel, linewidth=5) | |
# linesegments!(ax, line_normals, color = :blue, space = :pixel, linewidth=5) | |
# # miter and length | |
# miter = map(line_data) do data | |
# origins = getindex(data, 4) | |
# miters = getindex(data, 7) .* getindex(data, 8) | |
# ps = [origins[div(1+i, 2)] for i in 1:2length(miters)] | |
# ps[2:2:end] .+= miters | |
# ps | |
# end | |
# linesegments!(ax, miter, color = :green, space = :pixel, linewidth=5) | |
# Visualize dot positions | |
ps = map(line_data) do data | |
origins = getindex(data, 4) | |
vecs = getindex(data, 5) | |
us = getindex(data, 9) | |
ps = Point2f[] | |
target = 0.5 * 25 / 150 | |
for i in 1:length(us)-1 | |
for u in 0:0.5:ceil(us[i+1] - us[i] + (us[i] % 0.5)) | |
push!(ps, origins[i] + (target + u - (us[i] % 0.5)) * 300 * vecs[i]) | |
end | |
end | |
ps | |
end | |
scatter!( | |
ax, ps, color = :orange, marker = Circle, markersize = 5, | |
strokewidth = 2, strokecolor = :black, space = :pixel | |
) | |
scatter!( | |
ax, ps, color = :transparent, marker = Circle, markersize = 50, | |
strokewidth = 2, strokecolor = :black, space = :pixel | |
) | |
# # Visualize us | |
# ps_us = map(line_data) do data | |
# origins = getindex(data, 4) | |
# vecs = getindex(data, 5) | |
# us = getindex(data, 9) | |
# segments = Point2f[] | |
# final_us = Float32[] | |
# for i in 1:length(us)-1 | |
# push!(segments, origins[i]) | |
# push!(final_us, us[i] % 1.0) | |
# for u in 0:0.5:ceil(us[i+1] - us[i] + (us[i] % 0.5)) | |
# push!(segments, origins[i] + (u - (us[i] % 0.5)) * 300 * vecs[i]) | |
# push!(segments, origins[i] + (u - (us[i] % 0.5)) * 300 * vecs[i]) | |
# push!(final_us, 1.0, 0.0) | |
# end | |
# pop!(segments) | |
# pop!(final_us) | |
# end | |
# segments, final_us | |
# end | |
# linesegments!( | |
# ax, map(first, ps_us), color = map(last, ps_us), colorrange = (0, 1), | |
# colormap = [:black, :red], linewidth = 10, space = :pixel | |
# ) | |
# # center line | |
# lines!(ax, ls, color = :red) | |
# raw data | |
plt = scatter!( | |
ax, ls, color = :white, strokecolor = :green, strokewidth = 2, | |
overdraw = true | |
) | |
selected = Ref(-1) | |
on(events(fig).mousebutton, priority = 1000) do event | |
if event.button == Mouse.left | |
if event.action == Mouse.press | |
p, idx = pick(fig, mouseposition_px(fig)) | |
if p == plt | |
selected[] = idx | |
return Consume(true) | |
end | |
elseif event.action == Mouse.release | |
selected[] = -1 | |
end | |
end | |
return Consume(false) | |
end | |
on(events(fig).mouseposition, priority = 1000) do _ | |
if selected[] != -1 | |
mpos = mouseposition(ax) | |
ls[][selected[]] = mpos | |
notify(ls) | |
return Consume(true) | |
end | |
return Consume(false) | |
end | |
fig |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment