示例#1
0
        // Determina la distancia que debe existir entre los puntos muestreados
        public static double DeterminingResampleSpacing(Stroke s)
        {
            double dist_between_points;
            Point  top_left     = new Point();
            Point  bottom_right = new Point();;

            // Se obtiene el BoundingBox del Stroke
            Rectangle r = s.GetBoundingBox();

            // Se asignan a top_left la esquina superior izquierda del boundingbox,
            // y a bottom_right la esquina inferior derecha.
            top_left.X = r.Left;
            top_left.Y = r.Top;

            bottom_right.X = r.Right;
            bottom_right.Y = r.Bottom;

            // Se calcula la longitud de la diagonal formada por las dos esquinas
            // calculadas
            double diagonal = ExtraMath.Distance(bottom_right, top_left);

            // Se calcula la distancia entre los puntos muestreados
            dist_between_points = diagonal / 40.0;

            return(dist_between_points);
        }
示例#2
0
        // Determina la distancia del tramo (no la distancia más corta)
        public static double PathDistance(List <Point> resampled, int a, int b)
        {
            double distance = 0;

            for (int i = a; i < b; i++)
            {
                distance += (double)ExtraMath.Distance(resampled[i], resampled[i + 1]);
            }
            return(distance);
        }
示例#3
0
        // Deja los puntos del stroke que esten espaciados en dist_between_points
        public static List <Point> ResamplePoints(Stroke s, double dist_between_points)
        {
            // Se crea una lista con los puntos del stroke
            List <Point> points = new List <Point>(s.GetPoints());

            // Se añade el primer punto del stroke a la coleccion de resampled
            List <Point> resampled = new List <Point>();

            resampled.Add(points[0]);

            // Se crea un nuevo punto que se utilizara mas adelante
            Point pt = new Point();

            // Se inicializa el marcador de distancia a 0
            double distance_holder = 0;

            // Se inicializa la distancia entre dos puntos
            double distance_points = 0;

            // Se recorren todos los puntos del stroke haciendo lo siguiente
            for (int i = 1; i < points.Count; i++)
            {
                // Se calcula la distancia Euclidea entre el punto actual y el anterior
                distance_points = ExtraMath.Distance(points[i - 1], points[i]);

                if ((distance_holder + distance_points) >= dist_between_points)
                {
                    // Se crea un punto nuevo (pt) localizado aproximadamente a una distancia
                    // dist_between_points del último punto muestreado
                    pt.X = (int)(points[i - 1].X +
                                 (((dist_between_points - distance_holder) / distance_points) *
                                  (points[i].X - points[i - 1].X)));
                    pt.Y = (int)(points[i - 1].Y +
                                 (((dist_between_points - distance_holder) / distance_points) *
                                  (points[i].Y - points[i - 1].Y)));

                    // Se añade el punto pt a la lista de "resampled"
                    resampled.Add(pt);

                    // Se añade el punto pt al stroke, en la posicion anterior al punto en el
                    // que estamos
                    points.Insert(i, pt);

                    distance_holder = 0;
                }
                else
                {
                    distance_holder += distance_points;
                }
            }

            return(resampled);
        }
 /// <summary>
 /// Calculated the first time it is asked for and cached after that.
 /// </summary>
 /// <returns></returns>
 public double GetConvexPerimeter()
 {
     if (this.convexPerimeter == 0)
     {
         double perim = 0;
         for (int i = 0; i < convexPoints.Length - 1; i++)
         {
             perim += ExtraMath.Distance(convexPoints[i], convexPoints[i + 1]);
         }
         convexPerimeter = perim;
     }
     return(convexPerimeter);
 }
示例#5
0
        // Determina si la parte del stroke indicada es una línea o no
        public static bool IsLine(List <Point> resampled, int a, int b)
        {
            double distance      = (double)ExtraMath.Distance(resampled[a], resampled[b]);
            double path_distance = (double)PathDistance(resampled, a, b);

            if ((distance / path_distance) > Facade.THRESHOLD)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        // Compara los strokes por longitud
        private static int CompareStrokesByLength(Stroke s1, Stroke s2)
        {
            if (s1 == null)
            {
                if (s2 == null)
                {
                    // Si s1==s2==null => son iguales
                    return(0);
                }
                else
                {
                    // Si s1==null y s2!=null, s2 es mayor
                    return(-1);
                }
            }
            else
            {
                // Si s1!=null...

                if (s2 == null)
                // ...y s2==null, s1 es mayor.
                {
                    return(1);
                }
                else
                {
                    // ... y s2!=null, comparar la longitud de los 2 strokes
                    // ExtraMath.Distance(s.GetPoint(s.GetPoints().Length-1), s.GetPoint(0))
                    double s1_length = ExtraMath.Distance(s1.GetPoint(s1.GetPoints().Length - 1), s1.GetPoint(0));
                    double s2_length = ExtraMath.Distance(s2.GetPoint(s2.GetPoints().Length - 1), s2.GetPoint(0));

                    int retval = s1_length.CompareTo(s2_length);

                    if (retval != 0)
                    {
                        // Si tienen distinta longitud, el más largo es mayor

                        return(retval);
                    }
                    else
                    {
                        // Si tienen el mismo tamaño se toma el primero como mayor

                        return(1);
                    }
                }
            }
        }
        // Determina si el stroke "n" pertenece a la relación del stroke "s"
        public static bool BelongsToRelation(Stroke s, Stroke n, int index)
        {
            float dist;

            float f_index = n.NearestPoint(s.GetPoint(index), out dist);

            double stroke_lenght = ExtraMath.Distance(s.GetPoint(s.GetPoints().Length - 1), s.GetPoint(0));

            if (dist < stroke_lenght * Facade.LENGTH_PERCENTAGE)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
        public static float GetFIndex(Point pt_corner, Stroke s)
        {
            double best_distance = Facade.INFINITE;
            double distance      = Facade.INFINITE;
            float  findex        = 0;

            for (int i = 0; i < s.GetPoints().Length; i++)
            {
                distance = ExtraMath.Distance(pt_corner, s.GetPoint(i));

                if (distance < best_distance)
                {
                    best_distance = distance;
                    findex        = (float)i;
                }
            }

            return(findex);
        }
示例#9
0
        // Busca los puntos de resampled que se corresponden con esquinas
        public static List <int> GetCorners(List <Point> resampled)
        {
            // Se crea la lista donde iran las esquinas. Almacenara un conjunto de indices
            // que referencian puntos. Por ejemplo, corner(i)=j indica que el punto(j) es
            // la i-esima esquina encontrada
            List <int> corners = new List <int>();

            corners.Add(0);

            // Se crea una lista con las distancias entre dos puntos separados W puntos del punto
            // actual
            List <double> straws = new List <double>();

            for (int i = 0; i < Facade.W; i++)
            {
                straws.Add(ExtraMath.Distance(resampled[i + Facade.W], resampled[i]));
            }

            for (int i = Facade.W; i < (resampled.Count - Facade.W); i++)
            {
                straws.Add(ExtraMath.Distance(resampled[i - Facade.W], resampled[i + Facade.W]));
            }

            for (int i = (resampled.Count - Facade.W); i < resampled.Count; i++)
            {
                straws.Add(ExtraMath.Distance(resampled[i - Facade.W], resampled[i]));
            }

            // Se calcula un umbral, threshold. Para ello, ordenamos la lista de straws y calculamos
            // su mediana. Para calcular la mediana se necesita ordenar la lista. Se trabajara con una
            // copia de la lista para no modificar la original
            List <double> copy_straws = new List <double>(straws);

            copy_straws.Sort();
            int    middle = copy_straws.Count / 2;
            double median = (copy_straws.Count % 2 != 0) ?
                            (double)copy_straws[middle] :
                            ((double)copy_straws[middle] + (double)copy_straws[middle - 1]) / 2;
            double threshold = median * 0.95;

            // Ahora se recorre la lista de straws. Si la distancia es menor que el umbral, se considera
            // esquina
            double local_min;
            int    local_min_index;

            for (int i = Facade.W; i < (resampled.Count - Facade.W); i++)
            {
                if (straws[i] < threshold)
                {
                    local_min       = Facade.INFINITE;
                    local_min_index = i;

                    while (i < straws.Count && straws[i] < threshold)
                    {
                        if (straws[i] < local_min)
                        {
                            local_min       = straws[i];
                            local_min_index = i;
                        }
                        i++;
                    }
                    corners.Add(local_min_index);
                }
            }
            // Se añade el ultimo indice a corners
            corners.Add(resampled.Count - 1);

            corners = PostProcessCorners(resampled, corners, straws);

            return(corners);
        }