Closed hustf closed 3 years ago
Perhaps the decorate
keyword argument could be used/adapted for this?
I think most of what you want can be achieved with the decorate
functionality:
using Luxor
function fletcher()
line(O, polar(30, deg2rad(220)), :stroke)
line(O, polar(30, deg2rad(140)), :stroke)
end
function hollowarrowhead(shaftendpoint, endpoint, shaftangle)
@layer begin
sidept1 = shaftendpoint + polar(10, shaftangle + π/2 )
sidept2 = shaftendpoint - polar(10, shaftangle + π/2)
poly([sidept1, endpoint, sidept2], :fill)
poly([sidept1, endpoint, sidept2], :stroke, close=false)
end
end
@drawsvg begin
tiles = Tiler(600, 600, 2, 2)
background("grey99")
@layer begin
translate(first(tiles[1]))
sethue("orange")
arrow(O, O + (150, 100),
linewidth=4,
decorate=fletcher,
arrowheadfunction = hollowarrowhead,
decoration=range(0.1, .2, length=3))
end
@layer begin
translate(first(tiles[2]))
sethue("blue")
arrow(O, 50, 0, π + π/3,
linewidth=4,
decorate=fletcher,
arrowheadfunction = hollowarrowhead,
decoration=range(0.1, .3, length=3))
end
@layer begin
translate(first(tiles[3]))
sethue("purple")
arrow(O, O + (150, 10), [15, 15],
linewidth=4,
decorate=fletcher,
arrowheadfunction = hollowarrowhead,
decoration=range(0.1, .2, length=3))
end
@layer begin
sethue("red")
translate(first(tiles[4]))
arrow(box(O, 100, 100, vertices=true)...,
linewidth=4,
decorate=fletcher,
arrowheadfunction = hollowarrowhead,
decoration=range(0.1, .2, length=3))
end
end
I've fixed a few things in the code which weren't ideal.
Thanks for looking into this idea. Sorry for the delay in replying.
Something like the curved fletchings you demonstrated above could be an easily perceivable visualization of angular momentum.
Imagine similar arrows used in an animation of a distributed mass pendulum. Fletched arrows to represent angular momentum, unfletched to represent torque. The length of the arcs would cross zero during the animation. Fletchings would need scaling down when the arrow length is below a treshold. The treshold would depend on the length of spine and also the shape of decorations. The fletchings might fit best only on the outside of curvature.
So the interface soon becomes complicated, and users like yours truly always have the option of drawing their own wonderful superarrows.
As for passing more arguments and context to 'decorate' functions. That would be nice, but for backwards compatibility an argument-less callback would need to be acceptable. We could wish that something like the following would work (but it doesn't, and wouldn't be inferrable to the compiler).
function custom_luxor_arrow1(pt; linewidth = 1.0, decoratorfunc = (;kwa...) -> nothing, kw...)
args = union(kw, :linewidth => linewidth)
if applicable(decoratorfunc, args...)
println("kwargs applicable")
decoratorfunc(;args...)
else
decoratorfunc()
end
end
Many thanks for your insights and observations!
Is there anything specific to be done here…?
I think Luxor’s job is to provide basic tools to make simple drawings; for more complex work it should be possible to write your own custom functions, or else it will necessary to advance to more powerful systems such as TikZ or Asymptote. Complex interfaces tend to beneficial to fewer people…
I fully agree!
Ref #158.
Arrows are wonderfully powerful symbols. The brand new custom arrowhead approach is really flexible and elegant.
I was thinking that perhaps a natural extension to the custom head functionality is a custom vane / notch / fletching function?
As in,
But on second thought, a 'fletching' function might need more (keyword?) parameters to be as useful as the custom head function. Because there's a edge case with short spines, where the vanes would start before the tip.
Below is the function that made those 'velocity arrows'.