3d axes grid and ticks in gr

This commit is contained in:
Daniel Schwabeneder 2019-11-21 16:51:41 +01:00
parent cb6f0772b7
commit 84b108f6d0
3 changed files with 193 additions and 19 deletions

View File

@ -806,6 +806,7 @@ function axis_drawing_info_3d(sp::Subplot)
t = invf(f(0) + 0.012 * (f(ymax) - f(ymin))) t = invf(f(0) + 0.012 * (f(ymax) - f(ymin)))
(-t, t) (-t, t)
else else
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
t = invf(f(y1) + 0.012 * (f(y2) - f(y1)) * ticks_in) t = invf(f(y1) + 0.012 * (f(y2) - f(y1)) * ticks_in)
(y1, t) (y1, t)
end end
@ -830,13 +831,12 @@ function axis_drawing_info_3d(sp::Subplot)
t = invf(f(0) + 0.006 * (f(ymax) - f(ymin))) t = invf(f(0) + 0.006 * (f(ymax) - f(ymin)))
(-t, t) (-t, t)
else else
ticks_in = xaxis[:tick_direction] == :out ? -1 : 1
t = invf(f(y1) + 0.006 * (f(y2) - f(y1)) * ticks_in) t = invf(f(y1) + 0.006 * (f(y2) - f(y1)) * ticks_in)
(y1, t) (y1, t)
end end
for xtick in xminorticks for xtick in xminorticks
if xaxis[:showaxis] if xaxis[:showaxis]
push!(xtick_segs, (xtick, tick_start), (xtick, tick_stop)) # bottom tick push!(xtick_segs, (xtick, tick_start, z1), (xtick, tick_stop, z1)) # bottom tick
end end
if xaxis[:minorgrid] if xaxis[:minorgrid]
if sp[:framestyle] in (:origin, :zerolines) if sp[:framestyle] in (:origin, :zerolines)
@ -856,8 +856,7 @@ function axis_drawing_info_3d(sp::Subplot)
x1, x2 = if sp[:framestyle] in (:origin, :zerolines) x1, x2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0 0.0, 0.0
else else
# TODO: probably flip here xor(yaxis[:mirror], xaxis[:flip]) ? (xmin, xmax) : (xmax, xmin)
xor(yaxis[:mirror], xaxis[:flip]) ? (xmax, xmin) : (xmin, xmax)
end end
z1, z2 = if sp[:framestyle] in (:origin, :zerolines) z1, z2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0 0.0, 0.0
@ -932,14 +931,12 @@ function axis_drawing_info_3d(sp::Subplot)
x1, x2 = if sp[:framestyle] in (:origin, :zerolines) x1, x2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0 0.0, 0.0
else else
# TODO: probably flip here xor(zaxis[:mirror], xaxis[:flip]) ? (xmin, xmax) : (xmax, xmin)
xor(zaxis[:mirror], xaxis[:flip]) ? (xmax, xmin) : (xmin, xmax)
end end
y1, y2 = if sp[:framestyle] in (:origin, :zerolines) y1, y2 = if sp[:framestyle] in (:origin, :zerolines)
0.0, 0.0 0.0, 0.0
else else
# TODO: probably flip here xor(zaxis[:mirror], yaxis[:flip]) ? (ymin, ymax) : (ymax, ymin)
xor(zaxis[:mirror], yaxis[:flip]) ? (ymax, ymin) : (ymin, ymax)
end end
if zaxis[:showaxis] if zaxis[:showaxis]
if sp[:framestyle] != :grid if sp[:framestyle] != :grid

View File

@ -155,6 +155,48 @@ function gr_polyline(x, y, func = GR.polyline; arrowside = :none, arrowstyle = :
end end
end end
function gr_polyline3d(x, y, z, func = GR.polyline3d; arrowside = :none, arrowstyle = :simple)
iend = 0
n = length(x)
while iend < n-1
# set istart to the first index that is finite
istart = -1
for j = iend+1:n
if isfinite(x[j]) && isfinite(y[j]) && isfinite(z[j])
istart = j
break
end
end
if istart > 0
# iend is the last finite index
iend = -1
for j = istart+1:n
if isfinite(x[j]) && isfinite(y[j]) && isfinite(z[j])
iend = j
else
break
end
end
end
# if we found a start and end, draw the line segment, otherwise we're done
if istart > 0 && iend > 0
func(x[istart:iend], y[istart:iend], z[istart:iend])
if arrowside in (:head,:both)
gr_set_arrowstyle(arrowstyle)
GR.drawarrow(x[iend-1], y[iend-1], z[iend-1], x[iend], y[iend], z[iend])
end
if arrowside in (:tail,:both)
gr_set_arrowstyle(arrowstyle)
GR.drawarrow(x[istart+1], y[istart+1], z[istart+1], x[istart], y[istart], z[istart])
end
else
break
end
end
end
gr_inqtext(x, y, s::Symbol) = gr_inqtext(x, y, string(s)) gr_inqtext(x, y, s::Symbol) = gr_inqtext(x, y, string(s))
function gr_inqtext(x, y, s) function gr_inqtext(x, y, s)
@ -1004,30 +1046,163 @@ function gr_display(sp::Subplot{GRBackend}, w, h, viewport_canvas)
isfinite(clims3d[2]) && (zmax = clims3d[2]) isfinite(clims3d[2]) && (zmax = clims3d[2])
end end
GR.setspace(zmin, zmax, round.(Int, sp[:camera])...) GR.setspace(zmin, zmax, round.(Int, sp[:camera])...)
xtick = GR.tick(xmin, xmax) / 2
ytick = GR.tick(ymin, ymax) / 2
ztick = GR.tick(zmin, zmax) / 2
ticksize = 0.01 * (viewport_plotarea[2] - viewport_plotarea[1])
xticks, yticks, zticks, xaxis_segs, yaxis_segs, zaxis_segs, xtick_segs, ytick_segs, ztick_segs, xgrid_segs, ygrid_segs, zgrid_segs, xminorgrid_segs, yminorgrid_segs, zminorgrid_segs, xborder_segs, yborder_segs, zborder_segs = axis_drawing_info_3d(sp)
# draw the grid lines
if xaxis[:grid] if xaxis[:grid]
gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid]) gr_set_line(xaxis[:gridlinewidth], xaxis[:gridstyle], xaxis[:foreground_color_grid])
gr_set_transparency(xaxis[:foreground_color_grid], xaxis[:gridalpha]) gr_set_transparency(xaxis[:foreground_color_grid], xaxis[:gridalpha])
GR.grid3d(xtick, 0, 0, xmin, ymax, zmin, 2, 0, 0) gr_polyline3d(coords(xgrid_segs)...)
end end
if yaxis[:grid] if yaxis[:grid]
gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid]) gr_set_line(yaxis[:gridlinewidth], yaxis[:gridstyle], yaxis[:foreground_color_grid])
gr_set_transparency(yaxis[:foreground_color_grid], yaxis[:gridalpha]) gr_set_transparency(yaxis[:foreground_color_grid], yaxis[:gridalpha])
GR.grid3d(0, ytick, 0, xmin, ymax, zmin, 0, 2, 0) gr_polyline3d(coords(ygrid_segs)...)
end end
if zaxis[:grid] if zaxis[:grid]
gr_set_line(zaxis[:gridlinewidth], zaxis[:gridstyle], zaxis[:foreground_color_grid]) gr_set_line(zaxis[:gridlinewidth], zaxis[:gridstyle], zaxis[:foreground_color_grid])
gr_set_transparency(zaxis[:foreground_color_grid], zaxis[:gridalpha]) gr_set_transparency(zaxis[:foreground_color_grid], zaxis[:gridalpha])
GR.grid3d(0, 0, ztick, xmin, ymax, zmin, 0, 0, 2) gr_polyline3d(coords(zgrid_segs)...)
end end
gr_set_line(1, :solid, xaxis[:foreground_color_axis])
gr_set_transparency(xaxis[:foreground_color_axis]) if xaxis[:minorgrid]
GR.axes3d(xtick, 0, ztick, xmin, ymin, zmin, 2, 0, 2, -ticksize) gr_set_line(xaxis[:minorgridlinewidth], xaxis[:minorgridstyle], xaxis[:foreground_color_minor_grid])
GR.axes3d(0, ytick, 0, xmax, ymin, zmin, 0, 2, 0, ticksize) gr_set_transparency(xaxis[:foreground_color_minor_grid], xaxis[:minorgridalpha])
gr_polyline3d(coords(xminorgrid_segs)...)
end
if yaxis[:minorgrid]
gr_set_line(yaxis[:minorgridlinewidth], yaxis[:minorgridstyle], yaxis[:foreground_color_minor_grid])
gr_set_transparency(yaxis[:foreground_color_minor_grid], yaxis[:minorgridalpha])
gr_polyline3d(coords(yminorgrid_segs)...)
end
if zaxis[:minorgrid]
gr_set_line(zaxis[:minorgridlinewidth], zaxis[:minorgridstyle], zaxis[:foreground_color_minor_grid])
gr_set_transparency(zaxis[:foreground_color_minor_grid], zaxis[:minorgridalpha])
gr_polyline3d(coords(zminorgrid_segs)...)
end
gr_set_transparency(1.0)
# axis lines
if xaxis[:showaxis]
gr_set_line(1, :solid, xaxis[:foreground_color_border])
GR.setclip(0)
gr_polyline3d(coords(xaxis_segs)...)
end
if yaxis[:showaxis]
gr_set_line(1, :solid, yaxis[:foreground_color_border])
GR.setclip(0)
gr_polyline3d(coords(yaxis_segs)...)
end
if zaxis[:showaxis]
gr_set_line(1, :solid, zaxis[:foreground_color_border])
GR.setclip(0)
gr_polyline3d(coords(zaxis_segs)...)
end
GR.setclip(1)
# axis ticks
if xaxis[:showaxis]
if sp[:framestyle] in (:zerolines, :grid)
gr_set_line(1, :solid, xaxis[:foreground_color_grid])
gr_set_transparency(xaxis[:foreground_color_grid], xaxis[:tick_direction] == :out ? xaxis[:gridalpha] : 0)
else
gr_set_line(1, :solid, xaxis[:foreground_color_axis])
end
GR.setclip(0)
gr_polyline3d(coords(xtick_segs)...)
end
if yaxis[:showaxis]
if sp[:framestyle] in (:zerolines, :grid)
gr_set_line(1, :solid, yaxis[:foreground_color_grid])
gr_set_transparency(yaxis[:foreground_color_grid], yaxis[:tick_direction] == :out ? yaxis[:gridalpha] : 0)
else
gr_set_line(1, :solid, yaxis[:foreground_color_axis])
end
GR.setclip(0)
gr_polyline3d(coords(ytick_segs)...)
end
if zaxis[:showaxis]
if sp[:framestyle] in (:zerolines, :grid)
gr_set_line(1, :solid, zaxis[:foreground_color_grid])
gr_set_transparency(zaxis[:foreground_color_grid], zaxis[:tick_direction] == :out ? zaxis[:gridalpha] : 0)
else
gr_set_line(1, :solid, zaxis[:foreground_color_axis])
end
GR.setclip(0)
gr_polyline3d(coords(ztick_segs)...)
end
GR.setclip(1)
# TODO: tick labels
# # tick marks
# if !(xticks in (:none, nothing, false)) && xaxis[:showaxis]
# # x labels
# flip, mirror = gr_set_xticks_font(sp)
# for (cv, dv) in zip(xticks...)
# # use xor ($) to get the right y coords
# xi, yi = GR.wctondc(cv, sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? ymax : ymin)
# if xaxis[:ticks] in (:auto, :native)
# # ensure correct dispatch in gr_text for automatic log ticks
# if xaxis[:scale] in _logScales
# dv = string(dv, "\\ ")
# elseif xaxis[:formatter] in (:scientific, :auto)
# dv = convert_sci_unicode(dv)
# end
# end
# gr_text(xi, yi + (mirror ? 1 : -1) * 5e-3 * (xaxis[:tick_direction] == :out ? 1.5 : 1.0), string(dv))
# end
# end
#
# if !(yticks in (:none, nothing, false)) && yaxis[:showaxis]
# # y labels
# flip, mirror = gr_set_yticks_font(sp)
# for (cv, dv) in zip(yticks...)
# # use xor ($) to get the right y coords
# xi, yi = GR.wctondc(sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? xmax : xmin, cv)
# # @show cv dv xmin xi yi
# if yaxis[:ticks] in (:auto, :native)
# # ensure correct dispatch in gr_text for automatic log ticks
# if yaxis[:scale] in _logScales
# dv = string(dv, "\\ ")
# elseif yaxis[:formatter] in (:scientific, :auto)
# dv = convert_sci_unicode(dv)
# end
# end
# gr_text(xi + (mirror ? 1 : -1) * 1e-2 * (yaxis[:tick_direction] == :out ? 1.5 : 1.0), yi, string(dv))
# end
# end
#
# if !(zticks in (:none, nothing, false)) && zaxis[:showaxis]
# # y labels
# flip, mirror = gr_set_yticks_font(sp) # TODO for z
# for (cv, dv) in zip(zticks...)
# # use xor ($) to get the right y coords
# xi, yi = GR.wctondc(sp[:framestyle] == :origin ? 0 : xor(flip, mirror) ? xmax : xmin, cv)
# # @show cv dv xmin xi yi
# if yaxis[:ticks] in (:auto, :native)
# # ensure correct dispatch in gr_text for automatic log ticks
# if yaxis[:scale] in _logScales
# dv = string(dv, "\\ ")
# elseif yaxis[:formatter] in (:scientific, :auto)
# dv = convert_sci_unicode(dv)
# end
# end
# gr_text(xi + (mirror ? 1 : -1) * 1e-2 * (yaxis[:tick_direction] == :out ? 1.5 : 1.0), yi, string(dv))
# end
# end
#
# # border
# intensity = sp[:framestyle] == :semi ? 0.5 : 1.0
# if sp[:framestyle] in (:box, :semi)
# gr_set_line(intensity, :solid, xaxis[:foreground_color_border])
# gr_set_transparency(xaxis[:foreground_color_border], intensity)
# gr_polyline3d(coords(xborder_segs)...)
# gr_set_line(intensity, :solid, yaxis[:foreground_color_border])
# gr_set_transparency(yaxis[:foreground_color_border], intensity)
# gr_polyline3d(coords(yborder_segs)...)
# end
elseif ispolar(sp) elseif ispolar(sp)
r = gr_set_viewport_polar() r = gr_set_viewport_polar()

View File

@ -152,9 +152,11 @@ Segments(p::Int) = Segments(NTuple{p, Float64}[])
to_nan(::Type{Float64}) = NaN to_nan(::Type{Float64}) = NaN
to_nan(::Type{NTuple{2,Float64}}) = (NaN, NaN) to_nan(::Type{NTuple{2,Float64}}) = (NaN, NaN)
to_nan(::Type{NTuple{3,Float64}}) = (NaN, NaN, NaN)
coords(segs::Segments{Float64}) = segs.pts coords(segs::Segments{Float64}) = segs.pts
coords(segs::Segments{NTuple{2,Float64}}) = Float64[p[1] for p in segs.pts], Float64[p[2] for p in segs.pts] coords(segs::Segments{NTuple{2,Float64}}) = Float64[p[1] for p in segs.pts], Float64[p[2] for p in segs.pts]
coords(segs::Segments{NTuple{3,Float64}}) = Float64[p[1] for p in segs.pts], Float64[p[2] for p in segs.pts], Float64[p[3] for p in segs.pts]
function Base.push!(segments::Segments{T}, vs...) where T function Base.push!(segments::Segments{T}, vs...) where T
if !isempty(segments.pts) if !isempty(segments.pts)