protected MSCompactErrorShortcutSet FindShortcutsInDirection(MSShortcutChecker checker, bool forward) { var input = checker.Input; var output = checker.Output; checker.Forward = forward; var trajectory = input.Trajectory; var shortcuts = new MSCompactErrorShortcutSet(input, ShortcutSetFactory); output.LogLine("Starting calculations of shortcuts, " + (forward ? "forward" : "backwards")); Func <int, int> step; int startI; Func <int, bool> conditionI; Func <int, bool> conditionJ; if (forward) { step = i => i + 1; startI = 0; conditionI = i => i < trajectory.Count - 2; conditionJ = j => j < trajectory.Count; } else { step = i => i - 1; startI = trajectory.Count - 1; conditionI = i => i >= 2; conditionJ = j => j >= 0; } TPoint2D intervalLimit = null; LinkedListNode <TPoint2D> intervalLimitNode = null; if (input.SearchIntervals != null) { intervalLimitNode = forward ? input.SearchIntervals.First.Next : input.SearchIntervals.Last.Previous; intervalLimit = intervalLimitNode.Value; } var shortcutStartsHandled = 0; for (var i = startI; conditionI(i); i = step(i)) { var pointI = trajectory[i]; if (input.PrunedPoints.Contains(pointI)) { continue; } if (input.SearchIntervals != null) { if (intervalLimit.Index == pointI.Index) { intervalLimitNode = forward ? intervalLimitNode.Next : intervalLimitNode.Previous; intervalLimit = intervalLimitNode.Value; } } checker.OnNewShortcutStart(pointI); for (var j = step(i); conditionJ(j); j = step(j)) { var pointJ = trajectory[j]; if (input.SearchIntervals != null) { if (forward && pointJ.Index > intervalLimit.Index || !forward && pointJ.Index < intervalLimit.Index) { break; } } checker.BeforeShortcut(pointI, pointJ); //only continue when considering real shortcuts if (Math.Abs(j - i) > 1 && !input.PrunedPoints.Contains(pointJ)) { checker.BeforeShortcutValidation(pointI, pointJ); var start = forward ? pointI : pointJ; var end = forward ? pointJ : pointI; var shortcut = new Shortcut(start, end); var maxError = checker.GetMaxError(pointI, pointJ); shortcuts.Add(shortcut, maxError); } if (!checker.AfterShortcut(pointI, pointJ)) { break; } } shortcutStartsHandled++; if (shortcutStartsHandled >= trajectory.Count / 100) { var progress = forward ? i : trajectory.Count - i; output.LogLine("Shortcuts handled: " + progress * 100 / trajectory.Count + "%"); shortcutStartsHandled = 0; } } return(shortcuts); }
private MSSimpleShortcutSet FindShortcutsInDirection(MSShortcutChecker checker, bool forward) { var input = checker.Input; var trajectory = input.Trajectory; checker.Forward = forward; var shortcutSet = new MSSimpleShortcutSet(input, ShortcutSetFactory); Func <int, int> step; int startI; Func <int, bool> conditionI; Func <int, bool> conditionJ; if (forward) { step = i => i + 1; startI = 0; conditionI = i => i < trajectory.Count - 2; conditionJ = j => j < trajectory.Count; } else { step = i => i - 1; startI = trajectory.Count - 1; conditionI = i => i >= 2; conditionJ = j => j >= 0; } TPoint2D intervalLimit = null; LinkedListNode <TPoint2D> intervalLimitNode = null; if (input.SearchIntervals != null) { intervalLimitNode = forward ? input.SearchIntervals.First.Next : input.SearchIntervals.Last.Previous; intervalLimit = intervalLimitNode.Value; } var shortcutStartsHandled = 0; for (var i = startI; conditionI(i); i = step(i)) { var pointI = trajectory[i]; if (input.PrunedPoints.Contains(pointI)) { continue; } if (input.SearchIntervals != null) { if (intervalLimit.Index == pointI.Index) { intervalLimitNode = forward ? intervalLimitNode.Next : intervalLimitNode.Previous; intervalLimit = intervalLimitNode.Value; } } checker.OnNewShortcutStart(pointI); for (var j = step(i); conditionJ(j); j = step(j)) { var pointJ = trajectory[j]; if (input.SearchIntervals != null) { if (forward && pointJ.Index > intervalLimit.Index || !forward && pointJ.Index < intervalLimit.Index) { break; } } checker.BeforeShortcut(pointI, pointJ); if (Math.Abs(j - i) > 1 && !input.PrunedPoints.Contains(pointJ)) { checker.BeforeShortcutValidation(pointI, pointJ); var shortcutValid = false; for (var level = 1; level <= input.NumLevels; level++) { if (!shortcutValid) { shortcutValid = checker.ShortcutValid(level, pointI, pointJ); } if (!shortcutValid) { continue; } var start = forward ? pointI : pointJ; var end = forward ? pointJ : pointI; if (forward) { shortcutSet.Shortcuts[level].AppendShortcut(start, end); } else { shortcutSet.Shortcuts[level].PrependShortcut(start, end); } } } if (!checker.AfterShortcut(pointI, pointJ)) { break; } } shortcutStartsHandled++; if (shortcutStartsHandled >= trajectory.Count / 100) { var progress = forward ? i : trajectory.Count - i; //System.Diagnostics.Debug.WriteLine("Shortcuts handled: " + progress * 100 / trajectory.Count + "%"); checker.Output.LogLine("Shortcuts handled: " + progress * 100 / trajectory.Count + "%"); shortcutStartsHandled = 0; } } return(shortcutSet); }