// A "pen-based typing" alphabet recognizer - Ken Perlin public class AlphaDraw { public AlphaDraw() { init(); } void init() { reco = new Recognizer[4]; for (int i = 0 ; i < 4 ; i++) reco[i] = new Recognizer(); for (int dir = 0 ; dir < 6 ; dir++) { double theta = Math.PI * (5 - dir) / 3; double cos = 10 * Math.cos(theta), sin = 10 * Math.sin(theta); for (int j = 0 ; j < pattern.length ; j++) { double p[] = pattern[j]; if (p.length > 0) { int n = 2, xy[] = {0,0, 0,0, 0,0, 0,0, 0,0}; for (int m = 0 ; m < p.length ; m += 2) { xy[n++] = (int)( cos * p[m] + sin * p[m+1]); xy[n++] = (int)(-sin * p[m] + cos * p[m+1]); } add(xy, n, dir, j); } } } } void add(int xy[], int n, int dir, int j) { int ch = map(dir, j); reco[sortByLength[j]].add(xy, n, "" + (char)ch); } boolean isNonums = false; public void toggleHasNumbers() { isNonums = ! isNonums; init(); } public int shift(int c) { int m; if (c >= 'a' && c <= 'z') c += 'A' - 'a'; else for (int k = 0 ; k < _abc.length ; k++) if ( (m = _abc[k].indexOf(c)) >= 0) return _ABC[k].charAt(m); return c; } public double[] getPattern(Object obj) { return getPattern(obj, 1); } public double[] getPattern(Object obj, int j) { return reco[j].getPattern(obj); } public int recognize(int xy[], int n, int j, boolean shifted) { int c = ((String)reco[j].recognize(xy, n)).charAt(0), m; if (shifted) c = shift(c); String s = "" + (char)c; if (s == null) return 0; return (int)s.charAt(0); } public void toggleNumeric() { isNumeric = ! isNumeric; } private boolean isNumeric = false; public int map(int i, int j) { return remap((int)_abc[i].charAt(j)); } public static final int ALT = 2001; public static final int CNTRL = 2002; public static final int DELWD = 2003; public static final int END = 2004; public static final int SEND = 2005; public static final int SHIFT = 2006; private int remap(int c) { switch (c) { case 'A': c = ALT ; break; // ALT KEY case 'B': c = '\b' ; break; // BACKSPACE case 'C': c = SHIFT; break; // SHIFT KEY case 'D': c = 1005 ; break; // UP ARROW case 'E': c = 27 ; break; // ESC case 'F': c = ' ' ; break; // SPACE case 'I': c = END ; break; // END case 'K': c = CNTRL; break; // CONTROL KEY case 'L': c = 1006 ; break; // LEFT ARROW case 'N': c = '\n' ; break; // NEW LINE case 'O': c = SEND ; break; // SEND case 'R': c = 1007 ; break; // RIGHT ARROW case 'S': c = '\\' ; break; // BACKSLASH case 'T': c = '\t' ; break; // TAB case 'U': c = 1004 ; break; // DOWN ARROW case 'W': c = DELWD; break; // DELETE WORD } return c; } private Recognizer reco[]; // !"#$%&'()*+,-./0123456789:;<=>? // @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ // `abcdefghijklmnopqrstuvwxyz{|}~ String _abc[] = { "?4yab d5*", "`6cefjh7!", "'8gilkn9=", ".0mopqsA-", "%KrtuNw1,", "&2vBxCz3;", }; String _ABC[] = { "?>--- -[-", "^]-----{|", "\"}-----(+", ".)-----A_", "#K---N-\\,", "$/-B--C<:", }; double Y = .5 * Math.sqrt(3); double pattern[][] = { {-0.25, .5*Y, -1.0, 0.0, }, // [ 1 {-1.00, .5*Y, -1.0, 0.0, }, // 2 1 {-1.00, .5*Y, -2.0, 0.0, }, // v 3 {-1.00, 0, }, // B 1 {-1.00,-.5*Y, -2.0, 0.0, }, // x 3 {-1.50,- Y, 0.0, 0.0, }, // z 0 {-1.50,- Y, }, // W 2 {-1.00,-.5*Y, -1.0, 0.0, }, // 3 1 {-0.25,-.5*Y, -1.0, 0.0, }, // ( 1 }; int sortByLength[] = {1, 1, 3, 1, 3, 0, 2, 1, 1}; }