Introduction
I thought it would be kinda cool to teach the computer to auto generate glyphs that uniquely represent words, but do so procedurally like some sci-fi alien language. Kanji and other glyph/stroke based symbols evolved over time and there isn't a programmatic pattern to generate the symbols from an alphabet. Because I've always been interested in things that improve efficiency such as short hand, I figured it might be interesting to procedurally generate glyphs/Kanji like symbols from text.
Background
Well, this is what happens when I watch too much Dr. Who.
Languages are cool, so I created a sort of "procedural" generation of glyphs like "kanji" for Japanese, but it's just an alphabet translation.
Using the Code
First text is split into words, then the letters are "found" in a map, then the map locations are turned into a cursive like stroke connecting 2-3 points at a time to generate a glyph. There are a few cool tricks in the code. First I created a 2D map of the text (array of strings, each string is a row). When a character is found, it's location is the row/column in the map. This is then translated into a graphic location, and appended to the list. This list is then broken into pieces in a way to generally make 2-4 locations into a stroke, like a curved stroke of a brush. This also checks for double letters (adding additional markings) and makes sure that if there were say, 10 location it doesn't get broken into 2 strokes of 4 points and a two point in the end, but into a 4 pnt, and two 3 pnt strokes.
The code is also a decent example of double buffering and of drawing curves.
Map
The points are selected from the map:
string[] map = {
"1234567890",
"QWERTYUIOP",
"qwertyuiop",
"`~!@#$%^&**()-_=+",
"ASDFGHJKL",
"asdfghjkl",
",<.>/?;:'\"[{]}\\|",
"ZXCVBNM",
"zxcvbnm",
};
pnts.Add(new PointF(xInd, yInd));
for (int j = 0; j < words[i].Length; j++)
{
float x = 0;
float y = 0;
char c = words[i][j];
for (int k = 0; k < map.Length; k++)
{
int m = map[k].IndexOf(c);
if (m >= 0)
{
y = k * wordHeightScale;
x = m * wordWidthScale;
break;
}
}
pnts.Add(new PointF(x + xInd, y + yInd));
}
if (pnts.Count > 1)
{
renderLine(g, pnts, wordWidthScale, wordHeightScale);
}
Line Rendering
Rendering the line means breaking first into strokes, drawing a stroke then dealing with duplicate letters.
formSegments(pntsArray, segs);
using (Pen p = new Pen(Color.Black, 1.5f))
{
for (int i = 0; i < segs.Count; i++)
{
renderStroke(g, p, segs[i]);
}
... Duplicate letter code.
Segments are made:
protected void formSegments(PointF[] pnts, List<PointF[]> segs)
{
int start = 0;
while ((start < pnts.Length) && (segs.Count < 20))
{
int rem = pnts.Length - start;
if (rem > 6)
{
PointF[] p = new PointF[4];
for (int i = 0; i < 4; i++) p[i] = pnts[start + i];
start += 4;
rem -= 4;
segs.Add(p);
}
if (rem > 5)
{
PointF[] p = new PointF[3];
for (int i = 0; i < 3; i++) p[i] = pnts[start + i];
start += 3;
rem -= 3;
segs.Add(p);
}
if (rem <= 5)
{
PointF[] p = new PointF[rem];
for (int i = 0; i < rem; i++) p[i] = pnts[start + i];
start += rem;
segs.Add(p);
}
}
}
Then the lines get drawn:
protected void renderStroke(Graphics g, Pen p, PointF[] pntsArray)
{
g.DrawCurve(p, pntsArray, 0.75f);
for (int i = 0; i < 4; i++)
{
for (int j = 0; j < pntsArray.Length; j++)
{
pntsArray[j].X += i * 0.1f;
pntsArray[j].Y += i * 0.2f;
}
g.DrawCurve(p, pntsArray, 0.75f);
}
}
Use in Applications
The glyphs are interesting for decoration, or to create different UI experiences.
One way to think of this submission is as art, or another as looking at different ways a computer could communicate with another computer in a more graceful way than just binary or bar codes. Another thing that might be neat is to use phonetics, and mix in color.
In any case, it's for fun and I hope someone has fun with it.