public Point GetShift(float[] cursor_position) { cache.ChangeCursorPosition(cursor_position); shift_storage.calibration_window?.OnCursorPositionUpdate(cursor_position); var closest_corrections = cache.ClosestPoints; if (closest_corrections == null) { Debug.Assert(shift_storage.Corrections.Count() == 0); return(new Point(0, 0)); } float sum_of_reverse_distances = 0; foreach (var index in closest_corrections) { sum_of_reverse_distances += (1 / index.distance); } ApplyShades(closest_corrections); foreach (var correction in closest_corrections) { correction.weight = correction.weight / correction.distance / sum_of_reverse_distances; } Helpers.NormalizeWeights(closest_corrections); var result = Helpers.GetWeightedAverage(shift_storage, closest_corrections); if (shift_storage.calibration_window != null) { var lables = new List <Tuple <string /*text*/, int /*correction index*/> >(); foreach (var correction in closest_corrections) { lables.Add(new Tuple <string, int>((int)(correction.weight * 100) + "%", correction.index)); } shift_storage.calibration_window.UpdateCorrectionsLables(lables); shift_storage.calibration_window.UpdateCurrentCorrection(new UserCorrection(cursor_position, result)); } return(result); }
public void AddShift(float[] cursor_position, Point shift) { if (!Helpers.AreCoordinatesSane(cursor_position)) { return; } cache.ChangeCursorPosition(cursor_position); var closest_shifts = cache.ClosestPoints; if (closest_shifts != null && closest_shifts[0].distance < calibration_mode.zone_size) { cache.FreeIndex(closest_shifts[0].index); Corrections.RemoveAt(closest_shifts[0].index); if (closest_shifts.Count > 1 && closest_shifts[1].distance < calibration_mode.zone_size) { Debug.Assert(closest_shifts[1].index != closest_shifts[0].index); if (closest_shifts[1].index > closest_shifts[0].index) { closest_shifts[1].index--; } cache.FreeIndex(closest_shifts[1].index); Corrections.RemoveAt(closest_shifts[1].index); } } else if (Corrections.Count >= calibration_mode.max_zones_count) { Debug.Assert(Corrections.Count == calibration_mode.max_zones_count); // Remove least recently used item from the front of |Corrections|. cache.FreeIndex(0); Corrections.RemoveAt(0); } if (cache.AllocateIndex() != Corrections.Count) { throw new Exception("Logic error"); } cache.SaveToCache(cursor_position, Corrections.Count); Corrections.Add(new EyeTrackerErrorCorrection(cursor_position, shift)); OnShiftsChanged(); }
public Point GetShift(float[] cursor_position) { cache.ChangeCursorPosition(cursor_position); shift_storage.calibration_window?.OnCursorPositionUpdate(cursor_position); var closest_corrections = cache.ClosestPoints; if (closest_corrections == null) { Debug.Assert(shift_storage.Corrections.Count() == 0); return(new Point(0, 0)); } float sum_of_reverse_distances = 0; foreach (var index in closest_corrections) { sum_of_reverse_distances += (1 / index.distance); } foreach (var correction in closest_corrections) { correction.weight = 1 / correction.distance / sum_of_reverse_distances; } var avg = Helpers.GetWeightedAverage(shift_storage, closest_corrections); ApplyShades(closest_corrections); foreach (var correction in closest_corrections) { correction.weight = correction.weight / correction.distance / sum_of_reverse_distances; } Helpers.NormalizeWeights(closest_corrections); Debug.Assert(calibration_mode.correction_fade_out_distance > 0); float total_weight = 0; foreach (var correction in closest_corrections) { var vector_from_correction_to_cursor = correction.vector_from_correction_to_cursor; float XYdistance = (float)Math.Sqrt( vector_from_correction_to_cursor[0] * vector_from_correction_to_cursor[0] + vector_from_correction_to_cursor[1] * vector_from_correction_to_cursor[1]); float factor = 1.0f - (float)Math.Pow( XYdistance / calibration_mode.correction_fade_out_distance, 2); correction.weight *= factor > 0 ? factor : 0; total_weight += correction.weight; } Debug.Assert(total_weight <= 1); var result = Helpers.GetWeightedAverage(shift_storage, closest_corrections); result.X = (int)(result.X + avg.X * (1 - total_weight)); result.Y = (int)(result.Y + avg.Y * (1 - total_weight)); if (shift_storage.calibration_window != null) { var lables = new List <Tuple <string /*text*/, int /*correction index*/> >(); foreach (var correction in closest_corrections) { lables.Add(new Tuple <string, int>((int)(correction.weight * 100) + "%", correction.index)); } shift_storage.calibration_window.UpdateCorrectionsLables(lables); shift_storage.calibration_window.UpdateCurrentCorrection(new UserCorrection(cursor_position, result)); } return(result); }