It would be a lot easier to be sure that my test linkages are working if I could see pictures. That’s nearly convenient. Nearly.
SuzannaLinn, who teaches SLua courses, provided a library for drawing with SVG (Scaled Vector Graphics). In Second Life, that is reasonably useful, because you can open HTTP media in SL. On my Mac, Luau’s sandboxing is quite complete. I can’t serve a web page, write a file, or even copy text to the Mac pasteboard.
So it’s not totally convenient, but I can print the necessary HTML, copy it, paste it, save it, and then view it as a file. And, of course, I can paste it in here:
So you can see what I see. The above is just an experiment as I get the scaling set up. I plan to record here what I do, so that, the next time I need this, I won’t have to work so hard to re-learn how.
I am having to hack Suzanna’s library a bit. First of all, I want the origin of my pictures to be lower left, and SVG thinks top left with y increasing downward is a good idea. It isn’t. So I’ve figured out how to do the necessary scaling and translating to turn the y axis upside down, that is to say, rightside up.
I’ve turned Suzanna’s code into a file that can be used with require
. It returns a hash table mapping all the SVG objects (tables) in the library to their text names. As one does. So the code I wrote for the picture above is just this:
local Circle = svg.Circle
local Rect = svg.Rect
local Shape = svg.Shape
local height = 640
local x_axis = 100
Rect{x=0, y=0, width=640, height=height, fill=0x191919}
local wheel = svg.Circle{cx=40, cy=40, r=20, stroke="red"}
local wheel2 = svg.Circle{cx=140, cy=40, r=20, stroke="green"}
wheel:scale(2)
wheel2:scale(2)
print(Shape:draw())
I have hacked an SVG “group” into Suzanna’s code. Providing a real group capability would be a bit tricky since with XML we would have to open the group, do whatever was inside it, and then close it. So there would need to be some kind of nested structure. That is not provided in our existing library, and for our purposes, one group to set up the scaling should be just fine.
I’d like to work, in the code, with small numbers, because in SL, an entire locomotive is only maybe three or four meters tall, wheels are around one meter in diameter, and so on. And anyway, when writing tests, small numbers are easier to calculate.
In the SVG created above, you might notice that the circles have radius 20. I’d like them to have radius 2. So let’s start with that and fix up the group scaling. That will give me occasion to show what I’ve done and explain it for future me.
If the radius is 2, then the y coordinate should be 2 as well, so I’ll change the wheels to this:
local wheel = svg.Circle{cx=5, cy=2, r=2, stroke="red"}
local wheel2 = svg.Circle{cx=14, cy=2, r=2, stroke="green"}
I think we’ll really want the diagram to be a different shape and to have the X axis part way up. We’ll get there. My process for this is simply to make small changes in the direction I want to go, until I get a picture that I like. But the bottoms of the drive wheels are pretty much the bottom of the train, so putting y=0 about a third of the way up or less is probably where we’ll wind up.
I expect this code to draw two very small circles. It does. Do you want to see? OK:
I’ll adjust the numbers in the SVG writing by hand and then extract them either as constants in the code, or, if I get that far, as parameters in the draw
method.
“Hahaha”, she laughed. “I changed the scale from 1,-1 to 10,-10. The picture wasn’t quite what I expected, though it’s clear what happened.”
I am really quite amused by the big fat lines. SVG really does scale everything. I can deal with that by changing the stroke-width used in my drawing code. I wonder if there is a default being set. Oh: can we set stroke width in the group? I’ll try that first.
After a bit of trouble, I find out how to do it. The Shape object in the SVG file was setting a default stroke width of 1. I changed it not to do that. This may not be a righteous change. But anyway I have the picture now with thin-lined circles at the very bottom.
I was hoping that I could put the x-axis offset into my group, but that’s not going to work, because my background rectangle is inside the group, so its fill is also offset. Maybe if I offset it the other way. After a bit of tweaking, I have a picture that I like:
The generated SVG for that, just in case you want to see it, is:
<svg width="640" height="480" xmlns="http://www.w3.org/2000/svg" version="1.1">
<g stroke-width="0.1" transform="translate(0,380) scale(10,-10) " >
<rect x="0" y="0" width="640" height="480" fill="1644825" stroke="none" opacity="1" transform="translate(0, -100)" />
<circle cx="5" cy="2" r="2" fill="none" stroke="red" opacity="1" transform="scale(2, 2)" />
<circle cx="14" cy="2" r="2" fill="none" stroke="green" opacity="1" transform="scale(2, 2)" />
</g> </svg>
Not pretty but it’s doing what I need, at least for now.
The SVC library is not generalized. It has some built-in values and at least one of them is embedded in a large string, though I did manage to put the other into a string with substitution from some declared literal values.
I think that from here I can begin rigging my objects to draw themselves. We’ll call the morning’s work done at this point.
The current SVG code is in SVG.lua in the repo.
Safe paths!