xwidth=1024
ywidth=768
set display mode xwidth,ywidth,32
backdrop on:sync on:color backdrop rgb(0,0,0)
rem Describe mouse movements
dim movement$(3,3)
data "h","u","e","l","","r","g","d","f"
for yd=1 to 3
  for xd=1 to 3
    read movement$(xd,yd)
  next xd
next yd
angle_low#=25.0
angle_high#=65.0
rem Arrays to hold graphic shape of letter that is drawn
max_draw_points=1000
dim drawx(max_draw_points)
dim drawy(max_draw_points)
rem Characters (symbol) and the mouse movements (symcode) that construct the characters
symbols=43
dim symbol$(symbols)
dim symcode$(symbols)
for sym=1 to symbols
  read symbol$(sym),symcode$(sym)
next sym
 
drawp=1
line_size=3
char$=" "
rem Define the minimum length of a line segment to be drawn
segment#=5.0
x1=0
y1=0
start=0
quit=0
while not quit
  if (mouseclick()=3)
    if start=0
      rem Set the starting point on screen for the letter being drawn
      start=1
      x1=mousex()
      y1=mousey()
      drawx(drawp)=x1
      drawy(drawp)=y1
      inc drawp
    endif
    drawx(drawp)=mousex()
    drawy(drawp)=mousey()
    rem Calculate length of line drawn from last point
    length#=sqrt((drawx(drawp)-x1)^2+(drawy(drawp)-y1)^2)
    rem Process only when line is longer than the defined line segment
    if (length# > segment#)
      rem Calculate angle of line to determine direction of mouse movement
      if (drawx(drawp)=x1)
        angle#=90.0
      else
        angle#=atan(abs(drawy(drawp)-y1)/abs(drawx(drawp)-x1))
      endif
      if (drawx(drawp)-x1)<0
        x=1
      else
        x=3
      endif
      if (angle#<angle_low#) then y=2
      if (angle#>=angle_low#)
        if (drawy(drawp)-y1)<0
          y=1
        else
          y=3
        endif
      endif
      if (angle#>angle_high#) then x=2
      x1=drawx(drawp)
      y1=drawy(drawp)
      inc drawp
      if (drawp>max_draw_points) then dec drawp
      rem If direction of mouse movement changes, record new direction of movement
      if ( movement$(x,y) <> mid$(char$,len(char$)) ) and ( movement$(x,y) <> chr$(asc(mid$(char$,len(char$)))-32) )
        char$=char$+movement$(x,y)
        repeated=0
      else
        rem If same direction continues, record movement as a longer line
        inc repeated
        if (repeated > line_size)
          char$=char$+movement$(x,y)
          repeated=0
        endif
      endif
    endif
  else
    rem Mouse buttons released, match the drawn pattern to a character
    if start=1
      for sym=1 to symbols
        if match_code(symcode$(sym),char$)
          if (symbol$(sym) = "bp" )
            rem Process a backspace
            if (len(recognize$)>0)
              if (len(recognize$)=1)
                recognize$=""
              else
                recognize$=left$(recognize$,len(recognize$)-1)
              endif
            endif
          else
            rem Add recognized character to the string
            recognize$=recognize$+symbol$(sym)
          endif
          sym=symbols+1
        endif
      next sym
    endif
    rem Reset drawn shape for next character
    char$=""
    drawp=1
    start=0
  endif
  gosub draw_screen
  if escapekey() then quit=1
endwhile
end
 
draw_screen:
  ink rgb(128,128,128),0
  box int(xwidth/2)-int(line_size*20),int(ywidth/2)-int(line_size*20),int(xwidth/2)+int(line_size*20),int(ywidth/2)+int(line_size*20)
  ink rgb(255,255,255),0
  for c=2 to drawp-1
    line drawx(c-1),drawy(c-1),drawx(c),drawy(c)
  next c
  ink rgb(64,64,64),0
  box 40,40,xwidth-100,90
  ink rgb(255,255,255),0
  set cursor 50,50
  set text size 40
  print recognize$;"_"
  set cursor 1,ywidth-175
  set text size 20
  print "Hold down both mouse buttons to draw a letter."
  print "Draw captial letters only."
  print "Release mouse buttons when finished with letter."
  ink rgb(128,255,128),0
  print "Box is for reference only. You can draw anywhere on the screen."
  print "For best results: try and draw the letter the same size as the box."
  print
  ink rgb(255,128,128),0
  print "[BACKSPACE] - draw right to left. [SPACE] - draw left to right."
  set cursor 1,20
  print "Mouse Gesture - Character Recognition - by acelepage"
  sync
return
 
function match_code(symcode$,char$)
  found=1
  match_position=0
  misses=0
  for symchar=1 to len(symcode$)
    inc match_position
    match$=mid$(symcode$,symchar)
    while (mid$(char$,match_position) <> match$) and (match_position <= len(char$))
      inc match_position
      inc misses
    endwhile
    if match_position>len(char$)
      found=0
    endif
  next symchar
  if (misses>(len(symcode$)*2)) then found=0
endfunction found
 
data "B","urdlrdl"
data "E","ldrldr"
data "F","urldr"
data "Q","ruldr"
data "Q","ruldf"
data "O","rdlu"
data "O","lddruu"
data "O","ddruul"
data "G","lddrul"
data "S","ldrdl"
data "S","ldfdl"
data "R","urdlf"
data "Z","rgr"
data "T","rld"
data "A","udul"
data "D","uurddl"
data "P","uurdl"
data "H","durdu"
data "H","durud"
data "F","ldur"
data "K","degf"
data "M","ufed"
data "M","efef"
data "M","udud"
data "W","defu"
data "W","fefe"
data "W","dudu"
data "N","uufuu"
data "Y","fed"
data "X","fug"
data "X","fle"
data "C","ldr"
data "J","dlh"
data "U","dru"
data "V","fe"
data "V","fu"
data "V","du"
data "V","de"
data "L","dr"
data "I","d"
data " ","r"
data "bp","l"