private void AddNodesFromCommonLine(MyFrontSegment seg, List <MyFrontSegment> allSegs) { foreach (MyLine line in seg.CorrespondingArea.Lines) { for (int i = 0; i < line.Areas.Count; i++) { int id = line.Areas[i]; if (id != seg.CorrespondingArea.Id) { MyFrontSegment targetSeg = allSegs.Find(s => s.CorrespondingArea.Id == id); if (targetSeg != null) { List <MyNode> commonNodes; if (line is MyStraightLine) { commonNodes = findNodesAtStraightLine(seg.Nodes, line as MyStraightLine); } else { commonNodes = findNodesAtArc(seg.Nodes, line as MyArc); } foreach (MyNode node in commonNodes) { if (!targetSeg.Nodes.Contains(node)) { targetSeg.Nodes.Add(node); } } } } } } }
private void btnOk_Click(object sender, EventArgs e) { string modelName = gridName.Text; int elemId = 0; errorBadGridName.Visible = false; if (gridName.Text == string.Empty) { MessageBox.Show("Имя сетки не может быть пустым!"); return; } if (parent.currentFullModel.FiniteElementModels.Find(m => m.ModelName == modelName) != null) { errorBadGridName.Visible = true; return; } if (ddlGenerationMethod.SelectedIndex == -1) { MessageBox.Show("Не задан метод генерации точек!"); return; } this.Hide(); parent.StartProgress("Построение сетки"); List <MyFrontSegment> segments = new List <MyFrontSegment>(); nodesCount = 0; MyFiniteElementModel newModel = new MyFiniteElementModel(parent.currentFullModel.IdCandidate, gridName.Text, MyFiniteElementModel.GridType.Normal); // если выбрана триангуляция на основе существующих узлов if (ddlGenerationMethod.SelectedIndex == 4) { List <MyFiniteElement> elems = GetTriangulation(currentModel.Nodes); newModel.Nodes.AddRange(currentModel.Nodes); newModel.Nodes.ForEach(n => n.finiteElements.Clear()); foreach (MyFiniteElement elem in elems) { double cx = elem.Nodes.Sum(s => s.X) / 3; double cy = elem.Nodes.Sum(s => s.Y) / 3; foreach (MyArea area in parent.currentFullModel.geometryModel.Areas) { //if (Mathematics.ContainsPoint(area.Nodes, cx, cy)) if (PointFits(area, new List <MyNode>(), new MyPoint(cx, cy), double.MinValue)) { elem.Id = ++elemId; elem.areaId = area.Id; elem.LinkNodes(); newModel.FiniteElements.Add(elem); break; } } } } // любая другая триангуляция else { foreach (MyArea area in parent.currentFullModel.geometryModel.Areas) { List <MyNode> result = new List <MyNode>(); for (int j = 0; j < 4; j++) { int neighbor = parent.currentFullModel.geometryModel.joinTable[area.Id - 1, j] - 1; if (neighbor != -1) { if (neighbor < area.Id - 1) { List <MyLine> lines = area.Lines.FindAll(l => l.Areas.Contains(area.Id) && l.Areas.Contains(neighbor + 1)); foreach (MyLine line in lines) { if (line is MyStraightLine) { result.AddRange(findNodesAtStraightLine(segments[neighbor].Nodes, line as MyStraightLine)); } else { result.AddRange(findNodesAtArc(segments[neighbor].Nodes, line as MyArc)); } } } } } result = result.Distinct().ToList(); double h = (double)nudMinDistance.Value; foreach (MyPoint p in area.Nodes) { if (result.Find(n => Mathematics.sameNode(n, p)) == null) { result.Add(new MyNode(p.X, p.Y, ++nodesCount)); } } GeneratePoints(area, result); MyFrontSegment seg = new MyFrontSegment(area); seg.Nodes = result; segments.Add(seg); AddNodesFromCommonLine(seg, segments); } elemId = 0; if (ddlGenerationMethod.SelectedIndex == 1) { GenerateNodesInDensitySectors(segments); } foreach (MyFrontSegment seg in segments) { foreach (MyNode node in seg.Nodes) { if (!newModel.Nodes.Contains(node)) { newModel.Nodes.Add(node); } } } if (ddlGenerationMethod.SelectedIndex == 1) { foreach (MyFiniteElement elem in GetTriangulation(newModel.Nodes)) { double cx = elem.Nodes.Sum(s => s.X) / 3; double cy = elem.Nodes.Sum(s => s.Y) / 3; foreach (MyArea area in parent.currentFullModel.geometryModel.Areas) { //if (Mathematics.ContainsPoint(area.Nodes, cx, cy)) if (PointFits(area, new List <MyNode>(), new MyPoint(cx, cy), 0.001)) { elem.Id = ++elemId; elem.LinkNodes(); newModel.FiniteElements.Add(elem); break; } } } } else { foreach (MyFrontSegment seg in segments) { foreach (MyFiniteElement elem in GetTriangulation(seg.Nodes, seg.CorrespondingArea.Id)) { double cx = elem.Nodes.Sum(s => s.X) / 3; double cy = elem.Nodes.Sum(s => s.Y) / 3; MyArea area = parent.currentFullModel.geometryModel.Areas[segments.IndexOf(seg)]; //if (PointFits(Mathematics.ContainsPoint(area.Nodes, cx, cy)) if (PointFits(area, new List <MyNode>(), new MyPoint(cx, cy), 0.001)) { elem.Id = ++elemId; elem.LinkNodes(); seg.finiteElems.Add(elem); } } newModel.FiniteElements.AddRange(seg.finiteElems); } } } newModel.baseType = newModel.type = MyFiniteElementModel.GridType.Delauney; parent.currentFullModel.densityPoints.Clear(); parent.EndProgress(); parent.ModelCreated(newModel); Close(); // создаем для новой КЭ модели id }
private void GenerateNodesInDensitySectors(List <MyFrontSegment> segments) { foreach (DensityPoint dPoint in parent.currentFullModel.densityPoints) { List <MyArea> areas = new List <MyArea>(); int totalCount = 0; foreach (MyFrontSegment seg in segments) { List <MyNode> innerNodes = seg.Nodes.FindAll(n => Mathematics.FindDist(n.X, n.Y, dPoint.X, dPoint.Y) < dPoint.R); if (innerNodes.Count > 0) { innerNodes.ForEach(n => { if (seg.CorrespondingArea.Nodes.Find(p => Mathematics.sameNode(n, p)) == null //&& seg.CorrespondingArea.StraightLines.Find(l => Mathematics.pointOnLine(n, l)) == null && //seg.CorrespondingArea.Arcs.Find(a => Mathematics.pointFitsArc(n,a,0.01)) == null ) { seg.Nodes.Remove(n); } else { totalCount++; } } ); areas.Add(seg.CorrespondingArea); } } Random generator = new Random((int)DateTime.Now.Ticks); for (int i = 0; totalCount < dPoint.val; i++) { int triesCount = (int)nudTriesCount.Value; do { double x = dPoint.X - dPoint.R + generator.NextDouble() * dPoint.R * 2.0; double y = dPoint.Y - dPoint.R + generator.NextDouble() * dPoint.R * 2.0; MyNode p = new MyNode(x, y); if (Mathematics.FindDist(x, y, dPoint.X, dPoint.Y) > dPoint.R) { continue; } p.Id = -1; bool added = false; foreach (MyArea area in areas) { MyFrontSegment seg = segments.Find(s => s.CorrespondingArea == area); if (PointFits(area, seg.Nodes, p, dPoint.h)) { seg.Nodes.Add(p); added = true; } } if (added) { break; } } while (--triesCount > 0); if (triesCount == 0) { break; } totalCount++; } } List <MyNode> nodesToRenum = new List <MyNode>(); foreach (MyFrontSegment seg in segments) { nodesToRenum.AddRange(seg.Nodes); } nodesToRenum = nodesToRenum.Distinct().ToList(); for (int i = 0; i < nodesToRenum.Count; i++) { nodesToRenum[i].Id = i + 1; } }