/// <summary>
 /// Проверка на непересечение круга с множеством кругов.
 /// </summary>
 /// <param name="point">Вектор размещения круга.</param>
 /// <param name="circle">Круг.</param>
 /// <param name="circles">Множество кругов.</param>
 /// <param name="height">Значение допустимой погрешности. Положительное число.</param>
 /// <returns>Возвращает True, если круг не пересекается ни с одним кругом заданного множества. False - в противном случае.</returns>
 protected static bool IsCheckedCircles(Circle circle, Circle[] circles, int length, double eps)
 {
     for (int i = 0; i < length; i++)
         if (CircleExt.Расширенное_расстояние(circle, circles[i]) < -eps) // !!! Необходимо учитывать погрешность?
             return false;
     return true; ;
 }
Esempio n. 2
0
        public Placing(double height, double length, Circle[] circles, double mu, double beta, double eps)
            : base(height, length, circles, eps)
        {
            index_strip = 2 * circles.Length;

            X = new double[index_strip + 1];

            this.mu = mu;
            this.beta = beta;
        }
Esempio n. 3
0
        public PlacingOptWithCloseModel(double height, double length, Circle[] circles, Vertex<Geometric2d> vertex, double mu, double beta, double eps)
            : base(height, length, circles, mu, beta, eps)
        {
            this.vertex = vertex;
            this.triples = VertexExtention.GetTriples(vertex);

            for (int i = 0; i < circles.Length; i++)
                circles[i].ID = i;
        }
Esempio n. 4
0
 public PlacingOpt(double height, double length, Circle[] circles, double mu, double beta, double eps)
     : base(height, length, circles, mu, beta, eps)
 {
     #region Временный код.
     for (int i = 0; i < circles.Length; i++)
         if (circles[i].Value > 1)
             circles[i].Value -= 1;
     #endregion
 }
Esempio n. 5
0
 public static void SetCircleDelone(this Vertex<Geometric2d> vertex, Circle circle_delone)
 {
     vertex.Prev.Somes.CircleDelone = circle_delone;
     vertex.Somes.CircleDelone = circle_delone;
     vertex.Next.Somes.CircleDelone = circle_delone;
 }
Esempio n. 6
0
        public static List<System.Drawing.PointF> Отрезок(Vertex<Geometric2d> vertex)
        {
            List<System.Drawing.PointF> points = new List<System.Drawing.PointF>();
            double ed = CircleExt.Расширенное_расстояние(vertex.Somes.CircleDelone, vertex.Cros.Somes.CircleDelone) / 2;
            double k;
            int n = 100;
            Point2d point;
            Circle circle = new Circle { Pole = vertex.Somes.CircleDelone.Pole.Copy, Value = vertex.Somes.CircleDelone.Value + ed };
            Circle circle_cros = new Circle { Pole = vertex.Cros.Somes.CircleDelone.Pole.Copy, Value = vertex.Cros.Somes.CircleDelone.Value + ed };
            point = CircleExt.Точка_пересечения_границ(circle, circle_cros);
            if (point != null && !double.IsNaN(point.X) && !double.IsNaN(point.Y))
                points.Add(new System.Drawing.PointF((float)point.X, (float)point.Y));

            double ed_end;
            if (vertex.Prev.DataInVertex is Circle)
                ed_end = GeometricExt.Расширенное_расстояние(vertex.Somes.CircleDelone, (vertex.Prev.DataInVertex as Circle).Pole);
            else
                ed_end = 300; // TODO: Доделать!

            k = (ed_end - ed) / n;
            for (int i = 0; i < n; i++)
            {
                circle.Value += k;
                circle_cros.Value += k;
                point = CircleExt.Точка_пересечения_границ(circle, circle_cros);
                if (point != null && !double.IsNaN(point.X) && !double.IsNaN(point.Y))
                    points.Add(new System.Drawing.PointF((float)point.X, (float)point.Y));
            }

            points.Reverse();

            circle.Value = vertex.Somes.CircleDelone.Value + ed;
            circle_cros.Value = vertex.Cros.Somes.CircleDelone.Value + ed;

            if (vertex.Next.DataInVertex is Circle)
                ed_end = GeometricExt.Расширенное_расстояние(vertex.Somes.CircleDelone, (vertex.Next.DataInVertex as Circle).Pole) / 2;
            else
                ed_end = 300;

            k = (ed_end - ed) / n;
            for (int i = 0; i < n; i++)
            {
                circle.Value += k;
                circle_cros.Value += k;
                point = CircleExt.Точка_пересечения_границ(circle_cros, circle);
                if (point != null && !double.IsNaN(point.X) && !double.IsNaN(point.Y))
                    points.Add(new System.Drawing.PointF((float)point.X, (float)point.Y));
            }

            return points;
        }
Esempio n. 7
0
 public static Polygon2d Отрезок(Circle circle_this, Plane2d plane)
 {
     Polygon2d polygon = new Polygon2d();
     polygon.Add(circle_this.Pole - plane.Normal * circle_this.Value);
     polygon.Add(circle_this.Pole - plane.Normal * (circle_this.Value + PlaneExt.Расширенное_расстояние(plane, circle_this)));
     return polygon;
 }
Esempio n. 8
0
 public static Polygon2d Отрезок(Circle circle_this, Circle circle)
 {
     Polygon2d polygon = new Polygon2d();
     Vector2d vector = circle.Pole - circle_this.Pole;
     double length = Math.Sqrt(vector * vector);
     vector /= length;
     polygon.Add(circle_this.Pole + vector * circle_this.Value);
     polygon.Add(circle.Pole - vector * circle.Value);
     return polygon;
 }
        /// <summary>
        /// Поиск локального минимума с использованием метода последовательного одиночного размещения.
        /// </summary>
        protected override void Calculate()
        {
            #region Шаг 1. Метод последовательного одиночного размещения. Для каждого круга...
            for (int i = 0; i < circles.Length; i++)
            {
                #region Шаг 1.1. Создание списка точек возможных размещений и добавление двух начальных точек.
                List<Point2d> points = new List<Point2d>();
                points.Add(new Point2d { X = circles[i].Value, Y = circles[i].Value });
                points.Add(new Point2d { X = circles[i].Value, Y = height - circles[i].Value });
                #endregion
                #region Шаг 1.2. Создание и заполнение списка годографов.
                Circle[] godographs = new Circle[i];
                for (int j = 0; j < i; j++)
                    godographs[j] = CircleExt.Годограф_функции_плотного_размещения(circles[j], circles[i]);
                #endregion
                #region Шаг 1.3. Поиск точек пересечения круга с полосой.
                for (int j = 0; j < godographs.Length; j++)
                {
                    #region Шаг 1.3.1. Поиск точек пересечения круга с левой границей полосы.
                    if (godographs[j].Pole.X - godographs[j].Value < circles[i].Value)
                    {
                        double x = circles[i].Value - godographs[j].Pole.X;
                        double y = Math.Sqrt(godographs[j].Value * godographs[j].Value - x * x);
                        Point2d point;

                        point = new Point2d { X = circles[i].Value, Y = godographs[j].Pole.Y - y };
                        if (IsCheckedStrip(point, circles[i], height))
                            points.Add(point);

                        point = new Point2d { X = circles[i].Value, Y = godographs[j].Pole.Y + y };
                        if (IsCheckedStrip(point, circles[i], height))
                            points.Add(point);
                    }
                    #endregion
                    #region Шаг 1.3.2. Поиск точек пересечения круга с нижней границей полосы.
                    if (godographs[j].Pole.Y - godographs[j].Value < circles[i].Value)
                    {
                        double y = circles[i].Value - godographs[j].Pole.Y;
                        double x = Math.Sqrt(godographs[j].Value * godographs[j].Value - y * y);
                        Point2d point;

                        point = new Point2d { X = godographs[j].Pole.X - x, Y = circles[i].Value };
                        if (IsCheckedStrip(point, circles[i], height))
                            points.Add(point);

                        point = new Point2d { X = godographs[j].Pole.X + x, Y = circles[i].Value };
                        if (IsCheckedStrip(point, circles[i], height))
                            points.Add(point);
                    }
                    #endregion
                    #region Шаг 1.3.3. Поиск точек пересечения круга с верхней границей полосы.
                    if (godographs[j].Pole.Y + godographs[j].Value > height - circles[i].Value)
                    {
                        double y = height - circles[i].Value - godographs[j].Pole.Y;
                        double x = Math.Sqrt(godographs[j].Value * godographs[j].Value - y * y);
                        Point2d point;

                        point = new Point2d { X = godographs[j].Pole.X - x, Y = height - circles[i].Value };
                        if (IsCheckedStrip(point, circles[i], height))
                            points.Add(point);
                        point = new Point2d { X = godographs[j].Pole.X + x, Y = height - circles[i].Value };
                        if (IsCheckedStrip(point, circles[i], height))
                            points.Add(point);
                    }
                    #endregion
                }
                #endregion
                #region Шаг 1.4. Поиск точек пересечения годографов.
                for (int j = 0; j < godographs.Length - 1; j++)
                    for (int k = j + 1; k < godographs.Length; k++)
                    {
                        Point2d point;

                        point = CircleExt.Точка_пересечения_границ(godographs[j], godographs[k]);
                        if (point != null && IsCheckedStrip(point, circles[i], height))
                            points.Add(point); // Заменить на "Добавить в отсортированный набор данных". Лучше всего использовать бинарное взвешенное дерево.

                        point = CircleExt.Точка_пересечения_границ(godographs[k], godographs[j]);
                        if (point != null && IsCheckedStrip(point, circles[i], height))
                            points.Add(point); // Заменить на "Добавить в отсортированный набор данных". Лучше всего использовать бинарное взвешенное дерево.
                    }
                #endregion
                #region Шаг 1.5. Сортировка набора точек возможного размещения.!!! Данная часть не нужна, если использовать сортировку при вставке точек в набор данных.
                for (int j = 0; j < points.Count - 1; j++)
                    for (int k = j + 1; k < points.Count; k++)
                        if (points[j].X > points[k].X || (points[j].X == points[k].X && points[j].Y > points[k].Y))
                        {
                            Point2d temp_point = points[j];
                            points[j] = points[k];
                            points[k] = temp_point;
                        }
                #endregion
                #region Шаг 1.6. Выбор наилучшей точки размещения, при которой не возникает пересечение кругов и размещение круга.
                int p = -1;
                do
                {
                    p++;
                    circles[i].Pole.Copy = points[p];
                } while (!IsCheckedCircles(circles[i], circles, i, eps));
                #endregion
                #region Шаг 1.7. Пересчёт ширины занятой части полосы.
                length = Math.Max(length, circles[i].Pole.X + circles[i].Value);
                #endregion
            }
            #endregion
        }
 /// <summary>
 /// Проверка на попадание круга в полосу.
 /// </summary>
 /// <param name="point">Вектор размещения круга.</param>
 /// <param name="circle">Круг.</param>
 /// <param name="height">Высота полосы.</param>
 /// <returns>Возвращает True, если круг полностью лежит внутри полосы. False - в противном случае.</returns>
 protected bool IsCheckedStrip(Point2d point, Circle circle, double height)
 {
     return (point.Y + circle.Value <= height) && (point.X - circle.Value >= 0) && (point.Y - circle.Value >= 0); //!!! Необходимо учитывать погрешность.
 }
 private bool Существует_точка_плотного_размещения_второго_рода(Circle circle, Vertex<Geometric2d> vertex)
 {
     if (circle.Value > vertex.Somes.CircleDelone.Value)
         return false;
     else
         if (circle.Value >= vertex.Cros.Somes.CircleDelone.Value)
             return true;
         else
             if (Функция_расширенного_расстояния_на_отрезке_монотонна(vertex)) // Придумать что-то другое?
                 return false;
             else
                 return 2 * circle.Value >= GeometricExt.Расширенное_расстояние(vertex.Prev.DataInVertex, vertex.Next.DataInVertex);
 }
        public PlacingWithCloseModel(double height, Circle[] circles, double eps)
            : base(height, 0, circles, eps)
        {
            length = 2 * height;

            #region Шаг 1. Создаём начальную модель, состоящую из сторон прямоугольника. !!!Потом переделать на полосу!!!
            Geometric2d border_1 = new Plane2d { ID = -1, Pole = new Point2d { X = 0, Y = 2 * height / 2 }, Normal = new Vector2d { X = 0, Y = -1 } };
            Geometric2d border_2 = new Plane2d { ID = -2, Pole = new Point2d { X = 0, Y = 1 * height / 2 }, Normal = new Vector2d { X = 1, Y = 0 } };
            Geometric2d border_3 = new Plane2d { ID = -3, Pole = new Point2d { X = 0, Y = 0 * height / 2 }, Normal = new Vector2d { X = 0, Y = +1 } };

            Geometric2d border_4 = new Plane2d { ID = -4, Pole = new Point2d { X = length, Y = height / 2 }, Normal = new Vector2d { X = -1, Y = 0 } };

            vertex = Vertex<Geometric2d>.CreateClosenessModel(border_1, border_2, border_3);
            vertex.BreakCrosBy(border_4);
            #endregion

            #region Шаг 2. Устанавливаем для полученных троек круги Делоне. !Для полосы можно не автоматизировать. Для многоугольника необходимо придумать автоматизацию.
            vertex.SetCircleDelone(new Circle { Pole = new Point2d { X = height / 2, Y = height / 2 }, Value = height / 2 });
            vertex.Cros.SetCircleDelone(new Circle { Pole = new Point2d { X = length - height / 2, Y = height / 2 }, Value = height / 2 });

            vertex.Prev.Cros.SetCircleDelone(new Circle { Pole = new Point2d { X = -height / 2, Y = height / 2 }, Value = 0 });
            vertex.Cros.Prev.Cros.SetCircleDelone(new Circle { Pole = new Point2d { X = double.PositiveInfinity /*length + height / 2*/, Y = height / 2 }, Value = 0 });
            #endregion

            length = 0;

            triples = vertex.GetTriples();

            vertex = vertex.Cros;
        }
 public Placing(double height, Circle[] circles, double eps)
     : base(height, 0, circles, eps)
 {
 }
Esempio n. 14
0
 /// <summary>
 /// Проверка на непересечение круга с множеством кругов.
 /// </summary>
 /// <param name="point">Вектор размещения круга.</param>
 /// <param name="circle">Круг.</param>
 /// <param name="circles">Множество кругов.</param>
 /// <param name="height">Значение допустимой погрешности. Положительное число.</param>
 /// <returns>Возвращает True, если круг не пересекается ни с одним кругом заданного множества. False - в противном случае.</returns>
 public static bool IsCheckedCircles(Circle circle, List<Circle> circles, double eps)
 {
     for (int i = 0; i < circles.Count; i++)
         if (CircleExt.Расширенное_расстояние(circle, circles[i]) < -eps) // !!! Необходимо учитывать погрешность?
             return false;
     return true; ;
 }