Exemplo n.º 1
0
        /// <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; // Возвращает индекс найденной точки.
        }
Exemplo n.º 2
0
        public static void RotatePoint(ref Point3d p, float angle)
        {
            var x = (float)(p.X * Math.Cos(angle) - p.Y * Math.Sin(angle)); // новая координата по х.
            var y = (float)(p.X * Math.Sin(angle) + p.Y * Math.Cos(angle)); // новая координата по у.

            p.X = x;
            p.Y = y;
        }
Exemplo n.º 3
0
 public static Point3d Normal(Point3d a, Point3d b)
 {
     return new Point3d
                      {
                          X = (a.Y*b.Z - b.Y*a.Z),
                          Y = (-(a.Z*b.Z - b.Z*a.Z)),
                          Z = (a.X*b.Y - b.X*a.Y)
                      };
 }
Exemplo n.º 4
0
 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);
 }
Exemplo n.º 5
0
 public static double Length(Point3d p1, Point3d p2)
 {
     return Math.Sqrt(Math.Pow(p1.X - p2.X, 2) + Math.Pow(p1.Y - p2.Y, 2));
 }
Exemplo n.º 6
0
 public static void Transform(ref Point3d p, float dx, float dy)
 {
     p.X -= dx;
     p.Y -= dy;
 }
Exemplo n.º 7
0
        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));
        }
Exemplo n.º 8
0
 public VecLine(Point3d start, Point3d end)
 {
     Start = start;
     End = end;
 }
Exemplo n.º 9
0
        /// <summary>
        /// Строит триангуляцию заданного набора точек.
        /// </summary>
        /// <param name="points"> Заданный набор точек. </param>
        /// <returns> Результат триангуляции. </returns>
        public Triangles Triangulation(List<Point3d> points)
        {
            var triangles = new Triangles();

            // Первоначальное задание точек P1, P2, P3.
            var p1 = new Point3d(points[0].X, points[0].Y, points[0].Z, 0);
            var p2 = new Point3d(points[1].X, points[1].Y, points[1].Z, 1);
            var p3 = new Point3d(points[0].X - 2, points[0].Y, 0, -1);

            // Создание стека.
            var stack = new Stack<Point3d>();

            // Помещаем точки в стек.
            stack.Push(p3);
            stack.Push(p2);
            stack.Push(p1);

            while (stack.Count > 0) // Пока стек не пуст.
            {
                // Снимаем точки со стека.
                p1 = stack.Pop();
                p2 = stack.Pop();
                p3 = stack.Pop();
                int index;

                // Получаем массив точек.
                var tempPoints = new List<Point3d>();
                for (int i = 0; i < points.Count; i++ )
                    tempPoints.Add(new Point3d(points[i]));

                // Начальная и конечная точки линии P1 P2
                Point3d tempPS;
                Point3d tempPE;

                if (p2 > p1)    // Конец должен быть дальше начала.
                {
                    tempPS = new Point3d(p1);
                    tempPE = new Point3d(p2);
                }
                else
                {
                    tempPS = new Point3d(p2);
                    tempPE = new Point3d(p1);
                }

                // Если точка с другой стороны прямой найдена, то про возваращается ее индекс > -1
                if ((index = MyMath.FindPointAcrossLine(new Point3d(p3),
                        new VecLine(new Point3d(tempPS), new Point3d(tempPE)), tempPoints)) > -1)
                    {
                        // Создаем триугольник с найднной точкой.
                        var tempTriangle = new Triangle(tempPE, tempPS, points[index]);
                        if (!triangles.ifHas(tempTriangle)) // Если в списке триугольников еще нет этого
                        {
                            // то добавляем его в списко триугольников
                            triangles.Add(new Triangle(tempPE, tempPS, points[index]));
                            // Добавляем вершины в стек.
                            stack.Push(p1);
                            stack.Push(points[index]);
                            stack.Push(p2);

                            stack.Push(p2);
                            stack.Push(points[index]);
                            stack.Push(p1);
                        }

                    }
            }
            triangles.SolveMaxMin(); // Рассчитывает максимальное и минимальное значение вершины Z.
            return triangles; // Возвращает список треугольников.
        }