/// <summary> /// Gets line ends near the point by radius. /// does not support large distances as it only gets a small number of grid cells /// </summary> /// <returns>a sorted array of lines where 0 is the closest point within the radius</returns> protected GameLine[] LineEndsInRadius(TrackReader trk, Vector2d point, double rad) { var lines = trk.GetLinesInRect(new DoubleRect(point - new Vector2d(24, 24), new Vector2d(24 * 2, 24 * 2)), false); SortedList <double, List <GameLine> > ret = new SortedList <double, List <GameLine> >(); foreach (var line in lines) { var p1 = (point - line.Position).Length; var p2 = (point - line.Position2).Length; var closer = Math.Min(p1, p2); if (closer - line.Width < rad) { if (ret.ContainsKey(closer)) { ret[closer].Add(line); } else { var l = new List <GameLine>(); l.Add(line); ret[closer] = l; } } } List <GameLine> retn = new List <GameLine>(); for (int i = 0; i < ret.Values.Count; i++) { retn.AddRange(ret.Values[i]); } return(retn.ToArray()); }
protected IEnumerable <GameLine> SelectLines(TrackReader trk, Vector2d position) { var ends = LineEndsInRadius(trk, position, SnapRadius); foreach (var line in ends) { yield return(line); } var zoom = game.Track.Zoom; var lines = trk.GetLinesInRect( new DoubleRect((Vector2d)position - new Vector2d(24, 24), new Vector2d(24 * 2, 24 * 2)), false); foreach (var line in lines) { if (ends.Contains(line)) { continue; } double lnradius = line.Width; var angle = Angle.FromLine(line.Position, line.Position2); var rect = Utility.GetThickLine( line.Position, line.Position2, angle, lnradius * 2); if (Utility.PointInRectangle(rect, position)) { yield return(line); } } yield break; }