예제 #1
0
 internal static PointsAtDistanceSolution GetPointsAtDistance(Line2 first, Line2 second, double distance)
 {
     //check if parallel lines
     if (IsParallel(first, second))
     {
         //only two possible solutions:
         //  - parallel lines are at the correct distance => any points is a solution
         //  - parallel lines are not at the correct distance => no solutions
         if (Distance(first, second) == distance)
         {
             return new PointsAtDistanceSolution(SolutionType.Any);
         }
         else
         {
             return new PointsAtDistanceSolution(SolutionType.None);
         }
     }
     else
     {
         var results = new List<Tuple<Coordinates, Coordinates>>();
         Coordinates p11 = Coordinates.Zero;
         Coordinates p12 = Coordinates.Zero;
         Coordinates p21 = Coordinates.Zero;
         Coordinates p22 = Coordinates.Zero;
         if (first.B == 0)
         {
             double T1 = -first.C / first.A * second.M + second.Q;
             double T2 = Math.Sqrt(1 + Math.Pow(second.M, 2));
             p11.X = -first.C / first.A;
             p11.Y = T1 - distance * T2;
             p12.X = -first.C / first.A;
             p12.Y = T1 + distance * T2;
             p21.X = (-second.M * second.Q + second.M * p11.Y + p11.X) / Math.Pow(T2, 2);
             p21.Y = second.M * p21.X + second.Q;
             p22.X = (-second.M * second.Q + second.M * p12.Y + p12.X) / Math.Pow(T2, 2);
             p22.Y = second.M * p22.X + second.Q;
         }
         else if (second.B == 0)
         {
             p11.X = -second.C / second.A - distance;
             p11.Y = first.M * p11.X + first.Q;
             p12.X = -second.C / second.A + distance;
             p12.Y = first.M * p12.X + first.Q;
             p21.X = -second.C / second.A;
             p21.Y = p11.Y;
             p22.X = -second.C / second.A;
             p22.Y = p12.Y;
         }
         else
         {
             double T1 = second.Q - first.Q;
             double T2 = second.M - first.M;
             double T3 = Math.Sqrt(1 + Math.Pow(second.M, 2));
             p11.X = (-T1 + distance * T3) / T2;
             p11.Y = first.M * p11.X + first.Q;
             p12.X = (-T1 - distance * T3) / T2;
             p12.Y = first.M * p12.X + first.Q;
             p21.X = (-second.M * second.Q + second.M * p11.Y + p11.X) / Math.Pow(T3, 2);
             p21.Y = second.M * p21.X + second.Q;
             p22.X = (-second.M * second.Q + second.M * p12.Y + p12.X) / Math.Pow(T3, 2);
             p22.Y = second.M * p22.X + second.Q;
         }
         return new PointsAtDistanceSolution(SolutionType.Specific, new List<Tuple<Coordinates, Coordinates>>() { new Tuple<Coordinates, Coordinates>(p11, p21), new Tuple<Coordinates, Coordinates>(p12, p22) });
     }
 }
예제 #2
0
 public static double Distance(ICoordinates point1, ICoordinates point2)
 {
     return Coordinates.Sub(point2, point1).Module;
 }
예제 #3
0
 internal static bool IsParallel(Coordinates first, Coordinates second)
 {
     return first.Phase == second.Phase || first.Phase == (second.Phase + 180);
 }
예제 #4
0
 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) });
         }
     }
 }
예제 #5
0
 internal static double Distance(Coordinates point, Line2 line)
 {
     return Math.Abs(point.X * line.A + point.Y * line.B + line.C) / Math.Sqrt(Math.Pow(line.A, 2) + Math.Pow(line.B, 2));
 }
예제 #6
0
 public static Coordinates Normalize(Coordinates vector)
 {
     return(new Coordinates(module: 1, phase: vector.Phase));
 }
예제 #7
0
 public static Coordinates Cross(Coordinates right, Coordinates left)
 {
     return(new Coordinates(x: right.X *left.Y, y: right.Y *left.X));
 }
예제 #8
0
 public static double Dot(Coordinates right, Coordinates left)
 {
     return(right.X * left.X + right.Y * left.Y);
 }
예제 #9
0
 public static Coordinates MakeReadonly(Coordinates vector)
 {
     vector.m_IsReadonly = true;
     return(vector);
 }