public Point GetShift(float[] cursor_position)
        {
            if (cursor_position.Length != calibration_mode.additional_dimensions_configuration.CoordinatesCount)
            {
                return(new Point(0, 0));
            }

            var closest_corrections = shift_storage.GetClosestCorrections(cursor_position);

            if (closest_corrections == null)
            {
                Debug.Assert(shift_storage.Corrections.Count() == 0 || !Helpers.AreCoordinatesSane(cursor_position));
                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(closest_corrections);

            if (shift_storage.calibration_window != null)
            {
                var lables = new List <Tuple <string /*text*/, System.Windows.Point> >();
                foreach (var correction in closest_corrections)
                {
                    lables.Add(new Tuple <string, System.Windows.Point>((int)(correction.weight * 100) + "%",
                                                                        new System.Windows.Point(
                                                                            correction.correction.сoordinates[0],
                                                                            correction.correction.сoordinates[1])));
                }
                shift_storage.calibration_window.UpdateCorrectionsLables(lables);
                shift_storage.calibration_window.UpdateCurrentCorrection(new EyeTrackerErrorCorrection(cursor_position, result));
            }

            return(result);
        }
예제 #2
0
        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 Point GetShift(float[] cursor_position)
        {
            if (cursor_position.Length != calibration_mode.additional_dimensions_configuration.CoordinatesCount)
            {
                return(new Point(0, 0));
            }
            // |GetClosestCorrections| is computationaly heavy. We call it once and create copies for V0 and V1 parts of this function.
            List <ShiftsStorage.PointInfo> closest_corrections_v0 = new List <ShiftsStorage.PointInfo>(calibration_mode.considered_zones_count);
            List <ShiftsStorage.PointInfo> closest_corrections_v1 = new List <ShiftsStorage.PointInfo>(calibration_mode.considered_zones_count_v1);
            {
                var closest_corrections = shift_storage.GetClosestCorrections(cursor_position);
                if (closest_corrections == null || closest_corrections.Count() == 0)
                {
                    Debug.Assert(shift_storage.Corrections.Count() == 0 || !Helpers.AreCoordinatesSane(cursor_position));
                    return(new Point(0, 0));
                }
                for (int i = 0; i < closest_corrections.Count; i++)
                {
                    var correction = closest_corrections[i];
                    if (i < calibration_mode.considered_zones_count)
                    {
                        closest_corrections_v0.Add(new ShiftsStorage.PointInfo {
                            correction = correction.correction,
                            distance   = correction.distance,
                            weight     = correction.weight,
                            vector_from_correction_to_cursor = correction.vector_from_correction_to_cursor
                        });
                    }
                    if (i < calibration_mode.considered_zones_count_v1)
                    {
                        closest_corrections_v1.Add(new ShiftsStorage.PointInfo
                        {
                            correction = correction.correction,
                            distance   = correction.distance,
                            weight     = correction.weight,
                            vector_from_correction_to_cursor = correction.vector_from_correction_to_cursor
                        });
                    }
                }
            }
            // V0 part (average of closest error corrections weighted by distance):
            float sum_of_reverse_distances = 0;

            foreach (var index in closest_corrections_v0)
            {
                sum_of_reverse_distances += (1 / index.distance);
            }

            foreach (var correction in closest_corrections_v0)
            {
                correction.weight = 1 / correction.distance / sum_of_reverse_distances;
            }

            // V1 part (same as V0 plus shading)
            sum_of_reverse_distances = 0;
            foreach (var index in closest_corrections_v1)
            {
                sum_of_reverse_distances += (1 / index.distance);
            }
            ApplyShades(closest_corrections_v1);
            foreach (var correction in closest_corrections_v1)
            {
                correction.weight = correction.weight / correction.distance / sum_of_reverse_distances;
            }
            Helpers.NormalizeWeights(closest_corrections_v1);

            // Compute ratio of V0/V1 infuence on final result.
            Debug.Assert(calibration_mode.correction_fade_out_distance > 0);
            var   vector_from_correction_to_cursor = closest_corrections_v1[0].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]);
            // Longer the distance lower the factor.
            float v0_vs_v1_factor = 1.0f - (float)Math.Pow(
                XYdistance / calibration_mode.correction_fade_out_distance, 4);

            if (v0_vs_v1_factor < 0)
            {
                v0_vs_v1_factor = 0;
            }

            // Merge v0 and v1 to single set using the computed factor.
            List <ShiftsStorage.PointInfo> v1_v0_hybrid_corrections = new List <ShiftsStorage.PointInfo>();

            foreach (var correction in closest_corrections_v1)
            {
                correction.weight = v0_vs_v1_factor * correction.weight;
                v1_v0_hybrid_corrections.Add(correction);
            }

            foreach (var correction in closest_corrections_v0)
            {
                correction.weight = (1 - v0_vs_v1_factor) * correction.weight;
                int i = 0;
                for (; i < v1_v0_hybrid_corrections.Count; i++)
                {
                    if (correction.correction == v1_v0_hybrid_corrections[i].correction)
                    {
                        v1_v0_hybrid_corrections[i].weight += correction.weight;
                        break;
                    }
                }
                if (i == v1_v0_hybrid_corrections.Count)
                {
                    v1_v0_hybrid_corrections.Add(correction);
                }
            }

            var result = Helpers.GetWeightedAverage(v1_v0_hybrid_corrections);

            if (shift_storage.calibration_window != null)
            {
                var lables = new List <Tuple <string /*text*/, System.Windows.Point> >();
                foreach (var correction in v1_v0_hybrid_corrections)
                {
                    lables.Add(new Tuple <string, System.Windows.Point>((int)(correction.weight * 100) + "%",
                                                                        new System.Windows.Point(
                                                                            correction.correction.сoordinates[0],
                                                                            correction.correction.сoordinates[1])));
                }
                shift_storage.calibration_window.UpdateCorrectionsLables(lables);
                shift_storage.calibration_window.UpdateCurrentCorrection(new EyeTrackerErrorCorrection(cursor_position, result));
            }

            return(result);
        }
        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);
        }