An intuitive way to define and draw a simple glyph that scales.
Background
Sometimes, you need to draw a simple glyph such as a tick or a resize handle. Here's a neat trick you can use to avoid wildly searching for the correct transparent icon of a correct size and style, or the right Awesome Font glyph.
At the heart of this trick is a counter- intuitive idea that thinking in fractions (i.e., percentage) is easier than thinking in absolute units. For example - if you want to draw a letter 'X
' and your "vector
" coordinate system allows only values between 0 and 1, then you can define it by drawing two lines:
- a (diagonal) line from (0.25, 0.25) to (0.75, 0.75), and
- a line from (0.75, 0.25) to (0.25, 0.75).
The Code
Let us define two glyphs - letter 'X
', and a tick in C#.
PointF[][] X = new PointF[][] {
new PointF[] { new PointF( 0.25f, 0.25f ), new PointF( 0.75f, 0.75f ) },
new PointF[] { new PointF( 0.75f, 0.25f ), new PointF( 0.25f, 0.75f ) }
};
PointF[][] tick = new PointF[][] {
new PointF[] { new PointF( 0.3f, 0.6f ),
new PointF( 0.4f, 0.8f ), new PointF( 0.7f, 0.2f) }
};
To get absolute coordinates, we multiply these relative coordinates with absolute width and height of our destination area.
Let us assume the size of your window is 640 x 400 pixels and you want to draw a pixel at the center (0.5, 0.5). You simply multiply it by width width and height and you get 320, 200.
We draw our "vector glyph" like this:
foreach (PointF[] lines in X)
g.DrawLines(Pens.Black, lines.Select(p => new PointF(p.X*w, p.Y*h)).ToArray());
And that's the whole trick. Nothing spectacular. In WPF, you can use geometry instead.
I find it useful to quickly implement simple (flat!) glyphs, such as mail glyph, resize and maximize window glyphs, arrows glyphs, etc. You can experiment by scaling your pen thickness and/or adding simple arcs.
History
- 2nd March, 2021: Initial version