For the curve or straight line problem, I think I'd keep a list of the positions of old input. Then, I'd check the slope between every point (delta Y / delta X). If the slope does not change a lot, then it's probably a line. If it varies a lot, it's probably a curve. You could use a limit representing the slope difference that determines if the input is a line or a curve.
So, if I had to implement such a functionality, I think I'd go like this:
List<Vector2> inputPositions = new List<Vector2>();//the old input positions
then I'd find the slopes between every position:
float deltaY = 0f;
float deltaX = 0f;
List<float> slopes = new List<float>();
for (int i = 0; i < inputPositions.Count - 1; ++i)//check all the positions except the last one
{
deltaY = inputPositions[i + 1].Y - inputPositions[i].Y;//next pos.Y - current.Y
deltaX = inputPositions[i + 1].X - inputPositions[i].X;//next pos.X - current.X
if (deltaX != 0.0f)//prevent division by 0
{
slopes.Add(deltaY / deltaX);
}
else
{
//I'm not really sure about using these values, but basically it
//means that the movement was vertical
slopes.Add(deltaY > 0.0f ? float.MaxValue : float.MinValue);
}
}
then you can analyse the results to see if the slope difference was too huge.
bool IsLine(List<float> slopes)
{
const float IS_NOT_LINE_SLOPE_DIFF = 0.05f;//find an appropriate constant for your program
float slopeVariation = 0f;
for (int i = 0; i < slopes.Count - 1; ++i)//check all but the last element
{
slopeVariation = slopes[i] - slopes[i + 1];
if (Math.Abs(slopeVariation) >= IS_NOT_LINE_SLOPE_DIFF)
return false;
}
return true;
}
You could even get the median of the slope variations to get a more general result.
Sure, this isn't the cleanest and certainly not the best way to solve your problem, but that's the way I would go to do it.