/// <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 (Circle2dExt.Расширенное_расстояние(circle, circles[i]) < -eps) // !!! Необходимо учитывать погрешность?
             return false;
     return true; ;
 }
        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;
        }
Example #3
0
        /// <summary>
        /// Получить точку пересечения границ круга и круга.
        /// </summary>
        /// <param name="circle_prev">Круг.</param>
        /// <param name="circle_next">Круг.</param>
        /// <returns>Точка пересечения (одна из двух).</returns>
        public static Point2d Точка_пересечения_границ(Geometric2dWithPointScalar circle_prev, Geometric2dWithPointScalar circle_next)
        {
            Vector2d vector = circle_next.Pole - circle_prev.Pole;
            Vector2d vector_ = vector._I_(false);
            double vector_vector = vector * vector;

            double pr = circle_prev.Scalar * circle_prev.Scalar / vector_vector;
            double nr = circle_next.Scalar * circle_next.Scalar / vector_vector;

            double vector_length = -(nr - pr - 1) / 2;
            double vector_length_ = Math.Sqrt(pr - vector_length * vector_length);

            return circle_prev.Pole + vector * vector_length + vector_ * vector_length_;
        }
Example #4
0
        /// <summary>
        /// Получить точку пересечения границ круга и полуплоскости.
        /// </summary>
        /// <param name="circle_prev">Круг.</param>
        /// <param name="plane_next">Полуплоскость.</param>
        /// <returns>Точка пересечения.</returns>
        public static Point2d Точка_пересечения_границ(Geometric2dWithPointScalar circle_prev, Plane2d plane_next)
        {
            Vector2d vector_prev = plane_next.Normal._I_(false);
            Vector2d vector = plane_next.Pole - circle_prev.Pole;

            double b = vector_prev * vector;
            double c = vector * vector - circle_prev.Scalar * circle_prev.Scalar;
            double d = b * b - c;
            if (d < 0)
                return null;
            else
            {
                double t = -b - Math.Sqrt(d);
                return plane_next.Pole + vector_prev * t;
            }
        }
Example #5
0
        private bool PointInTriple(Circle circle, Vertex<Geometric> vertex)
        {
            if (vertex.Somes.CircleDelone == null)
                return false;

            double ed = Circle2dExt.Расширенное_расстояние(circle, vertex.Somes.CircleDelone);
            bool point_in_triple = ed < 0;
            if (point_in_triple)
            {
                Vertex<Geometric> vertex_temp = vertex;
                do
                {
                    point_in_triple = point_in_triple && Circle2dExt.Расширенное_расстояние(circle, vertex_temp.Cros.Somes.CircleDelone) > ed;

                    vertex_temp = vertex_temp.Next;
                } while (vertex_temp != vertex);
            }
            return point_in_triple;
        }
Example #6
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;
 }
Example #7
0
 /// <summary>
 /// Получить точку близости второго рода для круга и множества (круг, круг).
 /// </summary>
 /// <param name="circle_this">Круг.</param>
 /// <param name="circle_prev">Круг.</param>
 /// <param name="circle_next">Круг.</param>
 /// <returns>Точка близости (одна из двух).</returns>
 public static Point2d Точка_близости_второго_рода(this Geometric2dWithPointScalar circle_this, Geometric2dWithPointScalar circle_prev, Geometric2dWithPointScalar circle_next)
 {
     return Точка_пересечения_границ(Годограф_функции_плотного_размещения(circle_prev, circle_this), Годограф_функции_плотного_размещения(circle_next, circle_this));
 }
Example #8
0
 public static Polygon2d Отрезок(Circle circle_this, Plane2d plane)
 {
     Polygon2d polygon = new Polygon2d();
     polygon.Add(circle_this.Pole - plane.Normal * circle_this.Scalar);
     polygon.Add(circle_this.Pole - plane.Normal * (circle_this.Scalar + Plane2dExt.Расширенное_расстояние(plane, circle_this)));
     return polygon;
 }
Example #9
0
        public static List<System.Drawing.PointF> Отрезок(Vertex<Geometric2d> vertex)
        {
            List<System.Drawing.PointF> points = new List<System.Drawing.PointF>();
            double ed = Circle2dExt.Расширенное_расстояние(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, Scalar = vertex.Somes.CircleDelone.Scalar + ed };
            Circle circle_cros = new Circle { Pole = vertex.Cros.Somes.CircleDelone.Pole.Copy, Scalar = vertex.Cros.Somes.CircleDelone.Scalar + ed };
            point = Circle2dExt.Точка_пересечения_границ(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 = Geometric2dExt.Расширенное_расстояние(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.Scalar += k;
                circle_cros.Scalar += k;
                point = Circle2dExt.Точка_пересечения_границ(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.Scalar = vertex.Somes.CircleDelone.Scalar + ed;
            circle_cros.Scalar = vertex.Cros.Somes.CircleDelone.Scalar + ed;

            if (vertex.Next.DataInVertex is Circle)
                ed_end = Geometric2dExt.Расширенное_расстояние(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.Scalar += k;
                circle_cros.Scalar += k;
                point = Circle2dExt.Точка_пересечения_границ(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;
        }
Example #10
0
 /// <summary>
 /// Получить серединную полуплоскость круга и круга.
 /// </summary>
 /// <param name="circle_prev">Круг.</param>
 /// <param name="circle_next">Круг.</param>
 /// <returns>Серединная полуплоскость.</returns>
 public static Plane2d Серединная_полуплоскость(Geometric2dWithPointScalar circle_prev, Geometric2dWithPointScalar circle_next)
 {
     return new Plane2d { Pole = circle_prev.Pole.Copy, Normal = (circle_next.Pole - circle_prev.Pole)._I_(false) };
 }
Example #11
0
 public static void FillAndDraw(this Graphics graphics, Brush brush, Pen pen, Geometric2dWithPointScalar circle)
 {
     graphics.FillEllipse(brush, circle.ToRectangleF());
     graphics.DrawEllipse(pen, circle.ToRectangleF());
 }
 public Placing(double height, Circle[] circles, double eps)
     : base(height, 0, circles, eps)
 {
 }
 private bool Существует_точка_плотного_размещения_второго_рода(Circle circle, Vertex<Geometric2d> vertex)
 {
     if (circle.Scalar > vertex.Somes.CircleDelone.Scalar)
         return false;
     else
         if (circle.Scalar >= vertex.Cros.Somes.CircleDelone.Scalar)
             return true;
         else
             if (Функция_расширенного_расстояния_на_отрезке_монотонна(vertex)) // Придумать что-то другое?
                 return false;
             else
                 return 2 * circle.Scalar >= Geometric2dExt.Расширенное_расстояние(vertex.Prev.DataInVertex, vertex.Next.DataInVertex);
 }
Example #14
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
 }
Example #15
0
 /// <summary>
 /// Получить серединную полуплоскость круга и полуплоскости.
 /// </summary>
 /// <param name="circle_prev">Круг.</param>
 /// <param name="plane_next">Полуплоскость.</param>
 /// <returns>Серединная полуплоскость.</returns>
 public static Plane2d Серединная_полуплоскость(Geometric2dWithPointScalar circle_prev, Plane2d plane_next)
 {
     return new Plane2d { Pole = circle_prev.Pole.Copy, Normal = plane_next.Normal._I_(true) };
 }
Example #16
0
 /// <summary>
 /// Получить расширенное расстояние от круга до точки.
 /// </summary>
 /// <param name="circle_this">Круг.</param>
 /// <param name="point">Точка.</param>
 /// <returns>Расширенное расстояние.</returns>
 public static double Расширенное_расстояние(Geometric2dWithPointScalar circle_this, Point2d point)
 {
     return Point2dExt.Расширенное_расстояние(circle_this.Pole, point) - circle_this.Scalar;
 }
Example #17
0
 /// <summary>
 /// Получить годограф функции плотного размещения круга возле круга.
 /// </summary>
 /// <param name="circle_this">Круг.</param>
 /// <param name="circle">Круг.</param>
 /// <returns>Годограф функции плотного размещения.</returns>
 public static Geometric2dWithPointScalar Годограф_функции_плотного_размещения(Geometric2dWithPointScalar circle_this, Geometric2dWithPointScalar circle)
 {
     return new Geometric2dWithPointScalar { Pole = circle_this.Pole.Copy, Scalar = circle_this.Scalar + circle.Scalar };
 }
Example #18
0
 /// <summary>
 /// Получить расширенное расстояние от круга до круга.
 /// </summary>
 /// <param name="circle_this">Круг.</param>
 /// <param name="circle">Круг.</param>
 /// <returns>Расширенное расстояние.</returns>
 public static double Расширенное_расстояние(Geometric2dWithPointScalar circle_this, Geometric2dWithPointScalar circle)
 {
     return Расширенное_расстояние(circle_this, circle.Pole) - circle.Scalar;
 }
Example #19
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;
        }
Example #20
0
        public static List<System.Drawing.PointF> Отрезок(Vertex<Geometric> vertex)
        {
            List<System.Drawing.PointF> points = new List<System.Drawing.PointF>();
            double ed = Circle2dExt.Расширенное_расстояние(vertex.Somes.CircleDelone, vertex.Cros.Somes.CircleDelone) / 2;
            double k = 0.1;
            Point2d point;
            Circle circle = new Circle { Pole = vertex.Somes.CircleDelone.Pole.Copy, Scalar = vertex.Somes.CircleDelone.Scalar + ed };
            Circle circle_cros = new Circle { Pole = vertex.Cros.Somes.CircleDelone.Pole.Copy, Scalar = vertex.Cros.Somes.CircleDelone.Scalar + ed };
            do
            {
                circle.Scalar += k;
                circle_cros.Scalar += k;
                point = Circle2dExt.Точка_пересечения_границ(circle, circle_cros);
                if (point != null)
                    points.Add(new System.Drawing.PointF((float)point.X, (float)point.Y));
            } while (Geometric2dExt.Расширенное_расстояние(vertex.Prev.DataInVertex as Geometric2d, point) > 0 && points.Count < 10000);

            circle.Scalar = vertex.Somes.CircleDelone.Scalar + ed;
            circle_cros.Scalar = vertex.Cros.Somes.CircleDelone.Scalar + ed;
            do
            {
                circle.Scalar += k;
                circle_cros.Scalar += k;
                point = Circle2dExt.Точка_пересечения_границ(circle_cros, circle);
                if (point != null)
                    points.Insert(0, new System.Drawing.PointF((float)point.X, (float)point.Y));
            } while (Geometric2dExt.Расширенное_расстояние(vertex.Next.DataInVertex as Geometric2d, point) > 0 && points.Count < 10000);

            return points;
        }
        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 }, Scalar = height / 2 });
            vertex.Cros.SetCircleDelone(new Circle { Pole = new Point2d { X = length - height / 2, Y = height / 2 }, Scalar = height / 2 });

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

            length = 0;

            vertex = vertex.Cros.Next.Cros.Next;

            triples = vertex.GetTriples();
        }
Example #22
0
        private void MainForm_MouseDown(object sender, MouseEventArgs e)
        {
            for (int index = 0; index < 10; ++index)
            {
                Vertex<Geometric> vertex = null;
                Vertex<Geometric> vertex_temp;

                #region Заполнение круга.
                //Circle circle = new Circle() { Pole = new Point2d { X = e.X, Y = e.Y } };
                Circle circle = new Circle() { Pole = new Point2d { X = this.rand.Next(10, this.ClientSize.Width - 10), Y = this.rand.Next(10, this.ClientSize.Height - 10) } };

                int k = -1;
                for (int i = 0; i < triples.Count && k == -1; i++)
                    if (PointInTriple(circle, triples[i]))
                        k = i;
                if (k > -1)
                {
                    vertex = triples[k];

                    double radius_max = double.PositiveInfinity;

                    vertex_temp = vertex;
                    do
                    {
                        radius_max = Math.Min(Geometric2dExt.Расширенное_расстояние(circle, vertex_temp.DataInVertex as Geometric2d), radius_max);
                        vertex_temp = vertex_temp.Next;
                    } while (vertex_temp != vertex);
                    circle.Scalar = radius_max * rand.NextDouble();
                }
                #endregion

                if (vertex != null)
                {
                    vertex.BreakCrosBy(circle);
                    vertex = vertex.Cros;

                    vertex_temp = vertex;
                    do
                    {
                        while (Circle2dExt.Расширенное_расстояние(vertex_temp.DataInVertex as Circle, vertex_temp.Cros.Somes.CircleDelone) < 0)
                        {
                            vertex_temp.Rebuild();
                        }

                        vertex_temp.SetCircleDelone(Geometric2dExt.Круг_Делоне(vertex_temp.Prev.DataInVertex as Geometric2d, vertex_temp.DataInVertex as Geometric2d, vertex_temp.Next.DataInVertex as Geometric2d));

                        vertex_temp = vertex_temp.Next.Cros.Next;
                    } while (vertex_temp != vertex);

                    triples = ClosenessModelExt<Geometric, Circle>.GetTriples(this.vertex);
                }

                Invalidate();
                this.Refresh();
                System.Threading.Thread.Sleep(100);
            }
        }
 /// <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.Scalar <= height) && (point.X - circle.Scalar >= 0) && (point.Y - circle.Scalar >= 0); //!!! Необходимо учитывать погрешность.
 }
Example #24
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.Scalar);
     polygon.Add(circle.Pole - vector * circle.Scalar);
     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].Scalar, Y = circles[i].Scalar });
                points.Add(new Point2d { X = circles[i].Scalar, Y = height - circles[i].Scalar });
                #endregion
                #region Шаг 1.2. Создание и заполнение списка годографов.
                Circle[] godographs = new Circle[i];
                for (int j = 0; j < i; j++)
                    godographs[j] = Circle2dExt.Годограф_функции_плотного_размещения(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].Scalar < circles[i].Scalar)
                    {
                        double x = circles[i].Scalar - godographs[j].Pole.X;
                        double y = Math.Sqrt(godographs[j].Scalar * godographs[j].Scalar - x * x);
                        Point2d point;

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

                        point = new Point2d { X = circles[i].Scalar, 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].Scalar < circles[i].Scalar)
                    {
                        double y = circles[i].Scalar - godographs[j].Pole.Y;
                        double x = Math.Sqrt(godographs[j].Scalar * godographs[j].Scalar - y * y);
                        Point2d point;

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

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

                        point = new Point2d { X = godographs[j].Pole.X - x, Y = height - circles[i].Scalar };
                        if (IsCheckedStrip(point, circles[i], height))
                            points.Add(point);
                        point = new Point2d { X = godographs[j].Pole.X + x, Y = height - circles[i].Scalar };
                        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 = Circle2dExt.Точка_пересечения_границ(godographs[j], godographs[k]);
                        if (point != null && IsCheckedStrip(point, circles[i], height))
                            points.Add(point); // Заменить на "Добавить в отсортированный набор данных". Лучше всего использовать бинарное взвешенное дерево.

                        point = Circle2dExt.Точка_пересечения_границ(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].Scalar);
                #endregion
            }
            #endregion
        }
Example #26
0
 /// <summary>
 /// Получить годограф функции плотного размещения круга возле полуплоскости.
 /// </summary>
 /// <param name="plane_this">Полуплоскость.</param>
 /// <param name="circle">Круг.</param>
 /// <returns>Годограф функции плотного размещения.</returns>
 public static Plane2d Годограф_функции_плотного_размещения(Plane2d plane_this, Geometric2dWithPointScalar circle)
 {
     return new Plane2d() { Pole = plane_this.Pole + plane_this.Normal * circle.Scalar, Normal = plane_this.Normal };
 }