/// <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; ; }
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; }
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; }
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 }
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; }
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; }
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; }
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) { }
/// <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; ; }