private bool TestCrossing(GestureQuad quad, PointF p, PointF p2) { var q = quad.C; var q2 = quad.D; var r = p2.Subtract(p); var s = q2.Subtract(q); var qp = q.Subtract(p); var rs = r.Cross(s); // parallel case if (rs == 0) return false; var t = qp.Cross(s) / rs; var u = qp.Cross(r) / rs; return (t >= 0 && t <= 1 && u >= 0 && u <= 1); }
public GestureState TestMotion(int index, PointF start, PointF end) { if (index >= Points.Count - 1) { return GestureState.Complete; } var previousPoint = Points[index]; var nextPoint = Points[index + 1]; var previousRadiusSq = previousPoint.threshold * previousPoint.threshold; var endDX = end.X - previousPoint.X; var endDY = end.Y - previousPoint.Y; var endRadiusSq = (endDX * endDX) + (endDY * endDY); var quad = new GestureQuad(previousPoint, nextPoint); // first check for point completion if (TestCrossing(quad, start, end)) { if (index == Points.Count - 2) return GestureState.Complete; else return GestureState.Advance; } // must be inside the quad or the starting circle if (!(endRadiusSq <= previousRadiusSq || quad.Test(end))) return GestureState.Fail; return GestureState.OK; }