//public static class PointsEx //{ // public static Point2 Interpolate(int index, Point2 start, Point2 end, int count) // { // var x = LinearInterpolation.Interpolate(start.X, end.X, index, count); // var y = LinearInterpolation.Interpolate(start.Y, end.Y, index, count); // return new Point2(x, y); // } // public static Point3 Interpolate(int index, Point3 start, Point3 end, int count) // { // var x = LinearInterpolation.Interpolate(start.X, end.X, index, count); // var y = LinearInterpolation.Interpolate(start.Y, end.Y, index, count); // var z = LinearInterpolation.Interpolate(start.Z, end.Z, index, count); // return new Point3(x, y, z); // } //} public static IObservable <EyeData> FillInGaps(this IObservable <SingleEyeGazeData> eyeGazeData, TimeSpan maxGapDuration) { return(Observable.Create <EyeData>(o => { SingleEyeGazeData lastValidSample = null; int invalidSamplesCount = 0; return eyeGazeData.Subscribe(currentSample => { if (currentSample.Validity.HasEye()) { if (invalidSamplesCount > 0 && lastValidSample != null) { foreach (var interpolatedSample in Interpolate(lastValidSample, currentSample, invalidSamplesCount)) { o.OnNext(interpolatedSample); } invalidSamplesCount = 0; } lastValidSample = currentSample; o.OnNext(currentSample); } else { if (lastValidSample != null) { if (currentSample.Timestamp.Subtract(lastValidSample.Timestamp).Duration() <= maxGapDuration) { invalidSamplesCount++; } else { lastValidSample = null; while (invalidSamplesCount-- > 0) { o.OnNext(EyeData.Default); } invalidSamplesCount = 0; o.OnNext(currentSample); } } else { o.OnNext(currentSample); } } }, o.OnError, o.OnCompleted); })); }
private static EyeVelocity CalculateVelocity(SingleEyeGazeData sample, SingleEyeGazeData fromSample, SingleEyeGazeData toSample) { double velocity = 0; if (fromSample.Validity.HasEye() && toSample.Validity.HasEye() && sample.Validity.HasEye()) { double visualAngleDegrees = sample.GetVisualAngle(fromSample, toSample); if (Double.IsNaN(visualAngleDegrees) == false) { double durationSeconds = (toSample.Timestamp - fromSample.Timestamp).Duration().TotalSeconds; if (durationSeconds > 0d) { velocity = visualAngleDegrees / durationSeconds; } } } return(new EyeVelocity(velocity, sample)); }