public void addPosition(TimeSpan time, Offset position) { _index += 1; if (_index == _historySize) { _index = 0; } _samples[_index] = new _PointAtTime(position, time); }
public VelocityEstimate getVelocityEstimate() { List <float> x = new List <float>(); List <float> y = new List <float>(); List <float> w = new List <float>(); List <float> time = new List <float>(); int sampleCount = 0; int index = _index; _PointAtTime newestSample = _samples[index]; if (newestSample == null) { return(null); } _PointAtTime previousSample = newestSample; _PointAtTime oldestSample = newestSample; do { _PointAtTime sample = _samples[index]; if (sample == null) { break; } float age = (float)(newestSample.time - sample.time).TotalMilliseconds; float delta = Mathf.Abs((float)(sample.time - previousSample.time).TotalMilliseconds); previousSample = sample; if (age > _horizonMilliseconds || delta > _assumePointerMoveStoppedMilliseconds) { break; } oldestSample = sample; Offset position = sample.point; x.Add(position.dx); y.Add(position.dy); w.Add(1.0f); time.Add(-age); index = (index == 0 ? _historySize : index) - 1; sampleCount += 1; } while (sampleCount < _historySize); if (sampleCount >= _minSampleSize) { LeastSquaresSolver xSolver = new LeastSquaresSolver(time, x, w); PolynomialFit xFit = xSolver.solve(2); if (xFit != null) { LeastSquaresSolver ySolver = new LeastSquaresSolver(time, y, w); PolynomialFit yFit = ySolver.solve(2); if (yFit != null) { return(new VelocityEstimate( pixelsPerSecond: new Offset(xFit.coefficients[1] * 1000, yFit.coefficients[1] * 1000), confidence: xFit.confidence *yFit.confidence, duration: newestSample.time - oldestSample.time, offset: newestSample.point - oldestSample.point )); } } } return(new VelocityEstimate( pixelsPerSecond: Offset.zero, confidence: 1.0f, duration: newestSample.time - oldestSample.time, offset: newestSample.point - oldestSample.point )); }