| The Universe of Discourse | |||||||||||||||||||||||||||||||||||||||
|
12 recent entries Archive:
Comments disabled |
Sat, 20 Jan 2007
Another Linogram success story
Here was today's surprise. For a long time, my demo diagram has been a rough rendering of one of the figures from Higher-Order Perl: (It's big, so this is a reduced version; click to expand it.) I wanted component k in the middle of the diagram to be a curved line, but since I didn't have curved lines yet, I used two straight lines instead, as shown below:
define bentline {
line upper, lower;
param number depth = 0.2;
point start, end, center;
constraints {
center = upper.end = lower.start;
start = upper.start; end = lower.end;
start.x = end.x = center.x + depth;
center.y = (start.y + end.y)/2;
}
}
...
bentline k;
label klbl(text="k") = k.upper.center - (0.1, 0);
...
constraints {
...
k.start = plus.sw; k.end = times.nw;
...
}
So I had defined a thing called a bentline, which is a line
with a slight angle in it. Or more precisely, it's two
approximately-vertical lines joined end-to-end. It has three
important reference points: start, which is the top point,
end, the bottom point, which is directly under the top
point, and center, halfway in between, but displaced
leftward by depth. I now needed to replace this with a curved line. This meant removing all the references to start, end, upper and so forth, since curves don't have any of those things. A significant rewrite, in other words. But then I had a happy thought. I added the following definition to the file:
require "curve";
define bentline_curved extends bentline {
curve c(N=3);
constraints {
c.control[0] = start;
c.control[1] = center;
c.control[2] = end;
}
draw { c; }
}
A bentline_curved is now the same as a bentline, but
with an extra curved line, called c, which has three control
points, defined to be identical with start, center,
and end. These three points inherit all the same constraints
as before, and so are constrained in the same way and positioned in
the same way. But instead of drawing the two lines, the
bentline_curved draws only the curve. I then replaced:
bentline k;
with:
bentline_curved k;
and recompiled the diagram. The result is below:This diagram is identical, except that arc k has changed from a bent line to a curve. Compare:
I didn't foresee this when I designed the linogram language. Sometimes when you try a new kind of program for the first time, you keep getting unpleasant surprises. You find things you realize you didn't think through, or that have unexpected consequences, or features that turn out not to be as powerful as you need, or that mesh badly with other features. Then you have to go back and revisit your design, fix problems, try to patch up mismatches, and so forth. In contrast, the appearance of the sort of pleasant surprise like the one in this article is exactly the opposite sort of situation, and makes me really happy.
[Other articles in category /linogram] permanent link
Linogram development: 20070120 Update
The regular polygons are working pretty well, and the curves are working pretty well. Here are some simple examples:
One interesting design problem turned up that I had not foreseen. I had planned for the curve object to be specified by 2 or more control points. (The control points are marked by little circles in the demo pictures above.) The first and last controlpoints would be endpoints, and the curve would start at point 0, then head toward point 1, veer off toward point 2, then veer off toward point 3, etc., until it finally ended at point N. You can see this in the pictures. This is like the behavior of pic, which has good-looking curves. You don't want to require that the curve pass through all the control points, because that does not give it enough freedom to be curvy. And this behavior is easy to get just by using a degree-N Bézier curve, which was what I planned to do. However, PostScript surprised me. I had thought that it had degree-N Bézier curves, but it does not. It has only degree-3 ("cubic") Bézier curves. So then I was left with the puzzle of how to use PostScript's Bézier curves to get what I wanted. Or should I just change the definition of curve in linogram to be more like what PostScript wanted? Well, I didn't want to do that, because linogram is supposed to be generic, not a front-end to PostScript. Or, at least, not a front-end only to PostScript. I did figure out a compromise. The curves generated by the PostScript drawer are made of PostScript's piecewise-cubic curves, but, as you can see from the demo pictures, they still have the behavior I want. The four control points in the small demos above actually turn into two PostScript cubic Bézier curves, with a total of seven control points. If you give linogram the points A, B, C, and D, the PostScript engine draws two cubic Bézier curves, with control points {A, B, B, (B + C)/2} and {(B + C)/2, C, C, D}, respectively. Maybe I'll write a blog article about why I chose to do it this way. One drawback of this approach is that the curves turn rather sharply near the control points. I may tinker with the formula later to smooth out the curves a bit, but I think for now this part is good enough for beta testing.
[Other articles in category /linogram] permanent link |
||||||||||||||||||||||||||||||||||||||