locked
Velocity profile for ink stroke RRS feed

  • Question

  • Hello all!  I'm fairly new to Tablet PC app development, so sorry for my rather (but hopefully) simple question. 

    I used the ink recorder sample from the Tablet PC SDK and recorded a random scribble (2 strokes).  I was wondering if there is a way to find the velocity profile of this scribble.  Otherwise, is there a way to record strokes in digital ink (sort of like an e-signature capture) and retrieve its velocity profile?  Note: I'm using the SDK on a regular Windows XP machine, not a Tablet PC, so pressure profile isn't needed since I'm only using a mouse.

    Thanks in advance!
    - impish
    Wednesday, January 31, 2007 5:43 PM

Answers

  • Hi impish,

    the points in a stroke are collected with a constant sampling rate for a given input device (note that the mouse rate is a lot lower than the stylus rate, though). So you just need to calculate the spatial distance between two points. Then you can calculate the velocity by dividing it by the constant temporal distance between points.

    I have included a simple app below that demonstrates this approach. In the stroke event handler the code calculates the constant time interval between points. Then it walk all points, calculates the distance between the previous point and calculates the velocity at that point. 

    Thanks, Stefan Wick

     

    using System;
    using System.Drawing;
    using System.Windows.Forms;
    using Microsoft.Ink;

    namespace StrokeVelocityProfile
    {
        class Program : Form
        {
            public Program()
            {
                inkOverlay = new InkOverlay(this);
                inkOverlay.Enabled = true;
                inkOverlay.Stroke += new InkCollectorStrokeEventHandler(inkOverlay_Stroke);
                inkOverlay.CursorDown += new InkCollectorCursorDownEventHandler(inkOverlay_CursorDown);
            }

            void inkOverlay_CursorDown(object sender, InkCollectorCursorDownEventArgs e)
            {
                cursorDownTime = Environment.TickCount;
            }

            void inkOverlay_Stroke(object sender, InkCollectorStrokeEventArgs e)
            {
                int strokeDuration = Environment.TickCount - cursorDownTime;
                double packetDuration = (double)strokeDuration / (double)e.Stroke.PacketCount;
                Point []strokePoints = e.Stroke.GetPoints();

                for (int i = 1; i < strokePoints.Length; i++)
                {
                    double deltaX = (double)(strokePointsIdea.X - strokePoints[i-1].X);
                    double deltaY = (double)(strokePointsIdea.Y - strokePoints[i-1].Y);
                    double distance = Math.Sqrt(deltaX*deltaX + deltaY*deltaY);
                    double velocity = distance / packetDuration;
                    Console.WriteLine("Velocity at point " + i.ToString() + ": " + velocity.ToString());
                }
            }

            [STAThread]
            static void Main(string[] args)
            {
                Application.Run(new Program());
            }

            private InkOverlay inkOverlay;
            private int cursorDownTime;
        }
    }

    Wednesday, January 31, 2007 6:53 PM