public void Find() { double ed_curr = -1; double ed_next = -1; for (int i = 0; i < iterator_plane.Count && ed_curr < 0; i++) { ed_curr = Plane2dExt.Расширенное_расстояние(iterator_plane.Plane(0), iterator_point.Point(0)); ed_next = Plane2dExt.Расширенное_расстояние(iterator_plane.Plane(0), iterator_point.Point(1)); int k; if (ed_curr > ed_next) k = 1; else { ed_curr = ed_next; ed_next = Plane2dExt.Расширенное_расстояние(iterator_plane.Plane(0), iterator_point.Point(-1)); k = -1; } while (ed_curr >= 0 && ed_curr > ed_next) { iterator_point.Move(k); ed_curr = ed_next; ed_next = Plane2dExt.Расширенное_расстояние(iterator_plane.Plane(0), iterator_point.Point(0)); } if (ed_curr < 0) iterator_plane.Move(1); } if (ed_curr < 0) { Polygon2d.Iterator t = iterator_plane; iterator_plane = iterator_point; iterator_point = t; for (int i = 0; i < iterator_plane.Count && ed_curr < 0; i++) { ed_curr = Plane2dExt.Расширенное_расстояние(iterator_plane.Plane(0), iterator_point.Point(0)); ed_next = Plane2dExt.Расширенное_расстояние(iterator_plane.Plane(0), iterator_point.Point(1)); int k; if (ed_curr > ed_next) k = 1; else { ed_curr = ed_next; ed_next = Plane2dExt.Расширенное_расстояние(iterator_plane.Plane(0), iterator_point.Point(-1)); k = -1; iterator_point.Move(1); } while (ed_curr >= 0 && ed_curr > ed_next) { iterator_point.Move(k); ed_curr = ed_next; ed_next = Plane2dExt.Расширенное_расстояние(iterator_plane.Plane(0), iterator_point.Point(0)); } if (ed_curr < 0) iterator_plane.Move(1); } } }
public static bool IsRightPolygon(this Polygon2d polygon) { Polygon2d.Iterator iterator; iterator = new Polygon2d.Iterator(0, polygon, 0); bool is_right_polygon = true; for (int i = 0; i < iterator.Polygon.Count && is_right_polygon; i++) is_right_polygon = Plane2dExt.Расширенное_расстояние(iterator.Plane(i), iterator.Point(i + 2)) < 0; return is_right_polygon; }
public static bool IsContain(this Polygon2d polygon, Point2d point) { if (polygon.Count <= 1) return false; bool is_contain = true; Polygon2d.Iterator iterator = new Polygon2d.Iterator(0, polygon, 0); for (int i = 0; i < iterator.Polygon.Count && is_contain; i++) is_contain = Plane2dExt.Расширенное_расстояние(iterator.Plane(i), point) <= 0; return is_contain; }
/// <summary> /// Метод подготовки данных и запуска алгоритма размещения многоугольников (метод барьерных функций). /// </summary> /// <param name="mu"></param> /// <param name="beta"></param> /// <param name="eps"></param> public void CalculateStart(double mu, double beta, double eps) { double width_old; do { width_old = strip_vector.X; #region Шаг 1. Создаём начальную точку. FillPoint(); #endregion #region Шаг 2. Создаём функцию цели. Clear(F); F[index_strip] = 1; #endregion #region Шаг 3. Создаём набор ограничений. Clear(Gs); int k = 0; #region Шаг 3.1. Для каждого многоугольника... for (int i = 0; i < polygons.Length; i++) { #region Шаг 3.1.1. Создаём набор ограничений (G >= 0) по полосе. #region Шаг 3.1.1.1. Ограничение по нижней границе. // Y - min.Y >= 0 Gs[k][2 * i + 1] = 1; Gs[k][index_strip + 1] = -polygons[i].MinY; k++; #endregion #region Шаг 3.1.1.2. Ограничение по левой границе. // X - min.X >= 0 Gs[k][2 * i] = 1; Gs[k][index_strip + 1] = -polygons[i].MinX; k++; #endregion #region Шаг 3.1.1.3. Ограничение по верхней границе. // Y + max.Y <= H --> -Y - max.Y + H >= 0 Gs[k][2 * i + 1] = -1; Gs[k][index_strip + 1] = -polygons[i].MaxY + strip_vector.Y; k++; #endregion #region Шаг 3.1.1.4. Ограничение по правой границе. // X + max.X <= Z --> -X + Z - max.X >= 0 Gs[k][2 * i] = -1; Gs[k][index_strip] = 1; Gs[k][index_strip + 1] = -polygons[i].MaxX; k++; #endregion #endregion } #endregion #region Шаг 3.2. Для каждой пары многоугольников... for (int i = 0; i < polygons.Length - 1; i++) for (int j = i + 1; j < polygons.Length; j++) { #region Шаг 3.2.1. Создаём и находим разделяющую. //PlaneDividing pd = new PlaneDividing(new Polygon2d.Iterator(i, polygons[i], 0), new Polygon2d.Iterator(j, polygons[j], 0)); //pd.Find(); #region Временный код. PlaneDividing pd; Polygon2d.Iterator it1i = new Polygon2d.Iterator(i, polygons[i], 0); Polygon2d.Iterator it1j = new Polygon2d.Iterator(j, polygons[j], 0); double ed1 = Find(it1i, it1j); Polygon2d.Iterator it2i = new Polygon2d.Iterator(i, polygons[i], 0); Polygon2d.Iterator it2j = new Polygon2d.Iterator(j, polygons[j], 0); double ed2 = Find(it2j, it2i); if (ed1 > ed2) pd = new PlaneDividing(it1i, it1j); else pd = new PlaneDividing(it2j, it2i); #endregion #endregion #region Шаг 3.2.2. Создаём ограничение. Vector2d vector = pd.IteratorPlane.Point(1) - pd.IteratorPlane.Point(0); Vector2d normal = new Vector2d { X = -vector.Y, Y = vector.X }; //normal.Normalize(); // Нужна ли нормализация вектора? Gs[k][2 * pd.IteratorPoint.IndexPolygon] = -normal.X; Gs[k][2 * pd.IteratorPoint.IndexPolygon + 1] = -normal.Y; Gs[k][2 * pd.IteratorPlane.IndexPolygon] = normal.X; Gs[k][2 * pd.IteratorPlane.IndexPolygon + 1] = normal.Y; Gs[k][index_strip + 1] = -((pd.IteratorPoint.Polygon[pd.IteratorPoint.Index] - pd.IteratorPlane.Polygon[pd.IteratorPlane.Index]) * normal); k++; #endregion } #endregion #endregion #region Шаг 4. Выполняем поиск локального минимума с заданными ограничениями. Calculate(mu, beta, eps); #endregion #region Шаг 5. Преобразуем результат метода барьеров в результат задачи размещения. FillPolygons(); #endregion } while (Math.Abs(strip_vector.X - width_old) > eps); }
// Получить разделяющие для объекта, заданного номером. // TODO: Переделать. public System.Collections.Generic.List<Plane2d> GetPlanes(int index) { System.Collections.Generic.List<Plane2d> res = new System.Collections.Generic.List<Plane2d>(); int k=4*polygons.Length; for(int i=0; i<polygons.Length-1;i++) for (int j = i + 1; j < polygons.Length; j++) { if (index == i || index == j) { Polygon2d.Iterator iti = new Polygon2d.Iterator((int)Gs[k][0], polygons[(int)Gs[k][0]], (int)Gs[k][2]); res.Add(iti.Plane(0)); } k++; } return res; }
public PlaneDividing(Polygon2d.Iterator iterator_plane, Polygon2d.Iterator iterator_point) { this.iterator_plane = iterator_plane; this.iterator_point = iterator_point; }