Пример #1
0
        public void ExtraProperties_AreIgnored()
        {
            Point_2D point = Serializer.Deserialize <Point_2D>(@"{ ""x"":1,""y"":2,""b"":3}");

            Assert.Equal(0, point.X);
            Assert.Equal(0, point.Y);
        }
        public async Task CaseInsensitivityWorks()
        {
            var options = new JsonSerializerOptions {
                PropertyNameCaseInsensitive = true
            };

            Point_2D point = await Serializer.DeserializeWrapper <Point_2D>(@"{""x"":1,""y"":2}", options);

            Assert.Equal(1, point.X);
            Assert.Equal(2, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{""y"":2,""x"":1}", options);

            Assert.Equal(1, point.X);
            Assert.Equal(2, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{""x"":1,""Y"":2}", options);

            Assert.Equal(1, point.X);
            Assert.Equal(2, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{""y"":2,""X"":1}", options);

            Assert.Equal(1, point.X);
            Assert.Equal(2, point.Y);
        }
Пример #3
0
        /*
         * Returns angle between two 2D vectors.
         */
        private float angle(Point_2D a, Point_2D b, bool ignore_z)
        {
            Point_2D na = normalize(a, ignore_z);
            Point_2D nb = normalize(b, ignore_z);

            return((float)Math.Acos(dot(na, nb, ignore_z)));
        }
Пример #4
0
        public void FirstParameterWins()
        {
            Point_2D point = Serializer.Deserialize <Point_2D>(@"{""X"":1,""Y"":2,""X"":4}");

            Assert.Equal(4, point.X); // Not 1.
            Assert.Equal(2, point.Y);
        }
Пример #5
0
        /*
         * Returns the mean velocity vector for the gesture in screen space.
         */
        private Point_2D mean_velocity_2D(ref List <Point_2D> gesture)
        {
            Point_2D v = new Point_2D();

            v.time = 0;
            v.x    = 0;
            v.y    = 0;
            v.z    = 0;
            for (int i = 0; i < gesture.Count - 1; i++)
            {
                float dx = gesture[i + 1].x - gesture[i].x;
                float dy = gesture[i + 1].y - gesture[i].y;
                float dz = gesture[i + 1].z - gesture[i].z;
                float dt = gesture[i + 1].time - gesture[i].time;
                v.x += dx / dt;
                v.y += dy / dt;
                v.z += dz / dt;
            }

            v.x /= (gesture.Count - 1);
            v.y /= (gesture.Count - 1);
            v.z /= (gesture.Count - 1);

            return(v);
        }
Пример #6
0
        public void Escaped_ParameterNames_Work()
        {
            Point_2D point = Serializer.Deserialize <Point_2D>(@"{""\u0058"":1,""\u0059"":2}");

            Assert.Equal(1, point.X);
            Assert.Equal(2, point.Y);
        }
        public async Task ExtraProperties_AreIgnored()
        {
            Point_2D point = await Serializer.DeserializeWrapper <Point_2D>(@"{ ""x"":1,""y"":2,""b"":3}");

            Assert.Equal(0, point.X);
            Assert.Equal(0, point.Y);
        }
        public async Task Escaped_ParameterNames_Work()
        {
            Point_2D point = await Serializer.DeserializeWrapper <Point_2D>(@"{""\u0058"":1,""\u0059"":2}");

            Assert.Equal(1, point.X);
            Assert.Equal(2, point.Y);
        }
        public async Task LastParameterWins()
        {
            Point_2D point = await Serializer.DeserializeWrapper <Point_2D>(@"{""X"":1,""Y"":2,""X"":4}");

            Assert.Equal(4, point.X); // Not 1.
            Assert.Equal(2, point.Y);
        }
Пример #10
0
 /*
  * returns the norm of a 2D vector.
  */
 private float vec2_norm(Point_2D vec, bool ignore_z)
 {
     return((float)Math.Sqrt(
                vec.x * vec.x +
                vec.y * vec.y +
                ((ignore_z) ? 0 : vec.z *vec.z)
                ));
 }
Пример #11
0
        /*
         * Returns the normalized vector of a 2D vector.
         */
        private Point_2D normalize(Point_2D vec2, bool ignore_z)
        {
            Point_2D ret;
            float    norm = vec2_norm(vec2, ignore_z);

            ret.time = vec2.time;
            ret.x    = vec2.x / norm;
            ret.y    = vec2.y / norm;
            ret.z    = vec2.z / ((ignore_z) ? 1 : norm);
            return(ret);
        }
Пример #12
0
        public void MatchJsonPropertyToConstructorParameters()
        {
            Point_2D point = Serializer.Deserialize <Point_2D>(@"{""X"":1,""Y"":2}");

            Assert.Equal(1, point.X);
            Assert.Equal(2, point.Y);

            point = Serializer.Deserialize <Point_2D>(@"{""Y"":2,""X"":1}");
            Assert.Equal(1, point.X);
            Assert.Equal(2, point.Y);
        }
Пример #13
0
        /*
         * Returns distance between two points relative to size of the gesture.
         */
        float proximity(Point_2D a, Point_2D b, Bounds bounds)
        {
            float gesture_width     = bounds.max_x - bounds.min_x;
            float gesture_height    = bounds.max_y - bounds.min_y;
            float relative_dx       = (b.x - a.x) / gesture_width;
            float relative_dy       = (b.y - a.y) / gesture_height;
            float relative_distance = (float)Math.Sqrt(relative_dx * relative_dx
                                                       + relative_dy * relative_dy);

            return(relative_distance);
        }
        public async Task MatchJsonPropertyToConstructorParameters()
        {
            Point_2D point = await Serializer.DeserializeWrapper <Point_2D>(@"{""X"":1,""Y"":2}");

            Assert.Equal(1, point.X);
            Assert.Equal(2, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{""Y"":2,""X"":1}");

            Assert.Equal(1, point.X);
            Assert.Equal(2, point.Y);
        }
Пример #15
0
        /*
         * Returns an array of angles describing the direction vectors
         * of the first n - 1 points of a gesture with n points.
         */
        private float[] vector_list_angles(ref List <Point_2D> gesture)
        {
            float[]  angles = new float[gesture.Count - 1];
            Point_2D e1     = new Point_2D(0, 1, 0, 0);

            for (int i = 0; i < angles.Length; i++)
            {
                Point_2D a  = gesture[i];
                Point_2D b  = gesture[i + 1];
                float    dx = b.x - a.x;
                float    dy = b.y - a.y;
                angles[i] = (float)((Math.Atan2(dy, dx) + 2 * Math.PI) % (2 * Math.PI));
            }
            return(angles);
        }
Пример #16
0
        public static void ComplexReferenceTypeConverter_NullOptIn()
        {
            // Per null handling opt-in, converter handles null.
            var options = new JsonSerializerOptions();

            options.Converters.Add(new PointClassConverter_NullOptIn());

            Point_2D obj = JsonSerializer.Deserialize <Point_2D>("null", options);

            Assert.Equal(-1, obj.X);
            Assert.Equal(-1, obj.Y);

            obj = null;
            JsonTestHelper.AssertJsonEqual(@"{""X"":-1,""Y"":-1}", JsonSerializer.Serialize(obj, options));
        }
Пример #17
0
        /*
         * Optional low pass filter. Averages sequences of 2d points with
         * weights calculated from Gaussian function. Basically 1D Gaussian
         * blur. Crops edges.
         */
        private List <Point_2D> gaussian_average_lowpass(
            List <Point_2D> gesture,
            int kernel_size,
            float sigma
            )
        {
            List <Point_2D> output = new List <Point_2D>();
            double          denom  = Math.Sqrt(2 * Math.PI) * sigma;

            double[] kernel     = new double[2 * kernel_size + 1];
            double   kernel_sum = 0.0f;

            // calculate kernel coefficients
            for (int i = -kernel_size; i < kernel_size + 1; i++)
            {
                int    i_adj      = i + kernel_size;
                double numer      = Math.Exp((-(i * i)) / (2 * sigma * sigma));
                double cell_value = numer / denom;
                kernel[i_adj] = cell_value;
                kernel_sum   += cell_value;
            }

            // normalize kernel
            for (int i = 0; i < 2 * kernel_size + 1; i++)
            {
                kernel[i] /= kernel_sum;
                //Console.WriteLine(kernel[i]);
            }

            // apply kernel, with crop.
            for (int i = kernel_size; i < gesture.Count - kernel_size; i++)
            {
                Point_2D point = new Point_2D();
                point.x    = 0.0f;
                point.y    = 0.0f;
                point.time = 0.0f;
                for (int j = 0; j < 2 * kernel_size + 1; j++)
                {
                    point.x    += (float)kernel[j] * gesture[i - kernel_size + j].x;
                    point.y    += (float)kernel[j] * gesture[i - kernel_size + j].y;
                    point.z    += (float)kernel[j] * gesture[i - kernel_size + j].z;
                    point.time += (float)kernel[j] * gesture[i - kernel_size + j].time;
                }
                output.Add(point);
            }

            return(output);
        }
Пример #18
0
        public void ConstructorHandlingHonorsCustomConverters()
        {
            // Baseline, use internal converters for primitives
            Point_2D point = Serializer.Deserialize <Point_2D>(@"{""X"":2,""Y"":3}");

            Assert.Equal(2, point.X);
            Assert.Equal(3, point.Y);

            // Honor custom converters
            var options = new JsonSerializerOptions();

            options.Converters.Add(new ConverterForInt32());

            point = Serializer.Deserialize <Point_2D>(@"{""X"":2,""Y"":3}", options);
            Assert.Equal(25, point.X);
            Assert.Equal(25, point.X);
        }
Пример #19
0
        public static void ComplexReferenceTypeConverter_NoOverride()
        {
            // Baseline
            Point_2D obj = JsonSerializer.Deserialize <Point_2D>("null");

            Assert.Null(obj);
            Assert.Equal("null", JsonSerializer.Serialize(obj));

            // Per null handling default value for reference types (false), serializer handles null.
            var options = new JsonSerializerOptions();

            options.Converters.Add(new PointClassConverter_SpecialCaseNull());

            obj = JsonSerializer.Deserialize <Point_2D>("null", options);
            Assert.Null(obj);
            Assert.Equal("null", JsonSerializer.Serialize(obj));
        }
Пример #20
0
        private static void PointsInCircle_Solution()
        {
            Console.WriteLine($"Enter Point's data:");
            Console.Write("Point.X: ");
            var userInput_PointX    = Console.ReadLine();
            var isValidInput_PointX = double.TryParse(userInput_PointX, out double pointX);

            Console.Write("Point.Y: ");
            var userInput_PointY    = Console.ReadLine();
            var isValidInput_PointY = double.TryParse(userInput_PointY, out double pointY);
            var log = new StringBuilder();

            log.AppendLine(isValidInput_PointX && isValidInput_PointY ? "Valid input for both X and Y" : $"Wrong Input for one/both of the Points: Point.X({userInput_PointX}) Point.Y({userInput_PointY})");

            var point  = new Point_2D(pointX, pointY);
            var circle = new Circle();

            var msg_result = $"{(point.CheckInsideCircle(circle) ? "yes" : "no")} {point.FindDistanceToCenter():F2}";

            Console.WriteLine(msg_result);
        }
Пример #21
0
 /*
  * Hough transform.
  */
 private HoughPoint[] hough_transform(List <Point_2D> gesture)
 {
     HoughPoint[] houghpoints = new HoughPoint[gesture.Count - 1];
     for (int i = 0; i < houghpoints.Length; i++)
     {
         Point_2D a     = gesture[i];
         Point_2D b     = gesture[i + 1];
         float    dy    = b.y - a.y;
         float    dx    = b.x - a.x;
         float    a_r   = (float)Math.Sqrt(a.x * a.x + a.y * a.y);
         float    b_r   = (float)Math.Sqrt(b.x * b.x + b.y * b.y);
         float    a_phi = (float)Math.Atan2(a.y, a.x);
         float    b_phi = (float)Math.Atan2(b.y, b.x);
         float    phi_0 = (float)((Math.Abs(b.x - a.x) < 0.001) ? Math.PI / 2 : Math.Atan2(dy, dx));
         phi_0 += (float)(2 * Math.PI);
         phi_0 %= (float)(2 * Math.PI);
         float d = (float)(a_r * Math.Sin(a_phi - phi_0));
         houghpoints[i] = new HoughPoint(d, phi_0, i, (float)Math.Sqrt(dx * dx + dy * dy));
     }
     return(houghpoints);
 }
        public async Task UseDefaultValues_When_NoJsonMatch()
        {
            // Using CLR value when `ParameterInfo.DefaultValue` is not set.
            Point_2D point = await Serializer.DeserializeWrapper <Point_2D>(@"{""x"":1,""y"":2}");

            Assert.Equal(0, point.X);
            Assert.Equal(0, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{""y"":2,""x"":1}");

            Assert.Equal(0, point.X);
            Assert.Equal(0, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{""x"":1,""Y"":2}");

            Assert.Equal(0, point.X);
            Assert.Equal(2, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{""y"":2,""X"":1}");

            Assert.Equal(1, point.X);
            Assert.Equal(0, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{""X"":1}");

            Assert.Equal(1, point.X);
            Assert.Equal(0, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{""Y"":2}");

            Assert.Equal(0, point.X);
            Assert.Equal(2, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{""X"":1}");

            Assert.Equal(1, point.X);
            Assert.Equal(0, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{""Y"":2}");

            Assert.Equal(0, point.X);
            Assert.Equal(2, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{}");

            Assert.Equal(0, point.X);
            Assert.Equal(0, point.Y);

            point = await Serializer.DeserializeWrapper <Point_2D>(@"{""a"":1,""b"":2}");

            Assert.Equal(0, point.X);
            Assert.Equal(0, point.Y);

            // Using `ParameterInfo.DefaultValue` when set; using CLR value as fallback.
            Point_3D point3d = await Serializer.DeserializeWrapper <Point_3D>(@"{""X"":1}");

            Assert.Equal(1, point3d.X);
            Assert.Equal(0, point3d.Y);
            Assert.Equal(50, point3d.Z);

            point3d = await Serializer.DeserializeWrapper <Point_3D>(@"{""y"":2}");

            Assert.Equal(0, point3d.X);
            Assert.Equal(0, point3d.Y);
            Assert.Equal(50, point3d.Z);

            point3d = await Serializer.DeserializeWrapper <Point_3D>(@"{""Z"":3}");

            Assert.Equal(0, point3d.X);
            Assert.Equal(0, point3d.Y);
            Assert.Equal(3, point3d.Z);

            point3d = await Serializer.DeserializeWrapper <Point_3D>(@"{""X"":1}");

            Assert.Equal(1, point3d.X);
            Assert.Equal(0, point3d.Y);
            Assert.Equal(50, point3d.Z);

            point3d = await Serializer.DeserializeWrapper <Point_3D>(@"{""Y"":2}");

            Assert.Equal(0, point3d.X);
            Assert.Equal(2, point3d.Y);
            Assert.Equal(50, point3d.Z);

            point3d = await Serializer.DeserializeWrapper <Point_3D>(@"{""Z"":3}");

            Assert.Equal(0, point3d.X);
            Assert.Equal(0, point3d.Y);
            Assert.Equal(3, point3d.Z);

            point3d = await Serializer.DeserializeWrapper <Point_3D>(@"{""x"":1,""Y"":2}");

            Assert.Equal(0, point3d.X);
            Assert.Equal(2, point3d.Y);
            Assert.Equal(50, point3d.Z);

            point3d = await Serializer.DeserializeWrapper <Point_3D>(@"{""Z"":3,""y"":2}");

            Assert.Equal(0, point3d.X);
            Assert.Equal(0, point3d.Y);
            Assert.Equal(3, point3d.Z);

            point3d = await Serializer.DeserializeWrapper <Point_3D>(@"{""x"":1,""Z"":3}");

            Assert.Equal(0, point3d.X);
            Assert.Equal(0, point3d.Y);
            Assert.Equal(3, point3d.Z);

            point3d = await Serializer.DeserializeWrapper <Point_3D>(@"{}");

            Assert.Equal(0, point3d.X);
            Assert.Equal(0, point3d.Y);
            Assert.Equal(50, point3d.Z);

            point3d = await Serializer.DeserializeWrapper <Point_3D>(@"{""a"":1,""b"":2}");

            Assert.Equal(0, point3d.X);
            Assert.Equal(0, point3d.Y);
            Assert.Equal(50, point3d.Z);
        }
Пример #23
0
static void Main(string[] args)
{
    double x, y;
    x = 5;
    y = 8;
    Console.WriteLine(string.Format("Vars: ({0:0.00};{1:0.00}) = ({2:0.00};{3:0.00})", x, y, phi(x, y), radius(x, y)));


    Struct_2D s = new Struct_2D();
    s.x = 5;
    s.y = 8;
    Console.WriteLine(string.Format("S: ({0:0.00};{1:0.00}) = ({2:0.00};{3:0.00})", s.x, s.y, phi(s.x, s.y), radius(s.x, s.y)));

    Console.WriteLine();

    Point_2D p1 = new Point_2D();
    p1.setEucledian(5, 8);
    Console.WriteLine(string.Format("P1: ({0:0.00};{1:0.00}) = ({2:0.00};{3:0.00})", p1.X, p1.Y, p1.phi, p1.radius));


    Point_2D p2 = new Point_2D();
    p2.setPolar(32.01, 9.434);
    Console.WriteLine(string.Format("P2: ({0:0.00};{1:0.00}) = ({2:0.00};{3:0.00})", p2.X, p2.Y, p2.phi, p2.radius));

    Console.WriteLine();

    Struct_o_2D so = new Struct_o_2D();
    so.setEucledian(5, 8);
    Console.WriteLine(string.Format("S2: ({0:0.00};{1:0.00}) = ({2:0.00};{3:0.00})", so.X, so.Y, so.phi, so.radius));

    Console.WriteLine();

    Struct_o_2D soTemp = so;
    Point_2D pTemp = p2;
    Console.WriteLine(string.Format("STemp: ({0:0.00};{1:0.00}) = ({2:0.00};{3:0.00})", soTemp.X, soTemp.Y, soTemp.phi, soTemp.radius));
    Console.WriteLine(string.Format("PTemp: ({0:0.00};{1:0.00}) = ({2:0.00};{3:0.00})", pTemp.X, pTemp.Y, pTemp.phi, pTemp.radius));

    so.setEucledian(3, 3);
    p2.setEucledian(3, 3);

    Console.WriteLine();

    Console.WriteLine(string.Format("STemp: ({0:0.00};{1:0.00}) = ({2:0.00};{3:0.00})", soTemp.X, soTemp.Y, soTemp.phi, soTemp.radius));
    Console.WriteLine(string.Format("PTemp: ({0:0.00};{1:0.00}) = ({2:0.00};{3:0.00})", pTemp.X, pTemp.Y, pTemp.phi, pTemp.radius));

    Console.WriteLine();
}
Пример #24
0
        public Program()
        {
            List <Point_2D> gesture = new List <Point_2D>();

            string line;

            while ((line = Console.ReadLine()) != null && line != "")
            {
                string[] value_str  = line.Split(' ');
                var      data_point = new Point_2D();
                data_point.time = float.Parse(value_str[0]);
                data_point.x    = float.Parse(value_str[1]);
                data_point.y    = float.Parse(value_str[2]);
                data_point.z    = float.Parse(value_str[3]);
                gesture.Add(data_point);
            }

            // above is for demo code only
            Console.WriteLine("start");
            var watch = System.Diagnostics.Stopwatch.StartNew();

            Bounds       bounds = calculate_bounds(ref gesture, 0, gesture.Count);
            List <float> angles = new List <float>();

            if (LP_ENABLE)
            {
                gesture = gaussian_average_lowpass(gesture, LP_KERNEL_SIZE, LP_SIGMA);
            }

            float    angle_sum    = calculate_angles(ref gesture, ref angles, bounds);
            Point_2D avg_vel_vec2 = mean_velocity_2D(ref gesture);
            //Point_3D avg_vel_vec3 = mean_velocity_3D(ref gesture3D);

            float    gesture_width  = bounds.max_x - bounds.min_x;
            float    gesture_height = bounds.max_y - bounds.min_y;
            float    gesture_depth  = bounds.max_z - bounds.min_z;
            Point_2D start          = gesture[0];
            Point_2D end            = gesture[gesture.Count - 1];

            Gesture_Meta ret = new Gesture_Meta();

            ret.type = Gesture.unknown;
            //ret.avg_vel_vector = avg_vel_vec3;
            ret.angle_sum = angle_sum;
            ret.bounds    = bounds;

            // get velocity & acceleration vectors for gestures
            List <Point_2D> sparse_gesture = sparsify(ref gesture);
            List <Point_2D> vel_vectors    = derive_vector_list(ref sparse_gesture);
            List <Point_2D> acc_vectors    = derive_vector_list(ref vel_vectors);

            float[] vel_norms     = vector_list_norms(ref vel_vectors, true);
            float[] acc_norms     = vector_list_norms(ref acc_vectors, true);
            float[] global_angles = vector_list_angles(ref sparse_gesture);

            // ******************** gesture classification *********************
            float vel_vec_norm = vec2_norm(avg_vel_vec2, false);
            float x_pos_dev    = angle(avg_vel_vec2, new Point_2D(0, 1, 0, 0), false);
            float y_pos_dev    = angle(avg_vel_vec2, new Point_2D(0, 0, 1, 0), false);
            float z_pos_dev    = angle(avg_vel_vec2, new Point_2D(0, 0, 0, 1), false);
            float x_neg_dev    = angle(avg_vel_vec2, new Point_2D(0, -1, 0, 0), false);
            float y_neg_dev    = angle(avg_vel_vec2, new Point_2D(0, 0, -1, 0), false);
            float z_neg_dev    = angle(avg_vel_vec2, new Point_2D(0, 0, 0, -1), false);
            bool  x_pos        = x_pos_dev < x_neg_dev;
            bool  y_pos        = y_pos_dev < y_neg_dev;
            bool  z_pos        = z_pos_dev < z_neg_dev;
            bool  z_gesture    = gesture_depth > gesture_height &&
                                 gesture_depth > gesture_width;

            if (vel_vec_norm < VEL_VEC_NORM_THRESH && Math.Abs(angle_sum) > 6 * ANGLE_SUM_THRESH)
            {
                // likely a circle
                float min_angle = (float)((2 - ANGLE_SUM_THRESH) * Math.PI);
                float max_angle = (float)((2 + ANGLE_SUM_THRESH) * Math.PI);
                if (angle_sum > min_angle && angle_sum < max_angle)
                {
                    ret.type = Gesture.circle_ccw;
                }
                if (angle_sum < -min_angle && angle_sum > -max_angle)
                {
                    ret.type = Gesture.circle_cw;
                }
            }
            else if (vel_vec_norm > VEL_VEC_NORM_THRESH && z_gesture || gesture_depth > Z_DEPTH_THRESH)
            {
                // likely a gesture with depth
                if (z_pos_dev < ANGLE_DEVIATION_THRESH && Math.Abs(avg_vel_vec2.z) > 0.2)
                {
                    ret.type = Gesture.push;
                }
                else if (z_neg_dev < ANGLE_DEVIATION_THRESH && Math.Abs(avg_vel_vec2.z) > 0.2)
                {
                    ret.type = Gesture.pull;
                }
            }
            else if (ret.type == Gesture.unknown)
            {
                // likely a gesture of one or more line segments
                List <LinearSegment> segments = find_linear_segments(global_angles, sparse_gesture, bounds);
                Console.WriteLine(segments.Count);

                foreach (var s in segments)
                {
                    Console.WriteLine(s.val + " " + s.weight);
                }

                //Gesture[] candidate_gestures = gesture_len_map[segments.Count];
                Gesture[] candidate_gestures;
                gesture_len_map.TryGetValue(segments.Count, out candidate_gestures);
                if (candidate_gestures != null)
                {
                    foreach (Gesture g in candidate_gestures)
                    {
                        if (matches_linear_segments(segments, g, sparse_gesture,
                                                    alt_start_allowed_map[g]))
                        {
                            ret.type = g;
                            break;
                        }
                    }
                }
            }

            // Debug print
            watch.Stop();
            float time = watch.ElapsedMilliseconds;

            Console.WriteLine(time + "ms");
            Console.WriteLine(ret.type);

            //HoughPoint[] hh = hough_transform(sparse_gesture);
            //foreach(var h in hh) {
            //    Console.WriteLine(h.i + ": " /*+ h.r + " "*/ + h.phi + " @ " + h.weight);
            //}
        }
Пример #25
0
 /*
  * Returns the dot product of two 2D vectors.
  */
 private float dot(Point_2D a, Point_2D b, bool ignore_z)
 {
     return(a.x * b.x + a.y * b.y + ((ignore_z) ? 0 : a.z *b.z));
 }
Пример #26
0
    public Gesture_Meta recognize_gesture(List <Point_2D> gesture, List <Point_3D> gesture3D)
    {
        if (gesture.Count <= 2 * LP_KERNEL_SIZE)
        {
            var gm = new Gesture_Meta();
            gm.type = Gesture.unknown;
            return(gm);
        }
        Bounds       bounds = calculate_bounds(ref gesture, 0, gesture.Count);
        List <float> angles = new List <float>();

        if (LP_ENABLE)
        {
            gesture = gaussian_average_lowpass(gesture, LP_KERNEL_SIZE, LP_SIGMA);
        }

        float    angle_sum    = calculate_angles(ref gesture, ref angles, bounds);
        Point_2D avg_vel_vec2 = mean_velocity_2D(ref gesture);
        Point_3D avg_vel_vec3 = mean_velocity_3D(ref gesture3D);

        float    gesture_width  = bounds.max_x - bounds.min_x;
        float    gesture_height = bounds.max_y - bounds.min_y;
        float    gesture_depth  = bounds.max_z - bounds.min_z;
        Point_2D start          = gesture[0];
        Point_2D end            = gesture[gesture.Count - 1];

        Gesture_Meta ret = new Gesture_Meta();

        ret.type           = Gesture.unknown;
        ret.avg_vel_vector = avg_vel_vec3;
        ret.angle_sum      = angle_sum;
        ret.bounds         = bounds;

        List <Point_2D> sparse_gesture = sparsify(ref gesture);

        float[] global_angles = vector_list_angles(ref sparse_gesture);

        // ************************ Classify gesture **************************
        float vel_vec_norm = vec2_norm(avg_vel_vec2, false);
        float x_pos_dev    = angle(avg_vel_vec2, new Point_2D(0, 1, 0, 0), false);
        float y_pos_dev    = angle(avg_vel_vec2, new Point_2D(0, 0, 1, 0), false);
        float z_pos_dev    = angle(avg_vel_vec2, new Point_2D(0, 0, 0, 1), false);
        float x_neg_dev    = angle(avg_vel_vec2, new Point_2D(0, -1, 0, 0), false);
        float y_neg_dev    = angle(avg_vel_vec2, new Point_2D(0, 0, -1, 0), false);
        float z_neg_dev    = angle(avg_vel_vec2, new Point_2D(0, 0, 0, -1), false);
        bool  x_pos        = x_pos_dev < x_neg_dev;
        bool  y_pos        = y_pos_dev < y_neg_dev;
        bool  z_pos        = z_pos_dev < z_neg_dev;
        bool  z_gesture    = gesture_depth > gesture_height &&
                             gesture_depth > gesture_width;

        // likely a gesture with depth
        if (vel_vec_norm > VEL_VEC_NORM_THRESH && z_gesture || gesture_depth > Z_DEPTH_THRESH)
        {
            if (z_pos_dev < ANGLE_DEVIATION_THRESH && Math.Abs(avg_vel_vec2.z) > 0.2)
            {
                ret.type = Gesture.push;
            }
            else if (z_neg_dev < ANGLE_DEVIATION_THRESH && Math.Abs(avg_vel_vec2.z) > 0.2)
            {
                ret.type = Gesture.pull;
            }
        }

        // likely a gesture of one or more line segments
        if (ret.type == Gesture.unknown)
        {
            List <LinearSegment> segments = find_linear_segments(global_angles, sparse_gesture, bounds);
            Console.WriteLine(segments.Count);

            Gesture[] candidate_gestures;
            gesture_len_map.TryGetValue(segments.Count, out candidate_gestures);
            if (candidate_gestures != null)
            {
                foreach (Gesture g in candidate_gestures)
                {
                    if (matches_linear_segments(segments, g, sparse_gesture,
                                                alt_start_allowed_map[g]))
                    {
                        ret.type = g;
                        break;
                    }
                }
            }
        }

        // likely a circle
        if (ret.type == Gesture.unknown)
        {
            // likely a circle
            float min_angle = (float)((2 - ANGLE_SUM_THRESH) * Math.PI);
            float max_angle = (float)((2 + ANGLE_SUM_THRESH) * Math.PI);
            if (angle_sum > min_angle && angle_sum < max_angle)
            {
                ret.type = Gesture.circle_ccw;
            }
            else if (angle_sum < -min_angle && angle_sum > -max_angle)
            {
                ret.type = Gesture.circle_cw;
            }
            else if (angle_sum > 6 * Math.PI)
            {
                ret.type = Gesture.spiral_ccw;
            }
        }

        return(ret);
    }