/// <summary>
        /// Находит точку, лежащую с противоположной стороны линии, отностильно заданной точки.
        /// </summary>
        /// <param name="p"> Заданная точка. </param>
        /// <param name="vec"> Линия. </param>
        /// <param name="points"> Набор всех точек. </param>
        /// <returns> Индекс найденной точки. </returns>
        public static int FindPointAcrossLine(Point3d p, VecLine vec, List<Point3d> points)
        {
            MoveCenter(ref p, ref vec, ref points); // Смещает  центр координат.

            int indexMaxPoint = -1;
            float maxAngle = 0;

            // Проверка всех точек.
            for (int i = 0; i < points.Count; i++ )
            {
                if (points[i].Y * p.Y < 0)  // Если произведение меньше 0, то значит что точки лежат
                    // с разных сторон оси Х.
                {
                    var tempAngle = (float) SolveAngle(vec, points[i]); // Вычисляет угол.
                    if (maxAngle < tempAngle && tempAngle > 0.001)  // Если угол больше 0 и больше уже найденнго, то
                    {
                        maxAngle = tempAngle;   // Запоминает найденный угол.
                        indexMaxPoint = i;      // Запоминает индекс точки.
                    }
                    else if (indexMaxPoint >= 0)    // Если точка совпадает с началом или концом отрезка то берем ее.
                        if (maxAngle == tempAngle
                             && (points[i].Z == vec.Start.Z || points[i].Z == vec.End.Z))
                        {
                            indexMaxPoint = i;
                        }
                }
            }
            return indexMaxPoint; // Возвращает индекс найденной точки.
        }
 public static void MoveCenter(ref Point3d p, ref VecLine vec, ref List<Point3d> points)
 {
     float dx = vec.Start.X;
     float dy = vec.Start.Y;
     float angle = vec.Angle();
     Transform(ref p, dx, dy);
     Transform(ref vec, dx, dy);
     Transform(ref points, dx, dy);
     RotatePoint(ref p, -angle);
     RotatePoint(ref vec, -angle);
     RotatePoint(ref points, -angle);
 }
        public static void RotatePoint(ref VecLine vec, float angle)
        {
            var x = (float)(vec.Start.X * Math.Cos(angle) - vec.Start.Y * Math.Sin(angle)); // новая координата по х.
            var y = (float)(vec.Start.X * Math.Sin(angle) + vec.Start.Y * Math.Cos(angle)); // новая координата по у.

            vec.Start.X = x;
            vec.Start.Y = y;

            x = (float)(vec.End.X * Math.Cos(angle) - vec.End.Y * Math.Sin(angle)); // новая координата по х.
            y = (float)(vec.End.X * Math.Sin(angle) + vec.End.Y * Math.Cos(angle)); // новая координата по у.

            vec.End.X = x;
            vec.End.Y = y;
        }
        public static void Transform(ref VecLine vec, float dx, float dy)
        {
            vec.Start.X -= dx;
            vec.Start.Y -= dy;

            vec.End.X -= dx;
            vec.End.Y -= dy;
        }
        public static double SolveAngle(VecLine vec, Point3d p)
        {
            double a = Length(p, vec.Start);
            double b = Length(p, vec.End);

            return Math.Acos((Math.Pow(a, 2) + Math.Pow(b, 2) -
                              Math.Pow(vec.Length(), 2))/(2*a*b));
        }