Beispiel #1
0
        public List<double> Vector;        // vector representation -- for Protractor

        /// <summary>
        /// Constructor of a unistroke gesture. A unistroke is comprised of a set of points drawn
        /// out over time in a sequence.
        /// </summary>
        /// <param name="name">The name of the unistroke gesture.</param>
        /// <param name="timepoints">The array of points supplied for this unistroke.</param>
        public Unistroke(string name, List<TimePointF> timepoints)
        {
            this.Name = name;
            this.RawPoints = new List<TimePointF>(timepoints); // copy (saved for drawing)
            double I = GeotrigEx.PathLength(timepoints) / (Recognizer.NumPoints - 1); // interval distance between points
            this.Points = TimePointF.ConvertList(SeriesEx.ResampleInSpace(timepoints, I));
            double radians = GeotrigEx.Angle(GeotrigEx.Centroid(this.Points), this.Points[0], false);
            this.Points = GeotrigEx.RotatePoints(this.Points, -radians);
            this.Points = GeotrigEx.ScaleTo(this.Points, Recognizer.SquareSize);
            this.Points = GeotrigEx.TranslateTo(this.Points, Recognizer.Origin, true);
            this.Vector = Vectorize(this.Points); // vectorize resampled points (for Protractor)
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="timepoints"></param>
        /// <param name="protractor">false</param>
        /// <returns></returns>
        public NBestList Recognize(List <TimePointF> timepoints, bool protractor)       // candidate points
        {
            double        I       = GeotrigEx.PathLength(timepoints) / (NumPoints - 1); // interval distance between points
            List <PointF> points  = TimePointF.ConvertList(SeriesEx.ResampleInSpace(timepoints, I));
            double        radians = GeotrigEx.Angle(GeotrigEx.Centroid(points), points[0], false);

            points = GeotrigEx.RotatePoints(points, -radians);
            points = GeotrigEx.ScaleTo(points, SquareSize);
            points = GeotrigEx.TranslateTo(points, Origin, true);
            List <double> vector = Unistroke.Vectorize(points); // candidate's vector representation

            NBestList nbest = new NBestList();

            foreach (Unistroke u in _gestures.Values)
            {
                if (protractor) // Protractor extension by Yang Li (CHI 2010)
                {
                    double[] best  = OptimalCosineDistance(u.Vector, vector);
                    double   score = 1.0 / best[0];
                    nbest.AddResult(u.Name, score, best[0], best[1]); // name, score, distance, angle
                }
                else // original $1 angular invariance search -- Golden Section Search (GSS)
                {
                    double[] best = GoldenSectionSearch(
                        points,                                 // to rotate
                        u.Points,                               // to match
                        GeotrigEx.Degrees2Radians(-45.0),       // lbound
                        GeotrigEx.Degrees2Radians(+45.0),       // ubound
                        GeotrigEx.Degrees2Radians(2.0)          // threshold
                        );

                    double score = 1.0 - best[0] / HalfDiagonal;
                    nbest.AddResult(u.Name, score, best[0], best[1]); // name, score, distance, angle
                }
            }
            nbest.SortDescending(); // sort descending by score so that nbest[0] is best result
            return(nbest);
        }