public void DrawLinesArray(MyStraightLine[] lines, Color color, bool drawId = true, bool isAreaLine = false, double width = 2.0) { int count = lines.Length * 2; if (count == 0) { return; } float[] pts = new float[count * 2]; double[] vColors = colorArray(color); int list = Gl.glGenLists(1); Gl.glNewList(list, Gl.GL_COMPILE); Gl.glColor3dv(vColors); Gl.glLineWidth((float)(width)); Gl.glEndList(); for (int i = 0; i < lines.Length; i++) { MyStraightLine line = lines[i]; pts[i * 4] = (float)line.StartPoint.X; pts[i * 4 + 1] = (float)line.StartPoint.Y; pts[i * 4 + 2] = (float)line.EndPoint.X; pts[i * 4 + 3] = (float)line.EndPoint.Y; if (drawId) { DrawString("L" + line.Id.ToString(), (float)(line.EndPoint.X + line.StartPoint.X) / 2.0f, (float)(line.EndPoint.Y + line.StartPoint.Y) / 2.0f); } } if (drawId) { FlushText(color); } drawBuffer.Add(new DrawingOperation(Gl.GL_LINES, pts, list)); }
public static MyPoint crossPoint(MyPoint point, MyStraightLine sline) { double commonX, commonY; if (Math.Abs(sline.EndPoint.X - sline.StartPoint.X) < 0.01) { commonX = sline.StartPoint.X; commonY = point.Y; } else if (Math.Abs(sline.EndPoint.Y - sline.StartPoint.Y) < 0.01) { commonX = point.X; commonY = sline.StartPoint.Y; } else { double k1, b1; double k2, b2; // Находим точку пересечения прямой и перпендикуляра, опущенного на эту прямую из точки point k2 = (double)(sline.EndPoint.Y - sline.StartPoint.Y) / (sline.EndPoint.X - sline.StartPoint.X); k1 = Math.Tan(Math.Atan(k2) + Math.PI / 2.0); b2 = (double)sline.EndPoint.Y - k2 * sline.EndPoint.X; b1 = point.Y - k1 * point.X; commonX = (b2 - b1) / (k1 - k2); commonY = commonX * k2 + b2; } return(new MyPoint(commonX, commonY, MyPoint.PointType.IsGeometryPoint)); }
private void findNodesAtStraightLine(List <MyNode> notMoveableNodes, MyStraightLine sline) { foreach (MyNode node in currentModel.Nodes) { // уравнение прямой, проходящей через две точки if (Mathematics.pointOnLine(node.X, node.Y, sline)) { if (notMoveableNodes.IndexOf(node) == -1) { notMoveableNodes.Add(node); } } } }
public bool pointNearLine(MyPoint point, MyStraightLine sline) { MyPoint comPoint = crossPoint(point, sline); if (Mathematics.FindDist(point, comPoint) < visualizer.pointLocality) { if (comPoint.X <= Math.Max(sline.StartPoint.X, sline.EndPoint.X) && comPoint.X >= Math.Min(sline.StartPoint.X, sline.EndPoint.X) && comPoint.Y <= Math.Max(sline.StartPoint.Y, sline.EndPoint.Y) && comPoint.Y >= Math.Min(sline.StartPoint.Y, sline.EndPoint.Y)) // условие, гарантирующее, что точка от клика мышки лежит на отрезке, а не на прямой { return(true); } } return(false); }
private bool LineCrossingArc(MyStraightLine line, MyArc arc) { double r, a, b, c; if (Math.Abs(line.StartPoint.X - line.EndPoint.X) < 0.01) { b = 0; a = 1; c = -arc.CenterPoint.X; } else if (Math.Abs(line.StartPoint.Y - line.EndPoint.Y) < 0.01) { b = 1; a = 0; c = -arc.CenterPoint.Y; } else { double k, bx; k = (line.EndPoint.Y - line.StartPoint.Y) / (line.EndPoint.X - line.StartPoint.X); bx = line.EndPoint.Y - k * line.EndPoint.X; a = -k; c = -(bx + k * arc.CenterPoint.X - arc.CenterPoint.Y); b = 1; } r = Mathematics.FindDist(arc.StartPoint, arc.CenterPoint); double x0 = -a * c / (a * a + b * b), y0 = -b * c / (a * a + b * b); if (c * c > r * r * (a * a + b * b) + 0.01) { return(false); } else if (Math.Abs(c * c - r * r * (a * a + b * b)) < 0.01) { MyPoint xPoint = new MyPoint(x0, y0, MyPoint.PointType.IsGeometryPoint); return(pointFitsArc(xPoint, arc, checkType.doublePrecision) && Mathematics.FindDist(xPoint, line.EndPoint) > 0.01 && Mathematics.pointOnLine(xPoint, line)); } else { double d = r * r - c * c / (a * a + b * b); double mult = Math.Sqrt(d / (a * a + b * b)); double ax, ay, bx, by; ax = arc.CenterPoint.X + x0 + b * mult; bx = arc.CenterPoint.X + x0 - b * mult; ay = arc.CenterPoint.Y + y0 - a * mult; by = arc.CenterPoint.Y + y0 + a * mult; MyPoint xPoint1 = new MyPoint(ax, ay, MyPoint.PointType.IsGeometryPoint); MyPoint xPoint2 = new MyPoint(bx, by, MyPoint.PointType.IsGeometryPoint); return((pointFitsArc(xPoint1, arc, checkType.doublePrecision) && Mathematics.FindDist(xPoint1, line.EndPoint) > 0.01 && Mathematics.pointOnLine(xPoint1, line)) || (pointFitsArc(xPoint2, arc, checkType.doublePrecision) && Mathematics.FindDist(xPoint2, line.EndPoint) > 0.01 && Mathematics.pointOnLine(xPoint2, line))); } }
private List <MyNode> findNodesAtStraightLine(List <MyNode> nodes, MyStraightLine sline) { List <MyNode> result = new List <MyNode>(); foreach (MyNode node in nodes) { if (Mathematics.pointOnLine(node.X, node.Y, sline)) { if (result.IndexOf(node) == -1) { result.Add(node); } } } return(result); }
public void CreateStraightLine(int number, MyPoint p1, MyPoint p2) { if (p1 == p2) { this.errorSamePoints.Visible = true; return; } MyStraightLine newLine = new MyStraightLine(number, p1, p2); this.parent.currentFullModel.geometryModel.StraightLines.Add(newLine); this.parent.currentFullModel.geometryModel.NumOfLines++; this.number.Text = (parent.currentFullModel.geometryModel.NumOfLines + 1).ToString(); this.startPoint.Text = ""; this.endPoint.Text = ""; this.startPoint.Select(); }
private bool LinesCrossing(MyStraightLine l1, MyStraightLine l2) { double k1 = 0, b1 = 0; double k2 = 0, b2 = 0; double commonX, commonY; if (Math.Abs(l1.EndPoint.X - l1.StartPoint.X) < 0.01) { if (Math.Abs(l2.EndPoint.X - l2.StartPoint.X) < 0.01) { // параллельные прямые все ещё не пересекаются return(false); } else { k2 = (double)(l2.EndPoint.Y - l2.StartPoint.Y) / (l2.EndPoint.X - l2.StartPoint.X); b2 = (double)(l2.EndPoint.Y - k2 * l2.EndPoint.X); commonX = l1.StartPoint.X; commonY = commonX * k2 + b2; } } else { if (Math.Abs(l2.EndPoint.X - l2.StartPoint.X) < 0.01) { k1 = (l1.EndPoint.Y - l1.StartPoint.Y) / (l1.EndPoint.X - l1.StartPoint.X); b1 = (l1.EndPoint.Y - k1 * l1.EndPoint.X); commonX = l2.EndPoint.X; commonY = commonX * k1 + b1; } else { k1 = (double)(l1.EndPoint.Y - l1.StartPoint.Y) / (l1.EndPoint.X - l1.StartPoint.X); k2 = (double)(l2.EndPoint.Y - l2.StartPoint.Y) / (l2.EndPoint.X - l2.StartPoint.X); b2 = (double)(l2.EndPoint.Y - k2 * l2.EndPoint.X); b1 = (double)(l1.EndPoint.Y - k1 * l1.EndPoint.X); commonX = (b2 - b1) / (k1 - k2); commonY = commonX * k2 + b2; } } MyPoint commonPoint = new MyPoint(commonX, commonY, MyPoint.PointType.IsGeometryPoint); return(Mathematics.pointOnLine(commonX, commonY, l1) && Mathematics.pointOnLine(commonX, commonY, l2) && Mathematics.FindDist(commonPoint, l1.EndPoint) > 0.01); }
public static bool pointOnLine(MyPoint point, MyStraightLine sline) { double x = point.X, x1 = sline.StartPoint.X, x2 = sline.EndPoint.X; double y = point.Y, y1 = sline.StartPoint.Y, y2 = sline.EndPoint.Y; if (Math.Abs(y2 - y1) < 0.01 && x.MoreOrEqual(Math.Min(x1, x2)) && x.LessOrEqual(Math.Max(x1, x2)) && Math.Abs(y - y1) < 0.01) { return(true); } if (Math.Abs(x2 - x1) < 0.01 && y.MoreOrEqual(Math.Min(y1, y2)) && y.LessOrEqual(Math.Max(y1, y2)) && Math.Abs(x - x1) < 0.01) { return(true); } bool onLine = (Math.Abs((x - x1) * (y2 - y1) - (y - y1) * (x2 - x1)) < 0.1); onLine = (onLine && x.LessOrEqual(Math.Max(x1, x2)) && x.MoreOrEqual(Math.Min(x1, x2)) && y.LessOrEqual(Math.Max(y1, y2)) && y.MoreOrEqual(Math.Min(y1, y2))); return(onLine); }
private void findNodesAtStraightLine(ref List <MyNode> forcedNodes, MyStraightLine sline, int currentModel) { foreach (MyNode node in this.parent.currentFullModel.FiniteElementModels[currentModel].Nodes) { // уравнение прямой, проходящей через две точки if (Math.Abs((node.X - sline.StartPoint.X) * (sline.StartPoint.Y - sline.EndPoint.Y) - (node.Y - sline.StartPoint.Y) * (sline.StartPoint.X - sline.EndPoint.X)) < 0.001) { List <MyPoint> tempPoints = new List <MyPoint>(); tempPoints.Add(sline.StartPoint); tempPoints.Add(sline.EndPoint); double minX, maxX, minY, maxY; minX = tempPoints[0].X; maxX = tempPoints[0].X; minY = tempPoints[0].Y; maxY = tempPoints[0].Y; foreach (MyPoint point in tempPoints) // тут определяем мин и макс координаты точек { if (point.X < minX) { minX = point.X; } if (point.X > maxX) { maxX = point.X; } if (point.Y < minY) { minY = point.Y; } if (point.Y > maxY) { maxY = point.Y; } } /*if (!(node.X < minX || node.Y < minY || node.X > maxX || node.Y > maxY)) // условие, гарантирующее, что точка лежит на отрезке, а не на прямой * { * if (forcedNodes.IndexOf(node) == -1) forcedNodes.Add(node); * }*/ if (Math.Abs(minX - maxX) < 0.001) // если линия вертикальная { if (!(node.Y < minY || node.Y > maxY)) // условие, гарантирующее, что точка от клика мышки лежит на отрезке, а не на прямой { if (forcedNodes.IndexOf(node) == -1) { forcedNodes.Add(node); } } } if (Math.Abs(minY - maxY) < 0.001) // если линия горизонтальная { if (!(node.X < minX || node.X > maxX)) // условие, гарантирующее, что точка от клика мышки лежит на отрезке, а не на прямой { if (forcedNodes.IndexOf(node) == -1) { forcedNodes.Add(node); } } } if (!(node.X < minX || node.Y < minY || node.X > maxX || node.Y > maxY)) // условие, гарантирующее, что точка от клика мышки лежит на отрезке, а не на прямой { if (forcedNodes.IndexOf(node) == -1) { forcedNodes.Add(node); } } } } }
private void OK() { if (this.number.Text == "") { MessageBox.Show("Не введены номера линий!"); return; } if (this.function.Enabled == true && this.function.Text == "") { MessageBox.Show("Не введена функция нагрузки!"); return; } if (trytocalculateExpression() == false) { MessageBox.Show("Неверный формат функции нагрузки!"); return; } int x = 0; double x1; if (this.tb.Text == "") { x++; } else { if (double.TryParse(tb.Text, out x1)) { ProjectForm.toch = x1; } else { MessageBox.Show("Неверный формат ввода точности нагрузки!"); return; } } this.parent.precision = this.parent.DefinePrecision(); int currentModel = this.parent.GetCurrentModelIndex(); string[] textlinesnumbers = this.number.Text.Split(','); List <MyStraightLine> lines = new List <MyStraightLine>(); List <MyArc> arcs = new List <MyArc>(); foreach (string textlinenumber in textlinesnumbers) { MyStraightLine line = this.parent.currentFullModel.geometryModel.StraightLines.Find( thisline => thisline.Id == Convert.ToInt32(textlinenumber)); MyArc arc = this.parent.currentFullModel.geometryModel.Arcs.Find( thisline => thisline.Id == Convert.ToInt32(textlinenumber)); if (line == null && arc == null) { //this.number.Clear(); this.parent.clearSelection(); MessageBox.Show("Неверно заданы линии!"); return; } else if (line != null && arc == null) { lines.Add(line); } else if (line == null && arc != null) { arcs.Add(arc); } } if (lines.Count != 0 && arcs.Count != 0) { //this.number.Clear(); this.parent.clearSelection(); MessageBox.Show("Неверно заданы линии!"); return; } else if (lines.Count != 0) { List <MyPoint> points = new List <MyPoint>(); if (checkLinesConnect(ref lines, ref points, currentModel) == false) { //this.number.Clear(); this.parent.clearSelection(); MessageBox.Show("Неверно заданы линии!"); return; } LineType linesposition = checkLinesPosition(points); if (checkLinesOnLine(points, linesposition) == false) { //this.number.Clear(); this.parent.clearSelection(); MessageBox.Show("Неверно заданы линии!"); return; } List <MyNode> nodes = new List <MyNode>(); getNodesOnLine(lines, ref nodes, currentModel, linesposition); this.calculateForceAtNodes(nodes, linesposition, null, currentModel); } else if (arcs.Count != 0) { List <MyPoint> points = new List <MyPoint>(); if (checkArcsConnect(ref arcs, ref points, currentModel) == false) { //this.number.Clear(); this.parent.clearSelection(); MessageBox.Show("Неверно заданы линии!"); return; } LineType linesposition = LineType.IsArc; List <MyNode> nodes = new List <MyNode>(); getNodesOnArc(arcs, ref nodes, currentModel, linesposition); this.number.Text = Convert.ToString(nodes.Count); this.calculateForceAtNodes(nodes, LineType.IsArc, arcs.ElementAt(0), currentModel); } parent.clearSelection(); if (this.parent.currentFullModel.FiniteElementModels[currentModel].R.Count == 0) { for (int i = 0; i <= this.parent.currentFullModel.FiniteElementModels[currentModel].Nodes.Count * 2; i++) { this.parent.currentFullModel.FiniteElementModels[currentModel].R.Add(0.0); } } int m = 1; foreach (MyNode node in this.parent.currentFullModel.FiniteElementModels[currentModel].Nodes) { this.parent.currentFullModel.FiniteElementModels[currentModel].R[2 * (m - 1) + 1] = node.ForceX; this.parent.currentFullModel.FiniteElementModels[currentModel].R[2 * (m - 1) + 2] = node.ForceY; m++; } this.parent.DrawForces(Color.Purple); this.parent.currentFullModel.FiniteElementModels[currentModel].NLD++; if (this.parent.showForces.Checked != true) { this.parent.showForces.Checked = true; } this.number.TextChanged -= new System.EventHandler(this.number_TextChanged); this.number.Text = ""; this.number.TextChanged += new System.EventHandler(this.number_TextChanged); this.number.Select(); this.parent.currentFullModel.geometryModel.highlightStraightLines.Clear(); this.parent.currentFullModel.geometryModel.highlightArcs.Clear(); this.parent.ReDrawAll(); this.parent.clearSelection(); }
public static bool pointOnLine(double x, double y, MyStraightLine sline) { return(pointOnLine(new MyPoint(x, y, MyPoint.PointType.IsGeometryPoint), sline)); }
private void constructionArea_MouseClick(object sender, MouseEventArgs e) { MyPoint clickPoint = visualizer.getClickPoint(e.X, e.Y); mouseAboveArea = true; if (this.mouseMoved) { this.mouseMoved = false; return; // смысл данного действа в том, что если область отображения перемещали мышкой, то ничего рисовать не нужно (перемещение происходит при одновременно нажатой левой клавише мыши и при ее движнии, и комп воспринимает это как событие MouseClick) } constructionArea.Focus(); // создаем точку if (addPointControl != null && addPointControl.IsHandleCreated) { MyPoint newPoint = this.addPointControl.CreatePoint(Convert.ToInt32(this.addPointControl.number.Text), clickPoint.X, clickPoint.Y); this.TestOnLineCircleAndArc(ref newPoint); // проверяем, не попала ли точка на линию, окружность или дугу } // запоминаем выбранную точку, и если их две, то рисуем линию между ними if (addStraightLineControl != null && addStraightLineControl.IsHandleCreated) { MyPoint point = currentFullModel.geometryModel.Points.Find(p => Math.Abs(p.X - clickPoint.X) < visualizer.pointLocality && Math.Abs(p.Y - clickPoint.Y) < visualizer.pointLocality); if (point != null) { if (e.Button == MouseButtons.Left) { this.currentFullModel.geometryModel.pairOfPoints.Add(point); if (this.currentFullModel.geometryModel.pairOfPoints.Count == 1) { this.addStraightLineControl.startPoint.Text = point.Id.ToString(); } if (this.currentFullModel.geometryModel.pairOfPoints.Count == 2) { this.addStraightLineControl.endPoint.Text = point.Id.ToString(); this.addStraightLineControl.CreateStraightLine(Convert.ToInt32(this.addStraightLineControl.number.Text), this.currentFullModel.geometryModel.pairOfPoints[0], this.currentFullModel.geometryModel.pairOfPoints[1]); clearSelection(); } } else if (e.Button == MouseButtons.Right) { if (currentFullModel.geometryModel.pairOfPoints.Count > 0) { addStraightLineControl.startPoint.Text = ""; clearSelection(); } } ReDrawAll(); } } // запоминаем выбранную точку, и если их три то рисуем дугу - режим создания дуги if (addArcsControl != null && addArcsControl.IsHandleCreated) { MyPoint point = currentFullModel.geometryModel.Points.Find(p => Math.Abs(p.X - clickPoint.X) < visualizer.pointLocality && Math.Abs(p.Y - clickPoint.Y) < visualizer.pointLocality); if (point != null) { if (e.Button == MouseButtons.Left) { this.currentFullModel.geometryModel.tripleOfPoints.Add(point); if (this.currentFullModel.geometryModel.tripleOfPoints.Count == 1) { this.addArcsControl.start2Point.Text = point.Id.ToString(); } if (this.currentFullModel.geometryModel.tripleOfPoints.Count == 2) { this.addArcsControl.end2Point.Text = point.Id.ToString(); } if (this.currentFullModel.geometryModel.tripleOfPoints.Count == 3) { this.addArcsControl.center2Point.Text = point.Id.ToString(); } if (this.currentFullModel.geometryModel.tripleOfPoints.Count == 3) { this.addArcsControl.CreateArc(Convert.ToInt32(this.addArcsControl.number.Text), this.addArcsControl.сlockwise.Checked, currentFullModel.geometryModel.tripleOfPoints[0], currentFullModel.geometryModel.tripleOfPoints[1], currentFullModel.geometryModel.tripleOfPoints[2]); this.currentFullModel.geometryModel.tripleOfPoints.Clear(); } } else if (e.Button == MouseButtons.Right) { if (currentFullModel.geometryModel.tripleOfPoints.Count == 1) { currentFullModel.geometryModel.tripleOfPoints.Remove(point); addArcsControl.start2Point.Text = ""; } else { currentFullModel.geometryModel.tripleOfPoints.Remove(point); if (addArcsControl.start2Point.Text == point.Id.ToString()) { addArcsControl.start2Point.Text = addArcsControl.end2Point.Text; addArcsControl.end2Point.Text = ""; } else { addArcsControl.end2Point.Text = ""; } } } } } // выделяем или снимаем выделение с точки if (this.editPointsControl != null && this.editPointsControl.IsHandleCreated) { if (currentFullModel.geometryModel.Points.Find(p => Math.Abs(p.X - clickPoint.X) < visualizer.pointLocality && Math.Abs(p.Y - clickPoint.Y) < visualizer.pointLocality) == null) { currentFullModel.geometryModel.editedPoint = null; editPointsControl.number.Text = editPointsControl.x.Text = editPointsControl.y.Text = ""; ReDrawAll(); } MyPoint point = currentFullModel.geometryModel.Points.Find(p => Math.Abs(p.X - clickPoint.X) < visualizer.pointLocality && Math.Abs(p.Y - clickPoint.Y) < visualizer.pointLocality); if (point != null) { if (e.Button == MouseButtons.Right) // если нажали правую кнопку мыши, то снять выделение с точки { if (this.currentFullModel.geometryModel.editedPoint != null && this.currentFullModel.geometryModel.editedPoint == point) { this.currentFullModel.geometryModel.editedPoint = null; // сбрасываем id, x и y this.editPointsControl.number.Text = ""; this.editPointsControl.x.Text = ""; this.editPointsControl.y.Text = ""; ReDrawAll(); } } if (e.Button == MouseButtons.Left) // если нажали левую кнопку мыши, то выделить точку { this.currentFullModel.geometryModel.editedPoint = point; // отображаем id, x и y точки this.editPointsControl.number.Text = this.currentFullModel.geometryModel.editedPoint.Id.ToString(); this.editPointsControl.x.Text = Mathematics.floor(this.currentFullModel.geometryModel.editedPoint.X, Mathematics.accuracy_medium).ToString(); this.editPointsControl.y.Text = Mathematics.floor(this.currentFullModel.geometryModel.editedPoint.Y, Mathematics.accuracy_medium).ToString(); ReDrawAll(); } } } if (this.editNodesControl != null && editNodesControl.IsHandleCreated) { foreach (MyArea area in this.currentFullModel.geometryModel.Areas) { MyPoint node = area.Nodes.Find(p => Math.Abs(p.X - clickPoint.X) < visualizer.pointLocality && Math.Abs(p.Y - clickPoint.Y) < visualizer.pointLocality); if (node != null) { if (e.Button == MouseButtons.Right) // если нажали правую кнопку мыши, то снять выделение с точки { if (this.currentFullModel.geometryModel.editedNode != null && this.currentFullModel.geometryModel.editedNode == node) { this.currentFullModel.geometryModel.editedNode = null; // сбрасываем id, x и y this.editNodesControl.number.Text = ""; this.editNodesControl.x.Text = ""; this.editNodesControl.y.Text = ""; ReDrawAll(); } } if (e.Button == MouseButtons.Left) // если нажали левую кнопку мыши, то выделить точку { this.currentFullModel.geometryModel.editedNode = node; // отображаем id, x и y точки this.editNodesControl.number.Text = this.currentFullModel.geometryModel.editedNode.Id.ToString(); this.editNodesControl.x.Text = Mathematics.floor(this.currentFullModel.geometryModel.editedNode.X, Mathematics.accuracy_medium).ToString(); this.editNodesControl.y.Text = Mathematics.floor(this.currentFullModel.geometryModel.editedNode.Y, Mathematics.accuracy_medium).ToString(); ReDrawAll(); } break; } } } // удаляем точку if (this.deletePointsControl != null && this.deletePointsControl.IsHandleCreated) { MyPoint point = currentFullModel.geometryModel.Points.Find(p => Math.Abs(p.X - clickPoint.X) < visualizer.pointLocality && Math.Abs(p.Y - clickPoint.Y) < visualizer.pointLocality); if (point != null) { this.deletePointsControl.DeletePoint(point.Id); } } // удаляем линию if (this.deleteLinesControl != null && this.deleteLinesControl.IsHandleCreated) { foreach (MyStraightLine sline in this.currentFullModel.geometryModel.StraightLines) { if (pointNearLine(clickPoint, sline)) { this.currentFullModel.geometryModel.StraightLines.Remove(sline); ReDrawAll(); break; } } foreach (MyArc arc in this.currentFullModel.geometryModel.Arcs) { double radius = Mathematics.FindDist(arc.CenterPoint, arc.StartPoint); if (pointFitsArc(clickPoint, arc, checkType.clickPrecision)) { this.currentFullModel.geometryModel.Arcs.Remove(arc); this.ReDrawAll(); break; } } } // закрепляем линию if (this.addBoundsControl != null && this.addBoundsControl.IsHandleCreated) { if (!this.addBoundsControl.xBound.Checked && !this.addBoundsControl.yBound.Checked) { this.addBoundsControl.errorBoundType.Visible = true; return; } this.addBoundsControl.errorBoundType.Visible = false; foreach (MyStraightLine sline in this.currentFullModel.geometryModel.StraightLines) { if (pointNearLine(clickPoint, sline)) { this.addBoundsControl.BoundLine(sline); ReDrawAll(); break; } } foreach (MyArc arc in this.currentFullModel.geometryModel.Arcs) { double radius = Mathematics.FindDist(arc.CenterPoint, arc.StartPoint); if (pointFitsArc(clickPoint, arc, checkType.clickPrecision)) { this.addBoundsControl.BoundLine(arc); ReDrawAll(); break; } } } // удаляем закрепление линии if (this.deleteBoundsControl != null && this.deleteBoundsControl.IsHandleCreated) { foreach (MyStraightLine sline in this.currentFullModel.geometryModel.StraightLines) { if (pointNearLine(clickPoint, sline)) { this.deleteBoundsControl.UnboundLine(sline); ReDrawAll(); break; } } foreach (MyArc arc in this.currentFullModel.geometryModel.Arcs) { double radius = Mathematics.FindDist(arc.CenterPoint, arc.StartPoint); if (pointFitsArc(clickPoint, arc, checkType.clickPrecision)) { this.deleteBoundsControl.UnboundLine(arc); ReDrawAll(); break; } } } // добавляем плотность для Делоне if (delauneyTriangulateForm != null && this.delauneyTriangulateForm.IsHandleCreated) { delauneyTriangulateForm.AddDensity(Mathematics.floor(mouseXcord, 0.01), Mathematics.floor(mouseYcord, 0.01)); } if (activeForm != null) { MyLine line = null; bool add = false; MyStraightLine sline = currentFullModel.geometryModel.StraightLines.Find(l => pointNearLine(clickPoint, l)); if (sline != null) { line = sline; if (currentFullModel.geometryModel.highlightStraightLines.IndexOf(sline) < 0) { add = true; currentFullModel.geometryModel.highlightStraightLines.Add(sline); } else { add = false; currentFullModel.geometryModel.highlightStraightLines.Remove(sline); } ReDrawAll(); } else { MyArc arc = currentFullModel.geometryModel.Arcs.Find(a => pointFitsArc(clickPoint, a, checkType.clickPrecision)); if (arc != null) { line = arc; if (currentFullModel.geometryModel.highlightArcs.IndexOf(arc) < 0) { add = true; currentFullModel.geometryModel.highlightArcs.Add(arc); } else { add = false; currentFullModel.geometryModel.highlightArcs.Remove(arc); } ReDrawAll(); } } if (line != null) { TextBox targetTxt; if (activeForm is StdOptimisation) { targetTxt = StdOptForm.notMoveLines; } else if (activeForm is RuppertForm) { targetTxt = ruppertForm.notMoveLines; } else if (activeForm is Regularization) { targetTxt = RegulizeForm.notMoveLines; } else { targetTxt = forcesForm.number; } if (add) { if (targetTxt.Text == "") { targetTxt.Text = line.Id.ToString(); } else { targetTxt.Text += "," + line.Id.ToString(); } } else { string[] fixNumbers = targetTxt.Text.Split(','); if (fixNumbers.Length == 1) { targetTxt.Text = ""; } else { if (fixNumbers.Last() == line.Id.ToString()) { targetTxt.Text = targetTxt.Text.Replace("," + line.Id.ToString(), ""); } else { targetTxt.Text = targetTxt.Text.Replace(line.Id.ToString() + ",", ""); } } } ReDrawAll(); } } // создаем окружность if (addCirclesControl != null && addCirclesControl.IsHandleCreated) { if (this.creatingCircle) // если мы рисовали окружность, а потом кликнули мышкой, то значит надо завершить рисование { this.addCirclesControl.CreateCircle(this.currentFullModel.geometryModel.NumOfCircles + 1, this.currentFullModel.geometryModel.tempCircle.CenterPoint, this.currentFullModel.geometryModel.tempCircle.Radius); this.creatingCircle = false; this.currentFullModel.geometryModel.centerOfCircle = null; this.addCirclesControl.number.Text = ""; this.addCirclesControl.centerPoint.Text = ""; this.addCirclesControl.radius.Text = ""; this.currentFullModel.geometryModel.tempCircle = null; if (hoveredPoint != null) { MyCircle addedCircle = currentFullModel.geometryModel.Circles.Find(c => c.Id == currentFullModel.geometryModel.NumOfCircles); splitCircleByPoint(addedCircle, hoveredPoint); } } else { MyPoint point = currentFullModel.geometryModel.Points.Find(p => Math.Abs(p.X - clickPoint.X) < visualizer.pointLocality && Math.Abs(p.Y - clickPoint.Y) < visualizer.pointLocality); if (point != null) { this.currentFullModel.geometryModel.centerOfCircle = point; if (this.addCirclesControl != null) { this.addCirclesControl.number.Text = (this.currentFullModel.geometryModel.NumOfCircles + 1).ToString(); this.addCirclesControl.centerPoint.Text = point.Id.ToString(); } this.creatingCircle = true; } } ReDrawAll(); } // удаляем окружнсть if (this.deleteCirclesControl != null && this.deleteCirclesControl.IsHandleCreated) { foreach (MyCircle circle in this.currentFullModel.geometryModel.Circles) { // уравнение окружности if (Math.Abs(Mathematics.FindDist(clickPoint, circle.CenterPoint) - circle.Radius) < visualizer.pointLocality) { // удаляем окружность this.deleteCirclesControl.DeleteCircle(circle.Id); break; } } } if (this.deleteAreasControl != null && this.deleteAreasControl.IsHandleCreated) { foreach (MyArea area in currentFullModel.geometryModel.Areas) { if (Mathematics.ContainsPoint(area.Nodes.ConvertAll(n => (MyNode)n).ToArray(), clickPoint)) { deleteAreasControl.number.Text = area.Id.ToString(); deleteAreasControl.OK(); ReDrawAll(); return; } } } // создаем зону if (this.addAreasControl != null && this.addAreasControl.IsHandleCreated) { if (addAreasControl.autoSearch.Checked == true) { List <MyStraightLine> checkLines = new List <MyStraightLine>(); foreach (MyPoint point in currentFullModel.geometryModel.Points) { checkLines.Add(new MyStraightLine(0, clickPoint, point)); } MyArc suspiciousArc = null; List <MyPoint> zonePoints = new List <MyPoint>(); foreach (MyStraightLine line in checkLines) { List <MyArc> sarcs; if (currentFullModel.geometryModel.StraightLines.Find(l => LinesCrossing(line, l)) == null) { sarcs = currentFullModel.geometryModel.Arcs.FindAll(a => LineCrossingArc(line, a)); if (sarcs.Count == 0) { zonePoints.Add(line.EndPoint); } else { suspiciousArc = sarcs[0]; } } } if (zonePoints.Count != 4) { if (suspiciousArc != null) { if (zonePoints.IndexOf(suspiciousArc.EndPoint) == -1) { zonePoints.Add(suspiciousArc.EndPoint); } if (zonePoints.IndexOf(suspiciousArc.StartPoint) == -1) { zonePoints.Add(suspiciousArc.StartPoint); } } } List <MyStraightLine> lines = currentFullModel.geometryModel.StraightLines.FindAll(l => zonePoints.IndexOf(l.StartPoint) != -1 && zonePoints.IndexOf(l.EndPoint) != -1); List <MyArc> arcs = currentFullModel.geometryModel.Arcs.FindAll(a => zonePoints.IndexOf(a.StartPoint) != -1 && zonePoints.IndexOf(a.EndPoint) != -1); List <string> ids = new List <string>(); foreach (MyStraightLine line in lines) { ids.Add(line.Id.ToString()); } foreach (MyArc arc in arcs) { ids.Add(arc.Id.ToString()); } if (ids.Count < 4) { MessageBox.Show("Ошибка поиска зоны!"); return; } addAreasControl.line1.Text = ids[0]; addAreasControl.line2.Text = ids[1]; addAreasControl.line3.Text = ids[2]; addAreasControl.line4.Text = ids[3]; if (addAreasControl.OK()) { ReDrawAll(); } } else { foreach (MyStraightLine sline in this.currentFullModel.geometryModel.StraightLines) { // уравнение прямой, проходящей через две точки if (pointNearLine(clickPoint, sline)) { if (this.currentFullModel.geometryModel.numOfSelectedLines == 0) { this.addAreasControl.line1.Text = sline.Id.ToString(); currentFullModel.geometryModel.numOfSelectedLines++; this.currentFullModel.geometryModel.highlightStraightLines.Add(sline); ReDrawAll(); break; } if (this.currentFullModel.geometryModel.numOfSelectedLines == 1) { this.addAreasControl.line2.Text = sline.Id.ToString(); currentFullModel.geometryModel.numOfSelectedLines++; this.currentFullModel.geometryModel.highlightStraightLines.Add(sline); ReDrawAll(); break; } if (this.currentFullModel.geometryModel.numOfSelectedLines == 2) { this.addAreasControl.line3.Text = sline.Id.ToString(); currentFullModel.geometryModel.numOfSelectedLines++; this.currentFullModel.geometryModel.highlightStraightLines.Add(sline); ReDrawAll(); break; } if (this.currentFullModel.geometryModel.numOfSelectedLines == 3) { this.addAreasControl.line4.Text = sline.Id.ToString(); currentFullModel.geometryModel.numOfSelectedLines++; this.currentFullModel.geometryModel.highlightStraightLines.Add(sline); ReDrawAll(); } if (this.currentFullModel.geometryModel.numOfSelectedLines == 4) { this.addAreasControl.OK(); // вызываем функцию, как будто была нажата кнопка ОК. эта функция обрабатывает значения линий в текстовых полях контрола. ReDrawAll(); } break; } } foreach (MyArc arc in this.currentFullModel.geometryModel.Arcs) { double radius = Mathematics.FindDist(arc.CenterPoint, arc.StartPoint); if (pointFitsArc(clickPoint, arc, checkType.clickPrecision)) { if (this.currentFullModel.geometryModel.numOfSelectedLines == 0) { this.addAreasControl.line1.Text = arc.Id.ToString(); currentFullModel.geometryModel.numOfSelectedLines++; this.currentFullModel.geometryModel.highlightArcs.Add(arc); ReDrawAll(); break; } if (this.currentFullModel.geometryModel.numOfSelectedLines == 1) { this.addAreasControl.line2.Text = arc.Id.ToString(); currentFullModel.geometryModel.numOfSelectedLines++; this.currentFullModel.geometryModel.highlightArcs.Add(arc); ReDrawAll(); break; } if (this.currentFullModel.geometryModel.numOfSelectedLines == 2) { this.addAreasControl.line3.Text = arc.Id.ToString(); currentFullModel.geometryModel.numOfSelectedLines++; this.currentFullModel.geometryModel.highlightArcs.Add(arc); ReDrawAll(); break; } if (this.currentFullModel.geometryModel.numOfSelectedLines == 3) { this.addAreasControl.line4.Text = arc.Id.ToString(); currentFullModel.geometryModel.numOfSelectedLines++; this.currentFullModel.geometryModel.highlightArcs.Add(arc); ReDrawAll(); } if (this.currentFullModel.geometryModel.numOfSelectedLines == 4) { this.addAreasControl.OK(); // вызываем функцию, как будто была нажата кнопка ОК. эта функция обрабатывает значения линий в текстовых полях контрола. ReDrawAll(); } break; } } } } }
public void ReadSFMFile(string FileName) { int i; // откроем бинарный файл *.sfm FileStream F1 = null; try { F1 = new FileStream(FileName, FileMode.Open, FileAccess.Read); } catch (IOException e) { MessageBox.Show(e.Message); return; } BinaryReader reader1 = new BinaryReader(F1); byte[] array1 = reader1.ReadBytes(10); // читаем префикс string prefix = ""; for (i = 0; i < 10; i++) { prefix += Convert.ToChar(array1[i]).ToString(); } if (prefix != "Sigma Form") { MessageBox.Show("Данный файл не является файлом формы!"); return; } int version = reader1.ReadInt32(); // читаем версию int bytes = reader1.ReadInt16(); // читаем количество байт отведенных под хранение числа с плавающей точкой - 2 байта byte taskType = reader1.ReadByte(); // тип задачи - 1 байт this.variant.Text = reader1.ReadByte().ToString(); // вариант - 1 байт int NRC = reader1.ReadInt16(); // NRC - 2 байта (не имеет никакого значения - параметр все равно задает пользователь при создании сетки) // читаем магические 4 байта - не понятно что это... в спецификации нет, в исходниках тоже, откуда взялись - не понятно. если не прочитать, то не заработает... int magic = reader1.ReadInt32(); //24 байта до DB double DB = reader1.ReadDouble(); // ширина - 8 байт (не имеет никакого значения - определяется автоматически, если надо) double DH = reader1.ReadDouble(); // выстока - 8 байт (не имеет никакого значения - определяется автоматически, если надо) double radius = reader1.ReadDouble(); // радиус отверстия - 8 байт (не имеет никакого значения - определяется автоматически, если надо) double thickness = reader1.ReadDouble(); // толщина - 8 байт. Такие параметры, как толщина и свойства материала мы не можем применить ко всей пластине из-за устаревшей версии sfm файла, поэтому мы просто сохраним их в библиотеку материалов double RsumX = reader1.ReadDouble(); double RsumY = reader1.ReadDouble(); Int32 NLD = reader1.ReadInt32(); // число случаев нагружения - 4 байта Int32 NDF = reader1.ReadInt32(); // число степеней свободы - 4 байта Int32 NCN = reader1.ReadInt32(); // число узлов в элементе - 4 байта Int32 NMAT = reader1.ReadInt32(); // число материалов - 4 байта double E = reader1.ReadDouble(); // свойства материалов - модуль упругости double p = reader1.ReadDouble(); // коэффициент Пуассона double T = reader1.ReadDouble(); // допускаемое напряжение double L = reader1.ReadDouble(); // Int32 numOfAreas = reader1.ReadInt32(); // число зон - 4 байта Int32 numOfPoints = reader1.ReadInt32(); // число узлов зон - 4 байта List <MyPoint> allAreaNodes = new List <MyPoint>(); // список всех узлов, но они тут никак не объединены в зоны //reader1.ReadInt32(); for (i = 0; i < numOfPoints; i++) { int id = reader1.ReadInt16(); reader1.ReadBytes(6); // магические 6 байт. таже фигня что и выше.. и теперь я кажется знаю что это за ересь. в делфях тип record занимет больше памяти чем сумма памяти под ее члены. и для этого случая аж на 6 байт больше. и располагаются они между integer и real...... double x = reader1.ReadDouble(); double y = reader1.ReadDouble(); allAreaNodes.Add(new MyPoint(id, x, y, MyPoint.PointType.IsAreaNode)); } allAreaNodes.Sort((n1, n2) => n1.Id.CompareTo(n2.Id)); AddAreasControl control = new AddAreasControl(this); for (i = 0; i < numOfAreas; i++) { List <MyPoint> areaNodes = new List <MyPoint>(); // список из 8 узлов, составляющих зону. for (int j = 0; j < 8; j++) { int nodeId = reader1.ReadInt16(); // номер узла MyPoint node = allAreaNodes.Find(n => n.Id == nodeId); if (node != null) { areaNodes.Add(node); } } // после того, как мы знаем из каких узлов состоит зона, то мы можем создать точки, линии и дуги - т.е. создать гемоетрию по зоне. // создаем сначала точки List <MyPoint> points = new List <MyPoint>(); // угловые точки зоны for (int j = 0; j < 8; j += 2) { MyPoint existing = currentFullModel.geometryModel.Points.Find(pt => Mathematics.sameNode(pt, areaNodes[j])); if (existing != null) { points.Add(existing); } else { MyPoint newPoint = new MyPoint(this.currentFullModel.geometryModel.NumOfPoints + 1, areaNodes[j].X, areaNodes[j].Y, MyPoint.PointType.IsGeometryPoint); this.currentFullModel.geometryModel.Points.Add(newPoint); points.Add(newPoint); //this.DrawPoint(newPoint, System.Drawing.Color.Blue); this.currentFullModel.geometryModel.NumOfPoints++; } } List <MyStraightLine> slines = new List <MyStraightLine>(); List <MyArc> arcs = new List <MyArc>(); List <MyLine> lines = new List <MyLine>(); // цикл по четырем с сторонам зоны - каждый раз берем три точки с одной стороны - 1,2,3; 3,4,5; 5,6,7 и 7,8,1 for (int j = 0; j <= 6; j = j + 2) { MyPoint p1 = areaNodes[j], p2 = areaNodes[j + 1], p3 = areaNodes[j == 6 ? 0 : j + 2]; double xc, yc; double k1 = Math.Cos(Math.Atan2(p2.Y - p1.Y, p2.X - p1.X)); double k2 = Math.Cos(Math.Atan2(p3.Y - p2.Y, p3.X - p2.X)); if (Math.Abs(k1 - k2) < 0.01) // если коэффициенты наклона совпадают, значит точки лежат на прямой (условие непрерывности выполняется, т.к. известно что все точки принадлежат одной стороне зоны) { // создаем прямую линию MyPoint start = null; MyPoint end = null; foreach (MyPoint point in this.currentFullModel.geometryModel.Points) { if (Mathematics.sameNode(point, p1)) { start = point; } else if (Mathematics.sameNode(point, p3)) { end = point; } } MyStraightLine line = currentFullModel.geometryModel.StraightLines.Find( sline => (sline.StartPoint == start && sline.EndPoint == end) || (sline.StartPoint == end && sline.EndPoint == start) ); if (line != null) { slines.Add(line); lines.Add(line); } else { MyStraightLine newLine = new MyStraightLine(this.currentFullModel.geometryModel.NumOfLines + 1, start, end); this.currentFullModel.geometryModel.StraightLines.Add(newLine); slines.Add(newLine); lines.Add(newLine); this.currentFullModel.geometryModel.NumOfLines++; } } else { double x1 = p1.X, x2 = p2.X, x3 = p3.X; double y1 = p1.Y, y2 = p2.Y, y3 = p3.Y; // затем проверяем каждую сторону зоны - может ли она быть дугой или нет. для этого пытаемся расчитать центр окружности по трем точкам, и если получается, то создаем дугу. if (Math.Abs(x1 * y2 + y1 * x3 - y2 * x3 - x1 * y3 - x2 * y1 + x2 * y3) > 0.1) // если знаменатель не равен нулю { // адские формулы центра окржуности - расчитал Великий Maple // yc = -1.0 / 2.0 * (-x2 * x2 * x1 - y2 * y2 * x1 - x2 * x3 * x3 - x1 * x1 * x3 - y1 * y1 * x3 + x1 * x3 * x3 + x2 * x2 * x3 + y2 * y2 * x3 + x2 * x1 * x1 + x2 * y1 * y1 + x1 * y3 * y3 - x2 * y3 * y3) / (x1 * y2 + y1 * x3 - y2 * x3 - x1 * y3 - x2 * y1 + x2 * y3); // xc = 1.0 / 2.0 * (-x1 * x1 * y3 + x1 * x1 * y2 - x3 * x3 * y2 + y1 * y1 * y2 + y1 * y3 * y3 + y3 * x2 * x2 - y1 * x2 * x2 - y1 * y2 * y2 + y1 * x3 * x3 - y3 * y3 * y2 - y1 * y1 * y3 + y3 * y2 * y2) / (x1 * y2 + y1 * x3 - y2 * x3 - x1 * y3 - x2 * y1 + x2 * y3); // есть формулы попроще: double R1Sqr = x1 * x1 + y1 * y1; double R2Sqr = x2 * x2 + y2 * y2; double R3Sqr = x3 * x3 + y3 * y3; xc = ((R3Sqr - R1Sqr) * (y2 - y1) - (R2Sqr - R1Sqr) * (y3 - y1)) / ((x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1)) / 2.0; yc = ((R2Sqr - R1Sqr) * (x3 - x1) - (R3Sqr - R1Sqr) * (x2 - x1)) / ((x3 - x1) * (y2 - y1) - (x2 - x1) * (y3 - y1)) / 2.0; // ищем в точках точку с такими координатами, если не найдем, то созадим новую MyPoint definedCenter = new MyPoint(xc, yc); MyPoint centerPoint = currentFullModel.geometryModel.Points.Find(pt => Mathematics.sameNode(pt, definedCenter)); // если нет, тогда создаем новую точку - центр дуги if (centerPoint == null) { centerPoint = new MyPoint(this.currentFullModel.geometryModel.NumOfPoints + 1, xc, yc, MyPoint.PointType.IsGeometryPoint); this.currentFullModel.geometryModel.Points.Add(centerPoint); //this.DrawPoint(centerPoint, System.Drawing.Color.Blue); this.currentFullModel.geometryModel.NumOfPoints++; } // и проводим дугу... MyPoint start = null; //MyPoint p2 = null; MyPoint end = null; foreach (MyPoint point in this.currentFullModel.geometryModel.Points) { if (Mathematics.sameNode(point, p1)) { start = point; } else if (Mathematics.sameNode(point, p3)) { end = point; } } bool lineExists = false; foreach (MyArc arc in this.currentFullModel.geometryModel.Arcs) { if ((arc.StartPoint == start && arc.EndPoint == end) || (arc.StartPoint == end && arc.EndPoint == start)) { lineExists = true; arcs.Add(arc); lines.Add(arc); break; } } if (!lineExists) { // пробуем создать дугу с поворотом по часовой стрелке. если это невозоможно, то создадим с поворотом против) //MyArc newArc = new MyArc(this.currentFullModel.geometryModel.NumOfLines + 1, true, start, p2, centerPoint); MyArc newArc = new MyArc(this.currentFullModel.geometryModel.NumOfLines + 1, true, start, end, centerPoint); if (this.TestArc(newArc)) { this.currentFullModel.geometryModel.Arcs.Add(newArc); arcs.Add(newArc); lines.Add(newArc); //this.DrawArc(newArc, Color.Blue); this.currentFullModel.geometryModel.NumOfLines++; } else { //newArc = new MyArc(this.currentFullModel.geometryModel.NumOfLines + 1, false, start, p2, centerPoint); newArc = new MyArc(this.currentFullModel.geometryModel.NumOfLines + 1, false, start, end, centerPoint); if (this.TestArc(newArc)) { this.currentFullModel.geometryModel.Arcs.Add(newArc); arcs.Add(newArc); lines.Add(newArc); //this.DrawArc(newArc, Color.Blue); this.currentFullModel.geometryModel.NumOfLines++; } } } } } } List <MyStraightLine> Segments = new List <MyStraightLine>(); for (int l = 0; l < 8; l++) // этим мы создаем отрезки и соединяем ими узлы зоны { int k = l + 1; if (k == 8) { k = 0; } Segments.Add(new MyStraightLine(0, areaNodes[l], areaNodes[k])); } // эмулируем создание зоны так, как если бы мы создавали ее вручную control.number.Text = (this.currentFullModel.geometryModel.NumOfAreas + 1).ToString(); control.line1.Text = lines[0].Id.ToString(); control.line2.Text = lines[1].Id.ToString(); control.line3.Text = lines[2].Id.ToString(); control.line4.Text = lines[3].Id.ToString(); control.OK(areaNodes); } }
public bool OK(List <MyPoint> formerNodes = null) { MyPoint point = null; bool success = false; int[] lineID = new int[4]; bool[] lineExists = { false, false, false, false }; int numOfArcs = 0; parent.clearSelection(); if (number.TextLength == 0 || line1.TextLength == 0 || line2.TextLength == 0 || line3.TextLength == 0 || line4.TextLength == 0) { errorMessage1.Visible = true; return(success); } if (errorMessage2.Visible) { return(success); } lineID[0] = Convert.ToInt32(line1.Text); lineID[1] = Convert.ToInt32(line2.Text); lineID[2] = Convert.ToInt32(line3.Text); lineID[3] = Convert.ToInt32(line4.Text); if (lineID.Distinct().ToArray().Length != 4) { MessageBox.Show("Зона не может содержать повторяющиеся линии!"); return(success); } List <MyPoint> points = new List <MyPoint>(); List <MyStraightLine> slines = new List <MyStraightLine>(); List <MyArc> arcs = new List <MyArc>(); List <MyLine> lines = new List <MyLine>(); // ищем линии for (int i = 0; i < 4; i++) { MyLine currentLine; MyStraightLine line = parent.currentFullModel.geometryModel.StraightLines.Find(ln => ln.Id == lineID[i]); MyArc arc = parent.currentFullModel.geometryModel.Arcs.Find(a => a.Id == lineID[i]); if (line == null) { currentLine = arc; } else { currentLine = line; } if (currentLine != null) { lineExists[i] = true; bool neighborLineExists = false; // цикл по всем зонам MyArea area; if (line == null) { area = parent.currentFullModel.geometryModel.Areas.Find(a => a.Arcs.IndexOf(arc) != -1); } else { area = parent.currentFullModel.geometryModel.Areas.Find(a => a.StraightLines.IndexOf(line) != -1); } if (area != null) { if (points.IndexOf(currentLine.EndPoint) == -1) { points.Add(currentLine.EndPoint); } if (points.IndexOf(currentLine.StartPoint) == -1) { points.Add(currentLine.StartPoint); } neighborLineExists = true; } if (!neighborLineExists) { if (points.IndexOf(currentLine.StartPoint) == -1) { points.Add(currentLine.StartPoint); } if (points.IndexOf(currentLine.EndPoint) == -1) { points.Add(currentLine.EndPoint); } } lineExists[i] = true; if (line == null) { arcs.Add(arc); numOfArcs++; } else { slines.Add(line); } lines.Add(currentLine); } } // закончили поиск линий if (!lineExists.Contains(false)) { // указанные линии существуют, но надо еще проверить, образуют ли они замкнутую зону errorMessage4.Visible = false; errorAreaExists.Visible = false; if (points.Count == 4) // условие, определяющее то, что линии образуют замкнутую область { errorMessage3.Visible = false; // проверяем число зон, в которым принадлежать линии foreach (MyLine l in lines) { if (l.Areas.Count == 2) { clearLines(); errorTwoAreas.Visible = true; return(success); } } // проверяем, нет ли такой зоны уже if (lines.Find(l => l.Areas.Count != 1) == null) //lines[0].Areas.Count == 1 && lines[1].Areas.Count == 1 && lines[2].Areas.Count == 1 && lines[3].Areas.Count == 1) { if (lines.ConvertAll(l => parent.currentFullModel.geometryModel.Areas.Find(ar => ar.Id == l.Areas.First()).Id).Distinct().Count() == 1) { errorAreaExists.Visible = true; clearLines(); return(success); } } // определяем первую линию в списке линий int firstLine = 0; for (int i = 0; i < 4; i++) { if (lines[i].Areas.Count == 1) { firstLine = i; break; } } if (firstLine != 0) { MyLine tempLine = lines[0]; lines[0] = lines[firstLine]; lines[firstLine] = tempLine; } // определяем вторую линию в списке линий int secondLine = 1; point = lines[0].EndPoint; for (int i = 1; i < 4; i++) { if (point == lines[i].EndPoint || point == lines[i].StartPoint) { secondLine = i; break; } } if (secondLine != 1) { MyLine tempLine = lines[1]; lines[1] = lines[secondLine]; lines[secondLine] = tempLine; } // определяем четвертую (последниюю) линию в списке линий. определения третий линии нет, и это не ошибка. она определится автоматом int lastLine = 3; point = lines[0].StartPoint; for (int i = 2; i < 4; i++) { if (point == lines[i].EndPoint || point == lines[i].StartPoint) { lastLine = i; break; } } if (lastLine != 3) { MyLine tempLine = lines[3]; lines[3] = lines[lastLine]; lines[lastLine] = tempLine; } points.Clear(); int newAreaId; if (!int.TryParse(number.Text, out newAreaId)) { errorMessage2.Visible = true; number.Focus(); return(success); } if (parent.currentFullModel.geometryModel.Areas.Count > 0) { if (lines.All(l => l.Areas.Count == 0)) { MessageBox.Show("Невозможно образовать зону: не прилегает ни к одной из существующих зон"); return(success); } } points.Add(lines[0].StartPoint); points.Add(lines[0].EndPoint); if (lines[1].StartPoint != points[1]) { points.Add(lines[1].StartPoint); } else { points.Add(lines[1].EndPoint); } if (lines[3].StartPoint != points[0]) { points.Add(lines[3].StartPoint); } else { points.Add(lines[3].EndPoint); } double S = Square(points[0], points[1]) + Square(points[1], points[2]) + Square(points[2], points[3]) + Square(points[3], points[0]); if (S > 0.0) { MyPoint tempPoint = points[2]; points[2] = points[3]; points[3] = tempPoint; tempPoint = points[0]; points[0] = points[1]; points[1] = tempPoint; MyLine tempLine = lines[1]; lines[1] = lines[3]; lines[3] = tempLine; } MyPoint[] middlePoints = new MyPoint[4]; for (int i = 0; i < 4; i++) { middlePoints[i] = new MyPoint(0, 0, 0); } // если импортируем геометрию, возможно узлы уже двигали // считываем инфу оттуда if (formerNodes != null) { for (int j = 0; j < 4; j++) { MyPoint p1 = points[j]; MyPoint p2 = points[j == 3 ? 0 : j + 1]; for (int i = 1; i < 8; i += 2) { MyPoint f1 = formerNodes[i - 1]; MyPoint f2 = formerNodes[i]; MyPoint f3 = formerNodes[i == 7 ? 0 : i + 1]; if (Mathematics.sameNode(f1, p1) && Mathematics.sameNode(f3, p2) || Mathematics.sameNode(f1, p2) && Mathematics.sameNode(f3, p1)) { middlePoints[j].X = f2.X; middlePoints[j].Y = f2.Y; } } } } // иначе тыкаем узлы на середины линий. Ручками, конечно, ручками :( else { if (numOfArcs == 0) { middlePoints[0].X = points[0].X + (points[1].X - points[0].X) / 2; middlePoints[0].Y = points[0].Y + (points[1].Y - points[0].Y) / 2; middlePoints[1].X = points[1].X + (points[2].X - points[1].X) / 2; middlePoints[1].Y = points[1].Y + (points[2].Y - points[1].Y) / 2; middlePoints[2].X = points[2].X + (points[3].X - points[2].X) / 2; middlePoints[2].Y = points[2].Y + (points[3].Y - points[2].Y) / 2; middlePoints[3].X = points[3].X + (points[0].X - points[3].X) / 2; middlePoints[3].Y = points[3].Y + (points[0].Y - points[3].Y) / 2; } else { for (int i = 0; i < 4; i++) { int m = i + 1; if (m == 4) { m = 0; } MyArc tempArc = formAnArc(points[i], points[m]); if (tempArc != null) { double startAngle = (180.0 / Math.PI) * ProjectForm.ArcAngle(tempArc, tempArc.StartPoint); // вычисляем углы начальной и конечной точек дуги - меряются они от оси Х против часовой стрелки (в градусах) double endAngle = (180.0 / Math.PI) * ProjectForm.ArcAngle(tempArc, tempArc.EndPoint); double centerAngle = 0; // угол от оси Х до точки, делящей дугу по полам double sweepAngle = 0; // угол дуги if (tempArc.Clockwise && startAngle > endAngle) { sweepAngle = (startAngle - endAngle); } if (tempArc.Clockwise && startAngle < endAngle) { sweepAngle = 360.0 - (endAngle - startAngle); } if (!tempArc.Clockwise && startAngle > endAngle) { sweepAngle = 360.0 - (startAngle - endAngle); } if (!tempArc.Clockwise && startAngle < endAngle) { sweepAngle = (endAngle - startAngle); } if (sweepAngle > 0.0 && sweepAngle <= 180.0) { if (tempArc.Clockwise) { centerAngle = startAngle - sweepAngle / 2.0; double X, Y, R; R = Mathematics.FindDist(tempArc.CenterPoint, tempArc.StartPoint); X = R * Math.Cos(centerAngle * (Math.PI / 180.0)); Y = R * Math.Sin(centerAngle * (Math.PI / 180.0)); X += tempArc.CenterPoint.X; Y += tempArc.CenterPoint.Y; middlePoints[i].X = X; middlePoints[i].Y = Y; } else { centerAngle = startAngle + sweepAngle / 2.0; double X, Y, R; R = Mathematics.FindDist(tempArc.CenterPoint, tempArc.StartPoint); X = R * Math.Cos(centerAngle * (Math.PI / 180.0)); Y = R * Math.Sin(centerAngle * (Math.PI / 180.0)); X += tempArc.CenterPoint.X; Y += tempArc.CenterPoint.Y; middlePoints[i].X = X; middlePoints[i].Y = Y; } } if (sweepAngle < 0.0 && sweepAngle >= -180.0) { if (tempArc.Clockwise) { centerAngle = startAngle + sweepAngle / 2.0; double X, Y, R; R = Mathematics.FindDist(tempArc.CenterPoint, tempArc.StartPoint); X = R * Math.Cos(centerAngle * (Math.PI / 180.0)); Y = R * Math.Sin(centerAngle * (Math.PI / 180.0)); X += tempArc.CenterPoint.X; Y += tempArc.CenterPoint.Y; middlePoints[i].X = X; middlePoints[i].Y = Y; } else { centerAngle = startAngle - sweepAngle / 2.0; double X, Y, R; R = Mathematics.FindDist(tempArc.CenterPoint, tempArc.StartPoint); X = R * Math.Cos(centerAngle * (Math.PI / 180.0)); Y = R * Math.Sin(centerAngle * (Math.PI / 180.0)); X += tempArc.CenterPoint.X; Y += tempArc.CenterPoint.Y; middlePoints[i].X = X; middlePoints[i].Y = Y; } } } else { middlePoints[i].X = points[i].X + (points[m].X - points[i].X) / 2; middlePoints[i].Y = points[i].Y + (points[m].Y - points[i].Y) / 2; } } } } List <MyPoint> Nodes = new List <MyPoint>(); for (int i = 0; i < 4; i++) // этим мы обеспечиваем чередование угловых узлов зоны с промежуточными узлами, а также следим за сковозной нумерацией узлов для всех зон пластины { bool pointExists = false; bool middlePointExits = false; // Находим все зоны, содержащие текущую точку List <MyArea> areas = parent.currentFullModel.geometryModel.Areas.FindAll(a => a.Nodes.Any(n => Mathematics.sameNode(n, points[i]) || Mathematics.sameNode(n, middlePoints[i]))); areas.Sort((a, b) => a.Id.CompareTo(b.Id)); foreach (MyArea area in areas) // просматриваем все зоны { int borderSideNumber = 0; // номер стороны существующей зоны, которая соприкасается с другой зоной. номер человеческий и начинается с 1 а не с 0 MyPoint node = area.Nodes.Find(n => Mathematics.sameNode(n, points[i]) && !Nodes.Contains(n)); if (node != null) { Nodes.Add(node); // добавляем в список узлов зоны узел, который уже есть в списке узлов другой зоны pointExists = true; } node = area.Nodes.Find(n => Mathematics.sameNode(n, middlePoints[i]) && !Nodes.Contains(n)); if (node != null) { Nodes.Add(node); // добавляем в список узлов зоны узел, который уже есть в списке узлов другой зоны middlePointExits = true; borderSideNumber = (area.Nodes.IndexOf(node) + 1) / 2; parent.currentFullModel.geometryModel.joinTable[area.Id - 1, borderSideNumber - 1] = newAreaId; // т.к. area.Id и borderSideNumber - это индексы, а нумерация индексов с 0, то отнимаем 1 parent.currentFullModel.geometryModel.joinTable[newAreaId - 1, i] = area.Id; } } if (!pointExists) // если пройдя по всем зонам, мы не нашли там таких узлов, то создаем новый объект и добавляем его в список зоны { parent.currentFullModel.geometryModel.NumOfAreaNodes++; Nodes.Add(new MyPoint(parent.currentFullModel.geometryModel.NumOfAreaNodes, points[i].X, points[i].Y, MyPoint.PointType.IsAreaNode)); foreach (MyPoint p in parent.currentFullModel.geometryModel.Points) // задаем узлу зоны в соответствие точку геометрии и наоборот { if (p.X == points[i].X && p.Y == points[i].Y) { Nodes[Nodes.Count - 1].PointReference = p; p.NodeReference = Nodes[Nodes.Count - 1]; break; } } } if (!middlePointExits) // если пройдя по всем зонам, мы не нашли там таких узлов, то создаем новый объект и добавляем его в список зоны { parent.currentFullModel.geometryModel.NumOfAreaNodes++; Nodes.Add(new MyPoint(parent.currentFullModel.geometryModel.NumOfAreaNodes, middlePoints[i].X, middlePoints[i].Y, MyPoint.PointType.IsAreaNode)); foreach (MyPoint p in parent.currentFullModel.geometryModel.Points) // задаем узлу зоны в соответствие точку геометрии и наоборот { if (p.X == middlePoints[i].X && p.Y == middlePoints[i].Y) { Nodes[Nodes.Count - 1].PointReference = p; p.NodeReference = Nodes[Nodes.Count - 1]; break; } } } } List <MyStraightLine> Segments = new List <MyStraightLine>(); for (int i = 0; i < 8; i++) // этим мы создаем отрезки и соединяем ими узлы зоны { int k = i + 1; if (k == 8) { k = 0; } Segments.Add(new MyStraightLine(0, Nodes[i], Nodes[k])); } MyArea newArea = new MyArea(newAreaId, lines, slines, Segments, points, arcs, Nodes); parent.currentFullModel.geometryModel.Areas.Add(newArea); success = true; parent.currentFullModel.geometryModel.NumOfAreas++; foreach (MyLine l in lines) { l.Areas.Add(newAreaId); } number.Text = (parent.currentFullModel.geometryModel.NumOfAreas + 1).ToString(); parent.showOnlyAreas.Checked = true; } else { errorMessage3.Visible = true; } } else { errorMessage4.Visible = true; } return(success); }