internal Trace(CursorPoint cursor, Group group, List<IGestureListener> targets, bool guiTargets) { m_id = s_idCounter++; m_group = group; m_path = new List<CursorPoint>(); m_path.Add(cursor); m_first = m_last = cursor; m_state = States.ADDED; m_isAlive = true; m_initialTargets = new List<IGestureListener>(); m_finalTargets = new List<IGestureListener>(); m_enteringTargets = new List<IGestureListener>(); m_currentTargets = new List<IGestureListener>(); m_leavingTargets = new List<IGestureListener>(); m_intersectionTargets = new List<IGestureListener>(); m_unionTargets = new List<IGestureListener>(); m_group.StartTrace(this); UpdateTargets(targets, guiTargets); }
public float SquareDistance(CursorPoint cursor) { float dx = m_x - cursor.X; float dy = m_y - cursor.Y; return dx * dx + dy * dy; }
private bool TryResurrectTrace(CursorPoint cursor, out Trace resurrectingTrace) { resurrectingTrace = null; float minDist = Settings.TRACE_SPACE_GAP * Settings.TRACE_SPACE_GAP; float dist; foreach (Trace trace in m_resurrectableTraces) { dist = trace.Last.SquareDistance(cursor); if (dist < minDist) { minDist = dist; resurrectingTrace = trace; } } if (resurrectingTrace != null) { m_resurrectableTraces.Remove(resurrectingTrace); return true; } else return false; }
/// <summary> /// Clustering method. Determine the best matching group to add the cursor's trace to. /// If none existing groups are suitable, a new one is created. /// </summary> /// <param name="cursor">The cursor to cluster</param> /// <param name="targets">The given cursor's targets</param> /// <param name="guiTargets">Flag indicating whether the given targets are GUI controls</param> /// <returns>The matching group where to add the given cursor-s trace.</returns> private Group GetMatchingGroup(CursorPoint cursor, List<IGestureListener> targets, bool isZControl) { Group matchingGroup = null; float minDist = Settings.GROUPING_SPACE * Settings.GROUPING_SPACE; float tempDist; foreach (Group group in m_activeGroups) { // filter out groups that don't accept the trace if (!group.AcceptNewCursor(cursor, targets, isZControl)) continue; // group all traces on the same zControl if (isZControl && group.OnZControl && targets[0] == group.ClosestCurrentTarget) { matchingGroup = group; break; } // find the closest tempDist = group.SquareDistanceToNearestTrace(cursor, Settings.CLUSTERING_ONLY_WITH_ALIVE_TRACES); if (tempDist < minDist) { minDist = tempDist; matchingGroup = group; } } // if no group is found, create a new one if (matchingGroup == null) matchingGroup = CreateGroup(); return matchingGroup; }
protected void OnUp(CursorPoint c) { AppendEvent(Up, new BasicMultiFingerEventArgs("Up", Group.Id, c.X, c.Y, m_numberOfCurrentFingers, m_validInitialZTarget)); }
private void UpdateCursorValues(CursorPoint cursor) { if (m_state != States.REMOVED) { double dt = (double)(cursor.TimeStamp - m_last.TimeStamp) / 1000; double xSpeed = ((double)cursor.X - (double)m_last.X) / dt; double ySpeed = ((double)cursor.Y - (double)m_last.Y) / dt; double motionSpeed = Math.Sqrt(xSpeed * xSpeed + ySpeed * ySpeed); double motionAccel = (motionSpeed - (double)m_last.MotionSpeed) / dt; cursor.XSpeed = (float)xSpeed; cursor.YSpeed = (float)ySpeed; cursor.MotionSpeed = (float)motionSpeed; cursor.MotionAcceleration = (float)motionAccel; } //Console.WriteLine("x_sp={0},\ty_sp={1},\tsp={2},\tac={3}", cursor.XSpeed, cursor.YSpeed, cursor.MotionSpeed, cursor.MotionAcceleration); }
internal void AppendRemovingCursor( CursorPoint cursor, List<IGestureListener> targets, bool isZControl) { UpdateCursorValues(cursor); m_path.Add(cursor); m_last = cursor; m_isAlive = false; m_state = States.REMOVED; m_group.EndTrace(this); UpdateTargets(targets, isZControl); }
internal void AppendAddingOrUpdatingCursor( CursorPoint cursor, List<IGestureListener> targets, bool isZControl) { UpdateCursorValues(cursor); m_path.Add(cursor); m_last = cursor; if (m_state == States.REMOVED) { m_state = States.RESET; m_isAlive = true; } else m_state = States.UPDATED; m_group.UpdateTrace(this); UpdateTargets(targets, isZControl); }