hello everyone,

My M.Sc. project is to develop a handwritten character recognizer for
my language 'Sinhala.' As the first step I need to develop a
application to capture online handwritten character data. For this
purpose, I examined the "Pocket PC Signature Application
Sample" [http://msdn2.microsoft.com/en-us/library/aa446559.aspx] and
tried to modify it.

Exactly, at this moment my requirement is to collect stylus
coordinates(x,y) every 10 milliseconds when a stroke is drawn in the
pocket pc touch screen (in a specific area). i.e. All I need is a
series of [X,Y, Time] information for each stroke.

e.g.
STROKE #1
X Y Time
12,12,1
12,13,2
14,13,3
.
.

To achieve this I've modified the SingatureControl class in the above
example, but it did not work as I expected. (Every time I redraw a
stroke, it draws two other funny strokes!) Can you please guide me how
to correct this problem, or please advice me how to achieve this task?

Following is the code, that I've modified. But it does not give the
expected output. As the clock-triggering event and the moveMove events
are separated, I've no idea how to get the coordinates of mouse
pointer when timer triggers at 10milliseconds interval.

Thank you in advance,
Regards,
Asanka



/*
SignatureControl class
--
Collects and displays a signature. The signature is made up of
a list of line segments. Each segment contains an array of points
(x and y coordinates).

Draws to a memory bitmap to prevent flickering.

Raises the SignatureUpdate event when a new segment is added to
the signature.
*/

using System;
using System.Windows.Forms;
using System.Drawing;
using System.Collections;
using Common;


namespace PocketSignature
{
/// <summary>
/// Custom control that collects and displays a signature.
/// </summary>
public class SignatureControl : Control
{

// Timer
Timer clock= new Timer();
int time = 0;
int tx, ty = 0; // holds the mouse pointer position

// gdi objects
Bitmap _bmp;
Graphics _graphics;
Pen _pen = new Pen(Color.Black);

// list of line segments(strokes)
ArrayList _lines = new ArrayList();
ArrayList timeseg = new ArrayList(); //time
information for each stroke.

// the current line segment (stroke)
ArrayList _points = new ArrayList();
ArrayList _times = new ArrayList(); //time
information of current stroke
Point _lastPoint = new Point(0,0);

// if drawing signature or not
bool _collectPoints = false;

// notify parent that line segment was updated
public event EventHandler SignatureUpdate;


/// <summary>
/// List of signature line segments.
/// </summary>
public ArrayList Lines
{
get { return _lines; }
}

/// <summary>
/// List of signature line time segments.
/// </summary>
public ArrayList Times
{
get { return timeseg; }
}

/// <summary>
/// Return the signature flattened to a stream of bytes.
/// </summary>
public byte[] SignatureBits
{
get { return SignatureData.GetBytes(this.Width, this.Height,
_lines); }
}

public SignatureControl()
{

clock = new Timer();
clock.Interval = 1;
clock.Tick += new EventHandler(clock_Tick) ;
}

protected override void OnPaint(PaintEventArgs e)
{
// blit the memory bitmap to the screen
// we draw on the memory bitmap on mousemove so there
// is nothing else to draw at this time (the memory
// bitmap already contains all of the lines)
CreateGdiObjects();
e.Graphics.DrawImage(_bmp, 0, 0);
}

protected override void OnPaintBackground(PaintEventArgs e)
{
// don't pass to base since we paint everything, avoid flashing
}

protected override void OnMouseDown(MouseEventArgs e)
{

base.OnMouseDown(e);
time = 0; //
reset time count

// process if currently drawing signature
if (!_collectPoints)
{
// start collecting points

// use current mouse click as the first point
_lastPoint.X = e.X;
_lastPoint.Y = e.Y;

// this is the first point in the list
_points.Clear();
_times.Clear();
_points.Add(_lastPoint);
_times.Add(time);
_collectPoints = true;
clock.Enabled = true; //start
clock
}
}

private void clock_Tick(object sender, System.EventArgs e)
{

time++;
int x, y = 0;

if (_collectPoints)
{
// add point to current line segment
x=tx; //MousePosition.X;
y=ty; //MousePosition.Y;
_points.Add(new Point(x, y));
_times.Add(time);

// draw the new segment on the memory bitmap
_graphics.DrawLine(_pen, _lastPoint.X, _lastPoint.Y, x, y);

// update the current position
_lastPoint.X = x;
_lastPoint.Y = y;

// display the updated bitmap
Invalidate();
}


}

protected override void OnMouseUp(MouseEventArgs e)
{

base.OnMouseUp(e);

// process if drawing signature
if (_collectPoints)
{
// stop collecting points
_collectPoints = false;
clock.Enabled = false;
time = 0;

// add current line to list of segments
Point[] points = new Point[_points.Count];
int[] timesg = new int[_points.Count];

for (int i=0; i < _points.Count; i++)
{
Point pt = (Point)_points[i];
int t = (int) _times[i];

points[i].X = pt.X;
points[i].Y = pt.Y;
timesg[i] = t;

}

_lines.Add(points);
timeseg.Add(timesg);
// start over with a new line
_points.Clear();
_times.Clear();

// notify container a new segment was added
RaiseSignatureUpdateEvent();
}
}

protected override void OnMouseMove(MouseEventArgs e)
{
base.OnMouseMove(e);
if (_collectPoints)
{
tx = e.X;
ty = e.Y;
}


}

/// <summary>
/// Clear the signature.
/// </summary>
public void Clear()
{
_lines.Clear();
timeseg.Clear();
InitMemoryBitmap();
Invalidate();
}

/// <summary>
/// Create any GDI objects required to draw signature.
/// </summary>
private void CreateGdiObjects()
{
// only create if don't have one or the size changed
if (_bmp == null || _bmp.Width != this.Width || _bmp.Height !=
this.Height)
{
// memory bitmap to draw on
InitMemoryBitmap();
}
}

/// <summary>
/// Create a memory bitmap that is used to draw the signature.
/// </summary>
private void InitMemoryBitmap()
{
// load the background image
_bmp = Global.LoadImage("sign here.png");

// get graphics object now to make drawing during mousemove faster
_graphics = Graphics.FromImage(_bmp);
}

/// <summary>
/// Notify container that a line segment has been added.
/// </summary>
private void RaiseSignatureUpdateEvent()
{
if (this.SignatureUpdate != null)
SignatureUpdate(this, EventArgs.Empty);
}
}
}

Re: Stylus coordinates on a given time interval by ctacke/>

ctacke/>
Sat May 12 08:00:44 CDT 2007

Not sure, but I believe the point of the exercise is for you to learn. Part
of learning is debugging. Posting the entire control here and asking what's
wrong does not count as debugging.


--

Chris Tacke, Embedded MVP
OpenNETCF Consulting
Managed Code in an Embedded World
www.OpenNETCF.com



"Asanka" <wasala@gmail.com> wrote in message
news:1178964936.351649.279150@o5g2000hsb.googlegroups.com...
> hello everyone,
>
> My M.Sc. project is to develop a handwritten character recognizer for
> my language 'Sinhala.' As the first step I need to develop a
> application to capture online handwritten character data. For this
> purpose, I examined the "Pocket PC Signature Application
> Sample" [http://msdn2.microsoft.com/en-us/library/aa446559.aspx] and
> tried to modify it.
>
> Exactly, at this moment my requirement is to collect stylus
> coordinates(x,y) every 10 milliseconds when a stroke is drawn in the
> pocket pc touch screen (in a specific area). i.e. All I need is a
> series of [X,Y, Time] information for each stroke.
>
> e.g.
> STROKE #1
> X Y Time
> 12,12,1
> 12,13,2
> 14,13,3
> .
> .
>
> To achieve this I've modified the SingatureControl class in the above
> example, but it did not work as I expected. (Every time I redraw a
> stroke, it draws two other funny strokes!) Can you please guide me how
> to correct this problem, or please advice me how to achieve this task?
>
> Following is the code, that I've modified. But it does not give the
> expected output. As the clock-triggering event and the moveMove events
> are separated, I've no idea how to get the coordinates of mouse
> pointer when timer triggers at 10milliseconds interval.
>
> Thank you in advance,
> Regards,
> Asanka
>
>
>
> /*
> SignatureControl class
> --
> Collects and displays a signature. The signature is made up of
> a list of line segments. Each segment contains an array of points
> (x and y coordinates).
>
> Draws to a memory bitmap to prevent flickering.
>
> Raises the SignatureUpdate event when a new segment is added to
> the signature.
> */
>
> using System;
> using System.Windows.Forms;
> using System.Drawing;
> using System.Collections;
> using Common;
>
>
> namespace PocketSignature
> {
> /// <summary>
> /// Custom control that collects and displays a signature.
> /// </summary>
> public class SignatureControl : Control
> {
>
> // Timer
> Timer clock= new Timer();
> int time = 0;
> int tx, ty = 0; // holds the mouse pointer position
>
> // gdi objects
> Bitmap _bmp;
> Graphics _graphics;
> Pen _pen = new Pen(Color.Black);
>
> // list of line segments(strokes)
> ArrayList _lines = new ArrayList();
> ArrayList timeseg = new ArrayList(); //time
> information for each stroke.
>
> // the current line segment (stroke)
> ArrayList _points = new ArrayList();
> ArrayList _times = new ArrayList(); //time
> information of current stroke
> Point _lastPoint = new Point(0,0);
>
> // if drawing signature or not
> bool _collectPoints = false;
>
> // notify parent that line segment was updated
> public event EventHandler SignatureUpdate;
>
>
> /// <summary>
> /// List of signature line segments.
> /// </summary>
> public ArrayList Lines
> {
> get { return _lines; }
> }
>
> /// <summary>
> /// List of signature line time segments.
> /// </summary>
> public ArrayList Times
> {
> get { return timeseg; }
> }
>
> /// <summary>
> /// Return the signature flattened to a stream of bytes.
> /// </summary>
> public byte[] SignatureBits
> {
> get { return SignatureData.GetBytes(this.Width, this.Height,
> _lines); }
> }
>
> public SignatureControl()
> {
>
> clock = new Timer();
> clock.Interval = 1;
> clock.Tick += new EventHandler(clock_Tick) ;
> }
>
> protected override void OnPaint(PaintEventArgs e)
> {
> // blit the memory bitmap to the screen
> // we draw on the memory bitmap on mousemove so there
> // is nothing else to draw at this time (the memory
> // bitmap already contains all of the lines)
> CreateGdiObjects();
> e.Graphics.DrawImage(_bmp, 0, 0);
> }
>
> protected override void OnPaintBackground(PaintEventArgs e)
> {
> // don't pass to base since we paint everything, avoid flashing
> }
>
> protected override void OnMouseDown(MouseEventArgs e)
> {
>
> base.OnMouseDown(e);
> time = 0; //
> reset time count
>
> // process if currently drawing signature
> if (!_collectPoints)
> {
> // start collecting points
>
> // use current mouse click as the first point
> _lastPoint.X = e.X;
> _lastPoint.Y = e.Y;
>
> // this is the first point in the list
> _points.Clear();
> _times.Clear();
> _points.Add(_lastPoint);
> _times.Add(time);
> _collectPoints = true;
> clock.Enabled = true; //start
> clock
> }
> }
>
> private void clock_Tick(object sender, System.EventArgs e)
> {
>
> time++;
> int x, y = 0;
>
> if (_collectPoints)
> {
> // add point to current line segment
> x=tx; //MousePosition.X;
> y=ty; //MousePosition.Y;
> _points.Add(new Point(x, y));
> _times.Add(time);
>
> // draw the new segment on the memory bitmap
> _graphics.DrawLine(_pen, _lastPoint.X, _lastPoint.Y, x, y);
>
> // update the current position
> _lastPoint.X = x;
> _lastPoint.Y = y;
>
> // display the updated bitmap
> Invalidate();
> }
>
>
> }
>
> protected override void OnMouseUp(MouseEventArgs e)
> {
>
> base.OnMouseUp(e);
>
> // process if drawing signature
> if (_collectPoints)
> {
> // stop collecting points
> _collectPoints = false;
> clock.Enabled = false;
> time = 0;
>
> // add current line to list of segments
> Point[] points = new Point[_points.Count];
> int[] timesg = new int[_points.Count];
>
> for (int i=0; i < _points.Count; i++)
> {
> Point pt = (Point)_points[i];
> int t = (int) _times[i];
>
> points[i].X = pt.X;
> points[i].Y = pt.Y;
> timesg[i] = t;
>
> }
>
> _lines.Add(points);
> timeseg.Add(timesg);
> // start over with a new line
> _points.Clear();
> _times.Clear();
>
> // notify container a new segment was added
> RaiseSignatureUpdateEvent();
> }
> }
>
> protected override void OnMouseMove(MouseEventArgs e)
> {
> base.OnMouseMove(e);
> if (_collectPoints)
> {
> tx = e.X;
> ty = e.Y;
> }
>
>
> }
>
> /// <summary>
> /// Clear the signature.
> /// </summary>
> public void Clear()
> {
> _lines.Clear();
> timeseg.Clear();
> InitMemoryBitmap();
> Invalidate();
> }
>
> /// <summary>
> /// Create any GDI objects required to draw signature.
> /// </summary>
> private void CreateGdiObjects()
> {
> // only create if don't have one or the size changed
> if (_bmp == null || _bmp.Width != this.Width || _bmp.Height !=
> this.Height)
> {
> // memory bitmap to draw on
> InitMemoryBitmap();
> }
> }
>
> /// <summary>
> /// Create a memory bitmap that is used to draw the signature.
> /// </summary>
> private void InitMemoryBitmap()
> {
> // load the background image
> _bmp = Global.LoadImage("sign here.png");
>
> // get graphics object now to make drawing during mousemove faster
> _graphics = Graphics.FromImage(_bmp);
> }
>
> /// <summary>
> /// Notify container that a line segment has been added.
> /// </summary>
> private void RaiseSignatureUpdateEvent()
> {
> if (this.SignatureUpdate != null)
> SignatureUpdate(this, EventArgs.Empty);
> }
> }
> }
>



Re: Stylus coordinates on a given time interval by kdarling

kdarling
Sat May 12 19:27:31 CDT 2007

On May 12, 6:15 am, Asanka <was...@gmail.com> wrote:
> hello everyone,
>
> My M.Sc. project is to develop a handwritten character recognizer for
> my language 'Sinhala.' [...]
> Exactly, at this moment my requirement is to collect stylus
> coordinates(x,y) every 10 milliseconds when a stroke is drawn in the

If nothing else, this seems like a very hard way of writing a
character recognizer. Too much data collected, and perhaps too time-
dependent. See instead:

http://www.usenix.org/events/usenix03/tech/freenix03/full_papers/worth/worth_html/xstroke.html

In any case, debugging is your friend ;-)
Kev



Re: Stylus coordinates on a given time interval by Asanka

Asanka
Sun May 13 23:09:22 CDT 2007

On May 13, 6:27 am, kdarl...@basit.com wrote:
> On May 12, 6:15 am, Asanka <was...@gmail.com> wrote:
>
> > hello everyone,
>
>
> If nothing else, this seems like a very hard way of writing a
> character recognizer. Too much data collected, and perhaps too time-
> dependent. See instead:
>
> http://www.usenix.org/events/usenix03/tech/freenix03/full_papers/wort...
>
> In any case, debugging is your friend ;-)
> Kev

Thank you very much for your comments ! I'll have a look at it. I
think I have to move on to unmanaged code, otherwise i would stuck
when developing the SIP input method.

regards,
Asanka