State of DRAWSEGMENTs (newdrawing command) and coordinate transformations (and a little about fonts)
geoms can be a list of strings and datatypes that specify geometries. As part of the development of newdrawing, it became apparent that a method to transform coordinates for subsequent geoms would be a useful construct. You could have a text file with geoms and read it in, and have it transformed anywhere and in any rotation/scale you want.
During the development of font handling, It became clear this is the good framework for handling the placement of character glyphs. An initial transform is retained that indicates the origin (and any other affine transformation)* of the current character. After the character glyph is rendered, the transformation is translated one step: the width of the just-rendered character. On a newline character (0x0D or 13 decimal), the transformation is moved “down” one line, based on the current transformation matrix. In this way, the character advance direction and “down” can be defined as any direction (e.g. as specified by the current transformation matrix), and characters can thus be rendered at any position, rotation, and scale and maintain their character spacing and line characteristics.
Thinking about this further, it would be difficult to separate changes to the character transformation matrix (moving to an absolute position on the board or moving to the next character position) and also within the character itself (to draw the character). In this scenario, “characters” could just as easily be other geoms. Further these could be nested arbitrarily deep, each with their own transformation requirements to maintain the relationship to other geoms at that level.
What this means to me is that we need a method to retain multiple transformations, go to a new one, then return to the old one. I would call this a “stack,” or more precisely, a “transformation matrix stack”. So if a self-contained geom needs to modify or specify a transformation, it can do so while affecting only subsequent geoms in its nesting level, but not those outside.
Let’s call these new geom specifiers as “TransformNew” and “TransformOld” where TransformNew pushes a new transformation on the stack, and TransformOld pops and discards the then-current transformation.
The entire flow would be something like:
-
TransformNew [Other transform commands such as Translate, Scale, or Rotate] [geoms to be transformed] TransformOld
It looks to me like the units specification, which had been a precursor to the transformation commands, should instead only be relevant to transform commands themselves. To make a scale applicable to the current level of transformation commands, you would use the Scale command, perhaps with a units command within it. Something like:
-
TransformNew,Scale,mm,1,1,Line,1,1,2,2,TransformOld - this would create a line from 1mm,1mm to 2mm,2mm. Which would slope from upper left to lower right.
It seems most appropriate that the default scale should be in native units and carry the same x/y direction of KiCAD. That is, positive x and positive y are right and down. Note this may be different than many graphics coordinate systems which might expect that to be right and up. To plot a graphic using coordinates in millimeters x/y positive in the right/up direction, you would specify
-
TransformNew,Scale,mm,1,-1,Line,1,1,2,2,TransformOld - this would create a line from 1mm,1mm to 2mm,2mm. Which would slope from bottom left to upper right.
Finally, it might be useful to reset the scale back to normal and clear the stack, maybe with a command TransformReset or maybe TReset
The current transformation commands are Scale, Translate, Rotate, and Shear. Could there be a shorthand for these? Ts, Tt, Tr, Tz? Or even just S, T, R, Z? They could be extended to Sx, Sy, Tx, Ty, Zx, and Zy if you only want to specify x or y transform. To make this simpler, “T” looks like a sort of transform and could be a shorthand for each of these commands: T+, T-, and T0 (zero).
I’m still thinking about how to integrate geoms and the font capability as well as the best way to indicate transformations of geoms. I think this is a good start on that discussion.
* I like Wolfrom Mathworld’s description of Affine Transformation
Geometric contraction, expansion, dilation, reflection, rotation, shear, similarity transformations, spiral similarities, and translation are all affine transformations, as are their combinations. In general, an affine transformation is a composition of rotations, translations, dilations, and shears.