using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows;
namespace GestureControl
{
/// <summary>
/// Take a list of points and try to recognize a pattern
/// </summary>
public class SurfaceGesture : List<SurfaceGestureVector>
{
#region Prop
/// <summary>
/// Allow some variation without log a direction
/// </summary>
public int Precision { get; set; }
#endregion
#region Constructor
/// <summary>
/// load know patterns and generate the vector list from a list of points with a default 20 precision factor
/// </summary>
/// <param name="list"></param>
public SurfaceGesture(List<SurfaceGesturePoint> list)
{
this.Precision = 20;
this.Generate(list);
}
/// <summary>
/// load know patterns and generate the vector list from a list of points with a precision factor
/// </summary>
/// <param name="list"></param>
/// <param name="precision"></param>
public SurfaceGesture(List<SurfaceGesturePoint> list, int precision)
{
this.Precision = precision;
this.Generate(list);
}
#endregion
#region GenerateVector
/// <summary>
/// Generate list of vector from courbe mouvements, filter with the pas value
/// </summary>
/// <param name="list"></param>
/// <param name="pas"></param>
/// <returns></returns>
private bool GenerateCourb(List<SurfaceGesturePoint> list, int pas)
{
int sep = list.Count / pas;
double count = 0; ;
SurfaceGesturePoint past = new SurfaceGesturePoint() { X = 0, Y = 0 };
double y = 0;
for (int i = 0; i < list.Count - 1; i++)
{
if (i % pas != 0)
{
count += Math.Atan(list[i + 1].Y / list[i + 1].X) - Math.Atan(list[i].Y / list[i].X);
}
else
{
count /= pas;
if (count == 0 || this.GetDistancePoints(past, list[i + 1]) < 5)
{
y = list[i + 1].Y;
past.X = count;
continue;
}
if (y > list[i + 1].Y)
{
if (past.X > count)
this.AddDirection(SurfaceGestureVectorDirection.UPRIGHT);
else
this.AddDirection(SurfaceGestureVectorDirection.UPLEFT);
}
else
{
if (past.X > count)
this.AddDirection(SurfaceGestureVectorDirection.DOWNRIGHT);
else
this.AddDirection(SurfaceGestureVectorDirection.DOWNLEFT);
}
y = list[i + 1].Y;
past.X = count;
}
}
Console.Write(this);
/*if (this.GetPattern() != "None")
return true;
else*/
return false;
}
/// <summary>
/// Get distance between two points
/// </summary>
/// <param name="p1"></param>
/// <param name="p2"></param>
/// <returns></returns>
private int GetDistancePoints(SurfaceGesturePoint p1, SurfaceGesturePoint p2)
{
return (int)Math.Sqrt(Math.Pow((p2.X - p1.X), 2) + Math.Pow((p1.Y - p2.Y), 2));
}
/// <summary>
/// add a direction in the vector list if past who not the same
/// </summary>
/// <param name="type"></param>
private void AddDirection(SurfaceGestureVectorDirection type)
{
if (this.Count == 0)
{
this.Add(new SurfaceGestureVector { Direction = type, Lenght = 42 });
return;
}
if (this[this.Count - 1].Direction != type)
this.Add(new SurfaceGestureVector { Direction = type, Lenght = 42 });
}
/// <summary>
/// generate list of vector
/// </summary>
/// <param name="list"></param>
private void Generate(List<SurfaceGesturePoint> list)
{
this.Clear();
if (list.Count < 2)
{
this.Add(new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.TAP, Lenght = 0 });
return;
}
List<SurfaceGesturePoint> Points = new List<SurfaceGesturePoint>();
List<SurfaceGestureVector> Vectors = new List<SurfaceGestureVector>();
for (int index = 1; index <= list.Count; index++)
{
if (index == list.Count / 2 || index == list.Count)
{
SurfaceGestureVector verctorTemp = AnalysePoints(Points);
if (Vectors.Count == 0 || !Vectors[Vectors.Count - 1].Direction.Equals(verctorTemp.Direction))
Vectors.Add(verctorTemp);
Points.Clear();
}
else
Points.Add(list[index]);
}
foreach (SurfaceGestureVector elt in Vectors)
this.Add(elt);
}
SurfaceGestureVector AnalysePoints(List<SurfaceGesturePoint> list)
{
double diffX = Math.Abs(list[0].X - list[list.Count - 1].X);
double diffY = Math.Abs(list[0].Y - list[list.Count - 1].Y);
if (diffX < 10 && diffY > 10)
{
if (list[0].Y > list[list.Count - 1].Y)
return (new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.UP, Lenght = 0, Origin = list[0] });
else
return (new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.DOWN, Lenght = 0, Origin = list[0] });
}
else if (diffY < 10 && diffX > 10)
{
if (list[list.Count - 1].X > list[0].X)
return (new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.RIGHT, Lenght = 0, Origin = list[0] });
else
return (new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.LEFT, Lenght = 0, Origin = list[0] });
}
else if (diffX > 10 && diffY > 10)
{
if (list[0].Y > list[list.Count - 1].Y && list[list.Count - 1].X > list[0].X)
return new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.UPRIGHT, Lenght = 0, Origin = list[0] };
else if (list[0].Y > list[list.Count - 1].Y && list[list.Count - 1].X < list[0].X)
return new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.UPLEFT, Lenght = 0, Origin = list[0] };
else if (list[0].Y < list[list.Count - 1].Y && list[list.Count - 1].X > list[0].X)
return new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.DOWNRIGHT, Lenght = 0, Origin = list[0] };
else
return new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.DOWNLEFT, Lenght = 0, Origin = list[0] };
}
else
return new SurfaceGestureVector { Direction = SurfaceGestureVectorDirection.TAP, Lenght = 0 };
}
private SurfaceGestureVectorDirection GetHorizontal(SurfaceGesturePoint p1, SurfaceGesturePoint p2)
{
if (p1.Y < p2.Y)
{
// go up
if (Math.Abs(p2.X - p1.X) < Math.Abs(p2.Y - p1.Y))
return SurfaceGestureVectorDirection.DOWN;
else
{
if (p1.X < p2.X)
return SurfaceGestureVectorDirection.DOWNRIGHT;
else
return SurfaceGestureVectorDirection.DOWNLEFT;
}
}
else
{
// go down
if (Math.Abs(p1.X - p2.X) < Math.Abs(p1.Y - p2.Y))
return SurfaceGestureVectorDirection.UP;
else
{
if (p1.X < p2.X)
return SurfaceGestureVectorDirection.UPRIGHT;
else
return SurfaceGestureVectorDirection.UPLEFT;
}
}
}
private SurfaceGestureVectorDirection GetVertical(SurfaceGesturePoint p1, SurfaceGesturePoint p2)
{
if (p1.X < p2.X)
{
// go left
if (Math.Abs(p2.Y - p1.Y) < Math.Abs(p2.X - p1.X))
return SurfaceGestureVectorDirection.RIGHT;
else
{
if (p1.Y < p2.Y)
return SurfaceGestureVectorDirection.DOWNRIGHT;
else
return SurfaceGestureVectorDirection.UPRIGHT;
}
}
else
{
// go right=
if (Math.Abs(p1.Y - p2.Y) < Math.Abs(p1.X - p2.X))
return SurfaceGestureVectorDirection.LEFT;
else
{
if (p1.Y < p2.Y)
return SurfaceGestureVectorDirection.DOWNLEFT;
else
return SurfaceGestureVectorDirection.UPLEFT;
}
}
}
#endregion
#region Override
public override String ToString()
{
String ret = "";
foreach (SurfaceGestureVector v in this)
{
ret += (v.Direction + ", lenght:" + v.Lenght + ", precision:" + this.Precision + "\n");
//Console.WriteLine(v.Direction + ", lenght:" + v.Lenght + ", precision:" + this.Precision);
}
return ret;
}
#endregion
}
}