protected Rect GetClosest(IEnumerable <Rect> rects, Rect rect, Vector direction) { // TODO Hack, offset the rect a little bit so there are not margin problems var rectFixed = new Rect(rect.Left - .1f, rect.Top - .1f, rect.Right + .1f, rect.Bottom + .1f); return(rects .Select(r => new { rect = r, Score = ComputeScore(direction, rectFixed, r) }) .OrderByDescending(a => a.Score) .FirstOrDefault(a => a.Score > 0)?.rect); }
private static double ComputeScore(Vector lookDirection, Rect original, Rect target) { var targetCenter = target.Center + target.Size.Multiply(lookDirection / 2); var originalCenter = original.Center + original.Size.Multiply(lookDirection / 2); var relativePosition = targetCenter - originalCenter; var distance = relativePosition.Length; var direction = relativePosition.Normalized(); var dot = lookDirection * direction; return(dot * (1 / distance)); }