/// <summary> /// Вставка структурных ребер в триангуляцию. /// </summary> /// <param name="structRibs">Список структурных ребер для триангуляции.</param> void RestrictedTriangulation(List <Rib> structRibs) { while (structRibs.Count != 0) { // Поиск ближайших ребер, которые могут пересекаться со структурным (последнее в списке). var checkRibs = SearchRibsCross(structRibs); if (checkRibs == null) { continue; } var structRib = structRibs.Last(); var A = structRib.A; var B = structRib.B; Vertex pointNew = null; bool del = false; // Поиск точек пересечения. foreach (var ri in checkRibs) { pointNew = Vertex.PointCross(A, B, ri.A, ri.B); // Точка пересечения является одной из точек проверяемого ребра. if (pointNew == ri.A || pointNew == ri.B) { del = true; // Доработать поиск точек пересечения!! break; } if (pointNew != null) { break; } } // Разбиение структурного ребра. var newRibA = new Rib(pointNew, B, null, null); var newRibB = new Rib(pointNew, A, null, null); newRibA.SetBorderValue(structRib); newRibB.SetBorderValue(structRib); structRibs.Add(newRibA); structRibs.Add(newRibB); structRibs.Remove(structRib); if (del) { continue; } AddPoint(pointNew); } }
/// <summary> /// Нахождение вершины, противоположной ребру. /// </summary> /// <param name="rib">Ребро.</param> /// <returns>Возвращение вершины.</returns> public Vertex GetVertexOpposite(Rib rib) { if (Ribs[0] == rib) { return(Points[2]); } return(Ribs[1] == rib? Points[0]: Points[1]); }
/// <summary> /// Добавление ребер для нового треугольника. /// </summary> /// <param name="R1">Первое ребро.</param> /// <param name="R2">Второе ребро.</param> /// <param name="R3">Третье ребро.</param> public void SetRibs(Rib R1, Rib R2, Rib R3) { Ribs[0] = R1; Ribs[1] = R2; Ribs[2] = R3; Сlockwise(); SquareTriangle(); }
/// <summary> /// Добавление точки внутрь треугольника. /// Треугольник разделяется на 3 новых. /// </summary> /// <param name="T">Треугольник, в который попадает точка.</param> /// <param name="node">Точка.</param> /// <returns>Возвращаются новые треугольники.</returns> Triangle[] PointInTriangle(Triangle T, Vertex node) { // Точки. var A = T.Points[0]; var B = T.Points[1]; var C = T.Points[2]; // Ребра. var AB = T.GetRib(A, B); var BC = T.GetRib(B, C); // Новые треугольники. var LT = new Triangle(); var RT = new Triangle(); // Новые ребра. var OA = new Rib(node, A, LT, T); var OB = new Rib(node, B, LT, RT); var OC = new Rib(node, C, RT, T); AB.UpdateTriangle(T, LT); BC.UpdateTriangle(T, RT); T.UpdateRib(OA, AB); T.UpdateRib(OC, BC); LT.SetRibs(AB, OB, OA); RT.SetRibs(BC, OB, OC); // Задание значения проводимости новых треугольников. if (T.Permeability.HasValue) { LT.Permeability = T.Permeability.Value; RT.Permeability = T.Permeability.Value; } // Добавление новых треугольников в коллекцию. triangles.Add(LT); triangles.Add(RT); // Соседние треугольники точек. node.SetTriangle(T); node.SetTriangle(LT); node.SetTriangle(RT); A.SetTriangle(LT); B.SetTriangle(LT); B.SetTriangle(RT); B.DelTriangle(T); C.SetTriangle(RT); cache.UpdateCache(LT); cache.UpdateCache(RT); return(new Triangle[] { T, LT, RT }); }
/// <summary> /// Обновление ребра в треугольнике. /// </summary> /// <param name="newRib">Новое ребро.</param> /// <param name="oldRib">Старое ребро.</param> public void UpdateRib(Rib newRib, Rib oldRib) { if (Ribs[0] == oldRib) { Ribs[0] = newRib; } else if (Ribs[1] == oldRib) { Ribs[1] = newRib; } else { Ribs[2] = newRib; } Сlockwise(); SquareTriangle(); }
/// <summary> /// Формирование структуры элемента, обход точек по часовой стрелке. /// </summary> void Сlockwise() { Vertex C = null; var A = Ribs[0].A; var B = Ribs[0].B; Rib a = null; Rib b = null; var rib1 = Ribs[1]; if (rib1.A == A) { a = Ribs[2]; b = rib1; C = rib1.B; } else if (rib1.A == B) { a = rib1; b = Ribs[2]; C = rib1.B; } else if (rib1.B == A) { a = Ribs[2]; b = rib1; C = rib1.A; } else { a = rib1; b = Ribs[2]; C = rib1.A; } // Обновление вершин и ребер. Points[0] = A; Points[1] = B; Points[2] = C; Ribs[1] = a; Ribs[2] = b; }