public static double Distance(ICoordinates point1, ICoordinates point2) { return Coordinates.Sub(point2, point1).Module; }
internal static PointsAtDistanceSolution GetPointsAtDistance(Line2 first, Coordinates second, double distance) { //check that line is not too far if (Distance(second, first) > distance) { return new PointsAtDistanceSolution(SolutionType.None); } else { //check if point belong to line if (first.CheckPoint(second)) { return new PointsAtDistanceSolution(SolutionType.Specific, new List<Tuple<Coordinates, Coordinates>>() { new Tuple<Coordinates, Coordinates>(Coordinates.Add(second, first.Versor * distance), second), new Tuple<Coordinates, Coordinates>(Coordinates.Sub(second, first.Versor * distance), second) }); } else { Coordinates p1 = Coordinates.Zero; Coordinates p2 = Coordinates.Zero; if (first.B == 0) { double T1 = -first.C / first.A - second.X; double T2 = Math.Sqrt((distance - T1) * (distance + T1)); p1.X = -first.C / first.A; p1.Y = second.Y + T2; p2.X = -first.C / first.A; p2.Y = second.Y - T2; } else { double T1 = second.X + first.M * (second.Y - first.Q); double T2 = 1 + Math.Pow(first.M, 2); double T3 = Math.Sqrt(T2 * Math.Pow(distance, 2) - Math.Pow(first.M * second.X - second.Y + first.Q, 2)); p1.X = (T1 + T3) / T2; p1.Y = p1.X * first.M + first.Q; p2.X = (T1 - T3) / T2; p2.Y = p2.X * first.M + first.Q; } return new PointsAtDistanceSolution(SolutionType.Specific, new List<Tuple<Coordinates, Coordinates>>() { new Tuple<Coordinates, Coordinates>(p1, second), new Tuple<Coordinates, Coordinates>(p2, second) }); } } }