Category : Files from Magazines
Archive   : DDJ0492.ZIP
Filename : HANDPRIN.ASC

 
Output of file : HANDPRIN.ASC contained in archive : DDJ0492.ZIP
_YOUR OWN HANDPRINTING RECOGNITION ENGINE_
by Ron Avitzur


[LISTING ONE]

/*****************************************************************
A Writer-Dependent Hand-printing Recognizer -- by Ron Avitzur, 1991.
This is not the complete code. See the accompanying article for
a description of other necessary modules.
*****************************************************************/

typedef struct { short num_items; void *items[]; } *List;
typedef struct { short code; List strokes; } GesturePattern
typedef struct { char is_dot; List s[5]; } StrokePattern;
typedef struct {
Point Ink[MAX_POINTS],
P[MAX_N];
short Ink_Num,
N,
T[MAX_N],
IsDot;
unsigned long S[5];
double Aspect_Ratio;
long Xmax,Xmin,
Ymax,Ymin,
Height,Width,
XmaxT,XminT,
YmaxT,YminT,
HeightT,WidthT;
long start_time,end_time;
List matches;
} StrokeData,
*StrokePtr;

ProcPtr HashFunctions[] = { Fxn1,Fxn2,Fxn3,Fxn4,Fxn5 };

char Bits[] = {2,2,3,2,2};

#define DOT_THRESHHOLD (Wacom?80:4)
#define PT_SEP_POST (Wacom?40:4)

/****************************************************************/
void Analyze(register StrokePtr theStroke) {
char i,s[100];
Simplify();
for (i = 0; i < 5; i++) {
HashFunction[i](s,theStroke);

ConvertStringToLong(s,&S[i],Bits[i]);
}
theStroke->IsDot =
((theStroke->Height < DOT_THRESHHOLD
&&
theStroke->Width < DOT_THRESHHOLD)
|| N == 1);
}
/****************************************************************/
void Simplify(StrokePtr theStroke,Point *Ink,short N) {
Point Q[MAX_POINTS];
short min_dx = theStroke->Width / 8,
min_dy = theStroke->Height / 8;
if (theStroke->Aspect_Ratio < 0.2) min_dy = theStroke->Height;
if (theStroke->Aspect_Ratio > 5.0) min_dx = theStroke->Width;
theStroke->N = Process3(theStroke->P,Ink,N,min_dx,min_dy);
ComputeT(theStroke);
}
/****************************************************************/
void ComputeT(StrokePtr theStroke) {
register short *T = theStroke->T;
register Point *P = theStroke->P;
register short i,N = theStroke->N;
for (i = 0; i < N - 1; i++)
T[i] = ATAN2(P[i+1].v-P[i].v,P[i+1].h-P[i].h);
}
/****************************************************************/
short Process3(register Point *P, register Point *Q,
short num,short xd, short yd) {
register short i,n;
register short dx,dy;
n = 0;
P[0] = Q[0];
for (i = 1; i < num - 1; i++) {
dx = Q[i].h - P[n].h; dx = ABS(dx);
dy = Q[i].v - P[n].v; dy = ABS(dy);
if (dx + dy < PT_SEP_POST) continue;
if (dx < xd && dy < yd) continue;
n++;
P[n] = Q[i];
}
dx = Q[num - 1].h - P[n].h;
dy = Q[num - 1].v - P[n].v;
if (ABS(dx) + ABS(dy) > PT_SEP_POST)
n++;
P[n] = Q[num - 1];
return n + 1;
}
/****************************************************************/
/* These five lines determine what the features actually are. */
#define Feature1(t) ('0' + ((t + 10 + 45 + 180) / 90) % 4)
#define Feature2(t) ('0' + ((t + 10 + 00 + 180) / 90) % 4)

#define Feature3(t) ('0' + ((t + 10 + 22 + 180) / 45) % 8)
#define Feature4(p) ('0' + (4*((p).h - theStroke->XminT) /theStroke->WidthT))
#define Feature5(p) ('0' + (4*((p).v - theStroke->YminT) /theStroke->HeightT))

/****************************************************************/
#define FOO(name,fxn,type,array,end) \
void name(char *s,StrokePtr theStroke) \
{ \
register short i,d,n = 0; \
register type *T = theStroke->array; \
s[0] = fxn(*T++); \
i = theStroke->N - end; \
while (i-- > 0) { \
d = fxn(*T++); \
if (s[n] != d) \
s[++n] = d; \
} \
s[++n] = 0; \
}
FOO(Fxn1,Feature1,short,T,2)
FOO(Fxn2,Feature2,short,T,2)
FOO(Fxn3,Feature3,short,T,2)
FOO(Fxn4,Feature4,Point,P,1)
FOO(Fxn5,Feature5,Point,P,1)
/****************************************************************/
void ConvertStringToLong(char *s,unsigned long *np,short bits) {
unsigned long n = 0;
short i,len = strlen(s);
s[len] = s[len-1];
if (len > 32/bits) len = 32/bits;
for (i = 0; i <= len; i++)
n = (n << bits) + s[len - i] - '0';
*np = n;
}



  3 Responses to “Category : Files from Magazines
Archive   : DDJ0492.ZIP
Filename : HANDPRIN.ASC

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/