It may be that your application is too advanced for the simple drawing paradigm used by Luxor
I’ve seen the amazing examples you have throughout the docs and can therefore say with confidence that my use case is not beyond the capabilities of Luxor FWIW, the use case is a personal project / toy application that will convert arbitrary unicode strings into text that looks like Nomai writing from the (excellent) game Outer Wilds, e.g.:
structure that stores the current matrix for each point
Ah, that makes sense. How do I then translate an instance of PointMatrix
to a Point
in the current coordinate system? Do I need to multiply inv(cairotojuliamatrix(pm.matrix)) * [p.x, p.y, 1.0]
to get the “global” coordinates, then multiply by cairotojuliamatrix(getmatrix())
?
(I’m sorry Luxor is confusing - is there too little documentation, or too much?)
I don’t mean to be ungrateful for useful software freely provided! Definitely happy to discuss any of this more by DM/email/this thread/etc if it’s helpful to you. My new user experience was:
- Easy installation, easy to get first graphics shown, all that great. It was not a priori obvious to me how much drastically easier it’d be to learn Luxor in Pluto with
@drawsvg
rather than Drawing(...) ... finish; preview()
in the REPL. Faster feedback loops!
- Some curse of knowledge in the docs, where the neophyte reader has to infer basic things the docs author already knows. Examples include
- That a core workflow is the transform - draw from origin - untransform loop
- Relatedly trying to keep track of absolute positions is probably doomed.
- All drawing is stateful and happens at global state. (I think…though now I wonder how different Pluto cells each with
@drawsvg
macros work.) The combination of global state + stateful drawing “feels” very different than most Julia code which seems to emphasize a highly functional side-effect-free style. Big brain shift.
- That if you want to draw a series of connecting lines you need a polygon, not
line
- Some of the examples are, IMHO, “too clever.” E.g.:
- Even the first quick and short tutorial is doing clever things with colors and overlapping circles and rescaling, which takes precious brain cycles to parses for a new reader still literally trying to figure out which way is up.
c = colors[mod1(n, end)]
for i in 5:-0.1:1
setcolor(rescale(i, 5, 1, 0.5, 3) .* c)
circle(pos + (i/2, i/2), rescale(i, 5, 1, radius, radius/6), action = :fill)
end
- There are a lot of docs. Mostly this is good!
- Most of my confusions were eventually resolved by searching through the docs.
- Unsurprisingly, lots of the docs had to do with stuff that wasn’t relevant to me. That’s always going to happen since not every project touches every bit of functionality, but does slightly give a sense of “woah there’s a lot here and I am confused” for a new user. E.g. I don’t need image/pixel functionality, animations, typesetting.
- I think I personally made a mistake by not starting with the explanations section of the docs. (Thinking here of 4 kinds of documentation.) I started at the basic tutorial and that ended up maybe confusing me more.
- Now that I’ve built a mental map of the territory, the docs feel nice and well organized, but n=1 the first few nights of playing with Luxor I didn’t know what I was looking for.
I will say that a lot of the docstrings on individual functions feel pretty sparse. The written explanations/tutorials are good, the reference is comprehensive, but the docstrings don’t connect to concepts. E.g. if I’ve just learned about moving the coordinate system, do I want move
or translate
? That took me a while. translate
says “Translate the workspace to x
and y
or to pt
.” which feels similar to move
’s “move to a point”.
A partial list of things that confused me in my first days with Luxor:
- Why are there two coordinate systems, upper-left origin and center origin? Which do I want?
- Oh wait there are three, current coordinates are different. Can I just not use stateful transformations and work with a single global system?
- What’s
move
vs translate
?
- Okay the matrix represents the current transformation, but why is it 2x3? Why do I keep hearing about 3x3 matrices? Why do the examples keep manually setting the matrix values? That doesn’t feel like “for tourists!” How do I apply a matrix to a point?
- The docs mention that paths can have subpaths, but how do I create a subpath?
- What if I want to make joined lines in a
T
shape, ie there’s one vertex with 3 lines coming out of it. Is that possible or do I have to make a L
poly and then just add a line
?
- How can I create a polygon once and then draw copies of it?
Anyway I think Luxor is probably the right tool it’s just taken me a while to learn the basics of Luxorthought. Thanks for the package!