private void CalculateOrthogonalDirectionChange(FittsCoordinate coord, FittsTrajectory trajectory)
        {
            List <double> totalDistanceDifference = new List <double>();

            Vector2 firstPoint   = new Vector2(trajectory.x[0], trajectory.y[0]);
            double  lastDistance = Vector2.Distance(coord.select, firstPoint);

            bool distanceIsShorter = true;

            for (int i = 0; i < trajectory.x.Count; i++)
            {
                double currentDistance = Vector2.Distance(coord.select, new Vector2(trajectory.x[i], trajectory.y[i]));
                // Check to see if the trajectory continues in the same direction
                if (distanceIsShorter == currentDistance <= lastDistance)
                {
                    lastDistance = currentDistance;
                    // We clear the distance covered in new direction as not to add past difference to actual one
                    totalDistanceDifference.Clear();
                    continue;
                }
                // A new direction is chosen so we add up the distance covered in the new direction
                // to record a MDC only if it reach a certain threshold
                totalDistanceDifference.Add(currentDistance > lastDistance ? currentDistance - lastDistance : lastDistance - currentDistance);
                // The threshold is reached
                if (totalDistanceDifference.Sum() > threshold)
                {
                    distanceIsShorter = currentDistance <= lastDistance;
                    totalDistanceDifference.Clear();
                    orthogonalDirectionChange++;
                }
                lastDistance = currentDistance;
            }
        }
 public FittsTrial(FittsTime _time, FittsCoordinate _coord, bool isTouchingTarget, FittsTrajectory _trajectory)
 {
     time       = _time;
     coord      = _coord;
     trajectory = _trajectory;
     isError    = !isTouchingTarget;
 }
        public FittsSequence(SequenceParameter _parameter)
        {
            fittsTrials = new List <FittsTrial>();

            parameter = _parameter;

            trajectory = new FittsTrajectory();

            isInTarget = false;
        }
        public bool AddTriggerEvent(Vector3 pos, FittsTime time, bool trialIsError)
        {
            // Check if first selection because it is not recorded
            if (!TargetsCreator.IsFirstTarget())
            {
                AddTrial(pos, time, trialIsError);
            }

            // Start a new trajectory for the new target because each trial has his trajectory
            trajectory = new FittsTrajectory();

            return(parameter.nbOfTarget == fittsTrials.Count);
        }
        private void CreateDeltaYList(FittsCoordinate coord, FittsTrajectory trajectory)
        {
            // Contains the delta y from the controller trajectory and the projected line between from and select
            deltaY = new List <double>();

            // Ax + By + C = 0
            float a = (coord.select.y - coord.from.y) / (coord.select.x - coord.from.x);
            float b = -1;
            float c = coord.select.y - coord.select.x * a;

            // Fetch x and y coord of trajectory
            var trajectoryCoords = trajectory.x.Zip(trajectory.y, (_x, _y) => new { x = _x, y = _y });

            // Find each delta y for each trajectory coordinate
            foreach (var trajCoord in trajectoryCoords)
            {
                deltaY.Add((a * trajCoord.x + b * trajCoord.y + c) / (Math.Sqrt(a * a + b * b)));
            }
        }
        public FittsMovement(FittsCoordinate coord, FittsTrajectory trajectory)
        {
            threshold = 0.01f;

            CreateDeltaYList(coord, trajectory);

            // MO
            movementOffset = deltaY.Sum() / trajectory.y.Count;
            // ME
            movementError = deltaY.Sum(y => Math.Abs(y)) / trajectory.y.Count;
            // MV
            movementVariable = Math.Sqrt(deltaY.Sum(y => Math.Pow(y - movementOffset, 2)) / (trajectory.x.Count - 1));

            // TAC
            CalculateTaskAxisCrossing();
            // MDC
            CalculateMovementDirectionChange();
            // ODC
            CalculateOrthogonalDirectionChange(coord, trajectory);
        }