diff --git a/src/arrow_visualizer.jl b/src/arrow_visualizer.jl index 5b54205..0eccf36 100644 --- a/src/arrow_visualizer.jl +++ b/src/arrow_visualizer.jl @@ -22,25 +22,32 @@ function settransform!(vis::ArrowVisualizer, base::Point{3}, vec::Vec{3}; max_head_radius=2*shaft_radius, max_head_length=max_head_radius) vec_length = norm(vec) - rotation = if vec_length > eps(typeof(vec_length)) + T = typeof(vec_length) + rotation = if vec_length > eps(T) rotation_between(SVector(0., 0., 1.), vec) else one(Quat{Float64}) end |> LinearMap + vis_tform = Translation(base) ∘ rotation + settransform!(vis.vis, vis_tform) + shaft_length = max(vec_length - max_head_length, 0) - shaft_scaling = LinearMap(Diagonal(SVector(shaft_radius, shaft_radius, shaft_length))) - shaft_tform = Translation(base) ∘ rotation ∘ shaft_scaling - settransform!(vis.vis, shaft_tform) - - if vec_length > eps(typeof(vec_length)) - head_length = vec_length - shaft_length - head_radius = max_head_radius * head_length / max_head_length - head_scaling = LinearMap(Diagonal(SVector(head_radius, head_radius, head_length))) - head_tform = inv(shaft_scaling) ∘ Translation(shaft_length * Vec(0, 0, 1)) ∘ head_scaling - # head_tform = Translation(base) ∘ rotation ∘ Translation(shaft_length * Vec(0, 0, 1)) ∘ head_scaling - settransform!(vis.vis[:head], head_tform) + shaft_scaling_diag = SVector(shaft_radius, shaft_radius, shaft_length) + if iszero(shaft_length) + # This case is necessary to ensure that the shaft + # completely disappears in animations. + shaft_scaling_diag = zero(shaft_scaling_diag) end + shaft_scaling = LinearMap(Diagonal(shaft_scaling_diag)) + settransform!(vis.vis[:shaft], shaft_scaling) + + head_length = vec_length - shaft_length + head_radius = max_head_radius * head_length / max_head_length + head_scaling = LinearMap(Diagonal(SVector(head_radius, head_radius, head_length))) + head_tform = Translation(shaft_length * Vec(0, 0, 1)) ∘ head_scaling + # head_tform = Translation(base) ∘ rotation ∘ Translation(shaft_length * Vec(0, 0, 1)) ∘ head_scaling + settransform!(vis.vis[:head], head_tform) vis end diff --git a/test/visualizer.jl b/test/visualizer.jl index 61109b4..cab6117 100644 --- a/test/visualizer.jl +++ b/test/visualizer.jl @@ -197,6 +197,10 @@ end arrow_vis_1 = ArrowVisualizer(vis[:arrow1]) show(devnull, arrow_vis_1) setobject!(arrow_vis_1) + for l in [range(0, stop=1e-2, length=1000); 1.1 * eps(Float64)] + settransform!(arrow_vis_1, Point(0, 1, 0), Vec(0, 0, l)) + end + settransform!(arrow_vis_1, Point(0, 1, 0), Vec(0, 0, 1.1 * eps(Float64))) settransform!(arrow_vis_1, Point(0, 1, 0), Vec(1, 1, 1)) setobject!(vis[:arrow1_base], HyperSphere(Point(0., 1., 0.), 0.015)) setobject!(vis[:arrow1_tip], HyperSphere(Point(1., 2., 1.), 0.015))