protected GameLine SelectLine(TrackWriter trk, Vector2d position, out bool knob) { knob = false; var zoom = game.Track.Zoom; var ends = LineEndsInRadius(trk, position, SnapRadius); if (ends.Length > 0) { knob = true; return(ends[0]); } var lines = trk.GetLinesInRect( new DoubleRect((Vector2d)position - new Vector2d(24, 24), new Vector2d(24 * 2, 24 * 2)), false); foreach (var line in lines) { 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)) { return(line); } } return(null); }
/// <summary> /// Gets lines 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</returns> public GameLine[] LinesInRadius(TrackWriter trk, Vector2d position, double rad) { SortedList <int, GameLine> lines = new SortedList <int, GameLine>(); var inrect = trk.GetLinesInRect(new DoubleRect(position - new Vector2d(24, 24), new Vector2d(24 * 2, 24 * 2)), false); var circle = Rendering.StaticRenderer.GenerateCircle(position.X, position.Y, rad, 8); var ends = LineEndsInRadius(trk, position, rad); foreach (var line in ends) { lines[line.ID] = line; } foreach (var line in inrect) { if (lines.ContainsKey(line.ID)) { continue; } var angle = Angle.FromLine(line.Position, line.Position2); var rect = Utility.GetThickLine( line.Position, line.Position2, angle, line.Width * 2); if (Utility.PointInRectangle(rect, position)) { lines.Add(line.ID, line); continue; } else { for (int i = 0; i < circle.Length; i++) { if (Utility.PointInRectangle(rect, circle[i])) { lines.Add(line.ID, line); break; } } } } GameLine[] ret = new GameLine[lines.Count]; for (int i = 0; i < ret.Length; i++) { ret[i] = lines.Values[(lines.Count - 1) - i]; } return(lines.Values.ToArray()); }