// ввод новой трассы public static void GetTrace(List <Trace> trcList, List <Piquet> pqList, Piquet start) { foreach (var trace in trcList.Where(t => t.From == start.Name)) { var exists = false; var trace1 = trace; foreach (var piquet in pqList.Where(p => p.Name == trace1.To)) { if (piquet.Step > start.Step + 1) { var tmpPq = GetPiquet(trace, start, false); piquet.X = tmpPq.X; piquet.Y = tmpPq.Y; piquet.Z = tmpPq.Z; piquet.Step = tmpPq.Step; piquet.Distance = tmpPq.Distance; GetTrace(trcList, pqList, piquet); } exists = true; } if (exists) { continue; } var pq = GetPiquet(trace, start, false); pq.Name = trace.To; pq.Note = trace.Note; pqList.Add(pq); GetTrace(trcList, pqList, pq); } foreach (var trace in trcList.Where(t => t.To == start.Name)) { var exists = false; var trace1 = trace; foreach (var piquet in pqList.Where(p => p.Name == trace1.From)) { if (piquet.Step > start.Step + 1) { var tmpPq = GetPiquet(trace, start, true); piquet.X = tmpPq.X; piquet.Y = tmpPq.Y; piquet.Z = tmpPq.Z; piquet.Step = tmpPq.Step; piquet.Distance = tmpPq.Distance; GetTrace(trcList, pqList, piquet); } exists = true; } if (exists) { continue; } var pq = GetPiquet(trace, start, true); pq.Name = trace.From; pq.Note = trace.Note; pqList.Add(pq); GetTrace(trcList, pqList, pq); } }
public Piquet(Piquet piquet) { Name = piquet.Name; X = piquet.X; Y = piquet.Y; Note = piquet.Note; Step = piquet.Step; Delta = piquet.Delta; Distance = piquet.Distance; Offset = new Vector(piquet.Offset); }
// получение координат пикета из данных о трассе private static Piquet GetPiquet(Trace trace, Piquet start, bool back) { var piquet = new Piquet { X = start.X + trace.Tape * Math.Cos(trace.Clino * (back ? -1 : 1) * MathConst.Rad) * Math.Sin((trace.Azimuth + (back ? 180 : 0)) * MathConst.Rad), Y = start.Y + trace.Tape * Math.Cos(trace.Clino * (back ? -1 : 1) * MathConst.Rad) * Math.Cos((trace.Azimuth + (back ? 180 : 0)) * MathConst.Rad), Z = start.Z + trace.Tape * Math.Sin(trace.Clino * (back ? -1 : 1) * MathConst.Rad), Step = start.Step + 1, Distance = start.Distance + trace.Tape }; return(piquet); }
// получение цепочки трасс до начального пикета public static List <Trace> GetString(List <Piquet> stringPqList, List <Trace> traceList, Piquet prevous, List <Piquet> piquetList) { var result = new List <Trace>(); if (traceList == null || traceList.Count == 0) { return(new List <Trace>()); } foreach (var trace in traceList.Where(trc => trc.From == prevous.Name && !stringPqList.Select(pq => pq.Name).Contains(trc.To))) { var exPiq = piquetList.Find(p => p.Name == trace.To); if (exPiq.Step <= prevous.Step) { continue; } var current = new Piquet(exPiq); stringPqList.Add(current); result.Add(trace); result.AddRange(GetString(stringPqList, traceList, current, piquetList)); } foreach (var trace in traceList.Where(trc => trc.To == prevous.Name && !stringPqList.Select(pq => pq.Name).Contains(trc.From))) { var exPiq = piquetList.Find(p => p.Name == trace.From); if (exPiq.Step <= prevous.Step) { continue; } var current = new Piquet(exPiq); stringPqList.Add(current); result.Add(trace); result.AddRange(GetString(stringPqList, traceList, current, piquetList)); } return(result); }
// пункт меню Сохранить private void SaveMenu_Click(object sender, EventArgs e) { if (sdSave.ShowDialog() != DialogResult.OK) { return; } _traceList = new List <Trace>(); _piquetLst = new List <Piquet>(); foreach (DataGridViewRow row in dgTopo.Rows) { if (row.Cells[0].Value == null) { continue; } var trace = new Trace { From = row.Cells["ClFrom"].Value.ToString(), To = row.Cells["ClTo"].Value.ToString(), Tape = Convert.ToDouble(row.Cells["ClLen"].Value.ToString().Replace('.', ',')), Azimuth = Convert.ToDouble(row.Cells["ClAz"].Value.ToString().Replace('.', ',')), Clino = Convert.ToDouble(row.Cells["ClClino"].Value.ToString().Replace('.', ',')), Note = row.Cells["ClNote"].Value == null ? "" : row.Cells["ClNote"].Value.ToString() }; var down = row.Cells["ClDown"].Value.ToString().Replace('.', ','); var dVals = down.Split('\\'); if (dVals.Count() == 2) { trace.FromDown = Convert.ToDouble(dVals[0]); trace.Down = Convert.ToDouble(dVals[1]); } else { trace.Down = Convert.ToDouble(down); } var up = row.Cells["ClUp"].Value.ToString().Replace('.', ','); var uVals = up.Split('\\'); if (uVals.Count() == 2) { trace.FromUp = Convert.ToDouble(uVals[0]); trace.Up = Convert.ToDouble(uVals[1]); } else { trace.Up = Convert.ToDouble(up); } var left = row.Cells["ClLeft"].Value.ToString().Replace('.', ','); var lVals = left.Split('\\'); if (lVals.Count() == 2) { trace.FromLeft = Convert.ToDouble(lVals[0]); trace.Left = Convert.ToDouble(lVals[1]); } else { trace.Left = Convert.ToDouble(left); } var right = row.Cells["ClRight"].Value.ToString().Replace('.', ','); var rVals = right.Split('\\'); if (rVals.Count() == 2) { trace.FromRight = Convert.ToDouble(rVals[0]); trace.Right = Convert.ToDouble(rVals[1]); } else { trace.Right = Convert.ToDouble(right); } _traceList.Add(trace); } var start = new Piquet { Delta = 0D, Name = _traceList[0].From, X = 0D, Y = 0D, Z = 0D, Step = 0, Note = "" }; _piquetLst.Add(start); TopoLib.GetTrace(_traceList, _piquetLst, start); var min = 0.0; var max = 0.0; foreach (var piquet in _piquetLst) { min = Math.Min(min, piquet.Z); max = Math.Max(max, piquet.Z); } var rings = TopoLib.GetAllRing(_traceList, _piquetLst, start); MessageBox.Show(string.Format("Длина: {0:N0}м. Глубина: {1:N0}м. Неточность: {2:F3}%", _traceList.Sum(t => t.Tape), max - min, rings.Count > 0 ? (rings.Sum(r => r.Offset.Length) / rings.Sum(r => r.Length) * 100) : 0)); foreach (var ring in rings) { foreach (var point in ring.Points) { TopoLib.PiquetsCorrection(ring, _traceList, _piquetLst, point, point.Offset); } } using (var fl = new FileStream(sdSave.FileName, FileMode.Create)) { using (var zipp = new ZipOutputStream(fl)) { zipp.PutNextEntry("trace.xml"); using (var wr = new MemoryStream()) { var writer = XmlWriter.Create(wr); writer.WriteStartDocument(); writer.WriteStartElement("cave"); writer.WriteElementString("title", _surData.Name); writer.WriteStartElement("survey"); writer.WriteElementString("date", _surData.Date == null?"":_surData.Date.Value.ToString("dd.MM.yyyy")); writer.WriteStartElement("team"); if (_surData.Team != null) { foreach (var item in _surData.Team) { writer.WriteElementString("name", item); } } writer.WriteEndElement(); foreach (var trace in _traceList) { writer.WriteStartElement("segment"); writer.WriteElementString("from", trace.From); writer.WriteElementString("to", trace.To); writer.WriteElementString("tape", trace.Tape.ToString(CultureInfo.InvariantCulture)); writer.WriteElementString("compass", trace.Azimuth.ToString(CultureInfo.InvariantCulture)); writer.WriteElementString("clino", trace.Clino.ToString(CultureInfo.InvariantCulture)); writer.WriteElementString("left", trace.Left.ToString(CultureInfo.InvariantCulture)); writer.WriteElementString("right", trace.Right.ToString(CultureInfo.InvariantCulture)); writer.WriteElementString("up", trace.Up.ToString(CultureInfo.InvariantCulture)); writer.WriteElementString("down", trace.Down.ToString(CultureInfo.InvariantCulture)); if (trace.FromLeft > 0) { writer.WriteElementString("f_left", trace.FromLeft.ToString(CultureInfo.InvariantCulture)); } if (trace.FromRight > 0) { writer.WriteElementString("f_right", trace.FromRight.ToString(CultureInfo.InvariantCulture)); } if (trace.FromUp > 0) { writer.WriteElementString("f_up", trace.FromUp.ToString(CultureInfo.InvariantCulture)); } if (trace.FromDown > 0) { writer.WriteElementString("f_down", trace.FromDown.ToString(CultureInfo.InvariantCulture)); } if (!string.IsNullOrEmpty(trace.Note)) { writer.WriteElementString("note", trace.Note); } writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndElement(); writer.WriteEndDocument(); writer.Flush(); zipp.Write(wr.ToArray(), 0, (int)wr.Length); } zipp.PutNextEntry("piquet.xml"); using (var wr = new MemoryStream()) { var writer = XmlWriter.Create(wr); writer.WriteStartDocument(); writer.WriteStartElement("cave"); foreach (var piquet in _piquetLst) { writer.WriteStartElement("piquet"); writer.WriteElementString("name", piquet.Name); writer.WriteElementString("x", piquet.X.ToString(CultureInfo.InvariantCulture)); writer.WriteElementString("y", piquet.Y.ToString(CultureInfo.InvariantCulture)); writer.WriteElementString("z", piquet.Z.ToString(CultureInfo.InvariantCulture)); writer.WriteElementString("step", piquet.Step.ToString(CultureInfo.InvariantCulture)); writer.WriteElementString("note", piquet.Note); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndDocument(); writer.Flush(); zipp.Write(wr.ToArray(), 0, (int)wr.Length); } zipp.PutNextEntry("spline.xml"); using (var wr = new MemoryStream()) { var writer = XmlWriter.Create(wr); writer.WriteStartDocument(); writer.WriteStartElement("cave"); foreach (var spline in _splineList) { writer.WriteStartElement("spline"); writer.WriteElementString("name", spline.Name); writer.WriteElementString("type", spline.Type.ToString()); writer.WriteElementString("dirrection", spline.Dirrection.ToString()); writer.WriteStartElement("points"); foreach (var point in spline.PointList) { writer.WriteStartElement("point"); writer.WriteElementString("x", point.Point.X.ToString()); writer.WriteElementString("y", point.Point.Y.ToString()); writer.WriteElementString("ra_x", point.Ra.X.ToString()); writer.WriteElementString("ra_y", point.Ra.Y.ToString()); writer.WriteElementString("rb_x", point.Rb.X.ToString()); writer.WriteElementString("rb_y", point.Rb.Y.ToString()); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndDocument(); writer.Flush(); zipp.Write(wr.ToArray(), 0, (int)wr.Length); } zipp.PutNextEntry("cgn.xml"); using (var wr = new MemoryStream()) { var writer = XmlWriter.Create(wr); writer.WriteStartDocument(); writer.WriteStartElement("cave"); foreach (var cgn in _cgnList) { writer.WriteStartElement("cgn"); writer.WriteElementString("name", cgn.Name); writer.WriteElementString("type", cgn.Type.ToString()); writer.WriteElementString("x", cgn.Point.X.ToString()); writer.WriteElementString("y", cgn.Point.Y.ToString()); writer.WriteElementString("angle", cgn.Angle.ToString()); writer.WriteEndElement(); } writer.WriteEndElement(); writer.WriteEndDocument(); writer.Flush(); zipp.Write(wr.ToArray(), 0, (int)wr.Length); } } } MessageBox.Show(Resources.Saved); }
// пункт меню Загрузить private void LoadMenu_Click(object sender, EventArgs e) { if (odLoad.ShowDialog() != DialogResult.OK) { return; } try { dgTopo.Rows.Clear(); _traceList = new List <Trace>(); _piquetLst = new List <Piquet>(); _cgnList = new List <Cgn>(); _splineList = new List <Spline>(); using (var zip = ZipFile.Read(odLoad.FileName)) { using (var fl = new MemoryStream()) { var ent = zip["trace.xml"]; ent.Extract(fl); fl.Position = 0; using (var reader = XmlReader.Create(fl)) { var trc = new Trace(); while (reader.Read()) { if (reader.NodeType == XmlNodeType.Element) { switch (reader.Name) { case "team": _surData.Team = new List <string>(); break; case "name": reader.Read(); _surData.Team.Add(reader.Value); break; case "date": reader.Read(); try { _surData.Date = Convert.ToDateTime(reader.Value); } catch { _surData.Date = new DateTime(); } break; case "title": reader.Read(); _surData.Name = reader.Value; break; case "segment": dgTopo.Rows.Add(); trc = new Trace(); break; case "from": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[0].Value = reader.Value; trc.From = reader.Value; break; case "to": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[1].Value = reader.Value; trc.To = reader.Value; break; case "tape": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[2].Value = reader.Value; trc.Tape = Convert.ToDouble(reader.Value.Replace('.', ',')); break; case "compass": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[3].Value = reader.Value; trc.Azimuth = Convert.ToDouble(reader.Value.Replace('.', ',')); break; case "clino": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[4].Value = reader.Value; trc.Clino = Convert.ToDouble(reader.Value.Replace('.', ',')); break; case "left": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[5].Value = reader.Value; trc.Left = Convert.ToDouble(reader.Value.Replace('.', ',')); break; case "right": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[6].Value = reader.Value; trc.Right = Convert.ToDouble(reader.Value.Replace('.', ',')); break; case "up": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[7].Value = reader.Value; trc.Up = Convert.ToDouble(reader.Value.Replace('.', ',')); break; case "down": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[8].Value = reader.Value; trc.Down = Convert.ToDouble(reader.Value.Replace('.', ',')); break; case "f_left": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[5].Value = reader.Value + "\\" + dgTopo.Rows[dgTopo.RowCount - 2].Cells[5].Value; trc.FromLeft = Convert.ToDouble(reader.Value.Replace('.', ',')); break; case "f_right": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[6].Value = reader.Value + "\\" + dgTopo.Rows[dgTopo.RowCount - 2].Cells[6].Value; trc.FromRight = Convert.ToDouble(reader.Value.Replace('.', ',')); break; case "f_up": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[7].Value = reader.Value + "\\" + dgTopo.Rows[dgTopo.RowCount - 2].Cells[7].Value; trc.FromUp = Convert.ToDouble(reader.Value.Replace('.', ',')); break; case "f_down": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[8].Value = reader.Value + "\\" + dgTopo.Rows[dgTopo.RowCount - 2].Cells[8].Value; trc.FromDown = Convert.ToDouble(reader.Value.Replace('.', ',')); break; case "note": reader.Read(); dgTopo.Rows[dgTopo.RowCount - 2].Cells[9].Value = reader.Value; trc.Note = reader.Value; break; } } else if (reader.NodeType == XmlNodeType.EndElement && reader.Name == "segment") { _traceList.Add(trc); } } //while(reader.Read()) } } using (var fl = new MemoryStream()) { var pqEnt = zip["piquet.xml"]; pqEnt.Extract(fl); fl.Position = 0; using (var pqReader = XmlReader.Create(fl)) { var piquet = new Piquet(); while (pqReader.Read()) { if (pqReader.NodeType == XmlNodeType.Element) { switch (pqReader.Name) { case "piquet": if (pqReader.IsEmptyElement) { break; } piquet = new Piquet(); break; case "name": if (pqReader.IsEmptyElement) { break; } pqReader.Read(); piquet.Name = pqReader.Value; break; case "note": if (pqReader.IsEmptyElement) { break; } pqReader.Read(); piquet.Note = pqReader.Value; break; case "x": if (pqReader.IsEmptyElement) { break; } pqReader.Read(); piquet.X = Convert.ToDouble(pqReader.Value.Replace('.', ',')); break; case "y": if (pqReader.IsEmptyElement) { break; } pqReader.Read(); piquet.Y = Convert.ToDouble(pqReader.Value.Replace('.', ',')); break; case "z": if (pqReader.IsEmptyElement) { break; } pqReader.Read(); piquet.Z = Convert.ToDouble(pqReader.Value.Replace('.', ',')); break; case "step": pqReader.Read(); piquet.Step = Convert.ToInt32(pqReader.Value); break; } } else if (pqReader.NodeType == XmlNodeType.EndElement && pqReader.Name == "piquet") { _piquetLst.Add(piquet); } } //while(reader.Read()) } } using (var fl = new MemoryStream()) { var splEnt = zip["spline.xml"]; try { splEnt.Extract(fl); fl.Position = 0; using (var splReader = XmlReader.Create(fl)) { var spline = new Spline(); while (splReader.Read()) { if (splReader.NodeType == XmlNodeType.Element) { switch (splReader.Name) { case "spline": if (splReader.IsEmptyElement) { break; } spline = new Spline(); break; case "name": if (splReader.IsEmptyElement) { break; } splReader.Read(); spline.Name = splReader.Value; break; case "type": if (splReader.IsEmptyElement) { break; } splReader.Read(); spline.Type = (SplineType)Enum.Parse(typeof(SplineType), splReader.Value); break; case "dirrection": if (splReader.IsEmptyElement) { break; } splReader.Read(); spline.Dirrection = (SplineDirrection) Enum.Parse(typeof(SplineDirrection), splReader.Value); break; case "points": while (splReader.Read() && (splReader.NodeType != XmlNodeType.EndElement || splReader.Name != "points")) { var tX = 0D; var tY = 0D; var tRaX = 0D; var tRaY = 0D; var tRbX = 0D; var tRbY = 0D; while (splReader.Read() && (splReader.NodeType != XmlNodeType.EndElement || splReader.Name != "point")) { if (splReader.NodeType == XmlNodeType.Element) { switch (splReader.Name) { case "x": if (splReader.IsEmptyElement) { break; } splReader.Read(); tX = Convert.ToDouble(splReader.Value.Replace('.', ',')); break; case "y": if (splReader.IsEmptyElement) { break; } splReader.Read(); tY = Convert.ToDouble(splReader.Value.Replace('.', ',')); break; case "ra_x": if (splReader.IsEmptyElement) { break; } splReader.Read(); tRaX = Convert.ToDouble(splReader.Value.Replace('.', ',')); break; case "ra_y": if (splReader.IsEmptyElement) { break; } splReader.Read(); tRaY = Convert.ToDouble(splReader.Value.Replace('.', ',')); break; case "rb_x": if (splReader.IsEmptyElement) { break; } splReader.Read(); tRbX = Convert.ToDouble(splReader.Value.Replace('.', ',')); break; case "rb_y": if (splReader.IsEmptyElement) { break; } splReader.Read(); tRbY = Convert.ToDouble(splReader.Value.Replace('.', ',')); break; } } } spline.PointList.Add(new SplinePoint((float)tX, (float)tY, (float)tRaX, (float)tRaY, (float)tRbX, (float)tRbY)); } break; } } else if (splReader.NodeType == XmlNodeType.EndElement && splReader.Name == "spline") { _splineList.Add(spline); } } //while(reader.Read()) } } catch { } } using (var fl = new MemoryStream()) { var splEnt = zip["cgn.xml"]; try { splEnt.Extract(fl); fl.Position = 0; using (var cgnReader = XmlReader.Create(fl)) { var x = 0D; var y = 0D; var changex = false; var changey = false; var cgn = new Cgn(); while (cgnReader.Read()) { if (cgnReader.NodeType == XmlNodeType.Element) { switch (cgnReader.Name) { case "cgn": if (cgnReader.IsEmptyElement) { break; } cgn = new Cgn(); break; case "name": if (cgnReader.IsEmptyElement) { break; } cgnReader.Read(); cgn.Name = cgnReader.Value; break; case "type": if (cgnReader.IsEmptyElement) { break; } cgnReader.Read(); cgn.Type = (CgnType)Enum.Parse(typeof(CgnType), cgnReader.Value); break; case "x": if (cgnReader.IsEmptyElement) { break; } cgnReader.Read(); x = Convert.ToDouble(cgnReader.Value.Replace('.', ',')); changex = true; if (changex && changey) { cgn.Point = new Point((float)x, (float)y); } break; case "y": if (cgnReader.IsEmptyElement) { break; } cgnReader.Read(); y = Convert.ToDouble(cgnReader.Value.Replace('.', ',')); changey = true; if (changex && changey) { cgn.Point = new Point((float)x, (float)y); } break; case "angle": if (cgnReader.IsEmptyElement) { break; } cgnReader.Read(); cgn.Angle = Convert.ToDouble(cgnReader.Value.Replace('.', ',')); break; } } else if (cgnReader.NodeType == XmlNodeType.EndElement && cgnReader.Name == "cgn") { _cgnList.Add(cgn); x = 0D; y = 0D; changex = false; changey = false; } } //while(reader.Read()) } } catch { } } } } catch (Exception) { MessageBox.Show(Resources.FileReadError, Resources.ETopo, MessageBoxButtons.OK, MessageBoxIcon.Error); } finally { var min = 0.0; var max = 0.0; foreach (var piquet in _piquetLst) { min = Math.Min(min, piquet.Z); max = Math.Max(max, piquet.Z); } } }
// корректировка координат пикетов public static void PiquetsCorrection(Ring ring, List <Trace> trcList, List <Piquet> pqList, Piquet start, Vector offset) { foreach (var trace in trcList.Where(t => t.From == start.Name)) { var currentPiquet = pqList.Find(p => p.Name == trace.To); if (currentPiquet.Step == start.Step + 1 && !ring.Points.Select(p => p.Name).Contains(currentPiquet.Name)) { currentPiquet.Correct(offset); PiquetsCorrection(ring, trcList, pqList, currentPiquet, offset); } } foreach (var trace in trcList.Where(t => t.To == start.Name)) { var currentPiquet = pqList.Find(p => p.Name == trace.From); if (currentPiquet.Step == start.Step + 1 && !ring.Points.Select(p => p.Name).Contains(currentPiquet.Name)) { currentPiquet.Correct(offset); PiquetsCorrection(ring, trcList, pqList, currentPiquet, offset); } } }
// получение всех кольцовок public static List <Ring> GetAllRing(List <Trace> trcLst, List <Piquet> piquets, Piquet start) { var result = new List <Ring>(); var pqTemp = new List <Piquet> { start }; var pString = GetString(pqTemp, trcLst, start, piquets); foreach (var trace in trcLst.Where(trc => !pString.Contains(trc))) { var pqPair = pqTemp.Where(pq => pq.Name == trace.From || pq.Name == trace.To).ToList(); if (pqPair.Count != 2) { continue; } var step = Math.Max(pqPair[0].Step, pqPair[1].Step); var pq1 = pqPair[0]; var pq2 = pqPair[1]; var lst1 = new List <Piquet> { pq1 }; var lst2 = new List <Piquet> { pq2 }; while (pq1 != pq2) { if (pq1.Step == step) { Piquet pq = null; foreach (var trace1 in trcLst.Where(t => t.To == pq1.Name)) { pq = pqTemp.Find(p => p.Name == trace1.From && p.Step == step - 1); } if (pq == null) { foreach (var trace1 in trcLst.Where(t => t.From == pq1.Name)) { pq = pqTemp.Find(p => p.Name == trace1.To && p.Step == step - 1); } } if (pq == null) { continue; } pq1 = pq; lst1.Add(pq1); } if (pq2.Step == step) { Piquet pq = null; foreach (var trace1 in trcLst.Where(t => t.To == pq2.Name)) { pq = pqTemp.Find(p => p.Name == trace1.From && p.Step == step - 1); } if (pq == null) { foreach (var trace1 in trcLst.Where(t => t.From == pq2.Name)) { pq = pqTemp.Find(p => p.Name == trace1.To && p.Step == step - 1); } } if (pq == null) { continue; } pq2 = pq; if (pq == pq1) { continue; } lst2.Add(pq2); } step--; } lst2.Reverse(); lst1.AddRange(lst2); var ring = new Ring(lst1); ring.Length = GetRingLength(ring, trcLst); ring.Offset = GetRingOffset(ring, trcLst, piquets); var tgOff = ring.Offset.Length / ring.Length; var minStep = ring.Points[0].Step; var minInd = 0; var minDist = 0D; foreach (var point in ring.Points.Where(point => point.Step < minStep)) { minStep = point.Step; minInd = ring.Points.IndexOf(point); minDist = point.Distance; } foreach (var point in ring.Points) { var dirrFi = ring.Points.IndexOf(point) < minInd ? 0 : 180; var dirrTe = ring.Points.IndexOf(point) < minInd ? 1 : -1; var vect = new Vector { Length = tgOff * (point.Distance - minDist), Fi = ring.Offset.Fi + dirrFi, Teta = ring.Offset.Teta * dirrTe }; point.Offset = point.Offset + vect; } result.Add(ring); } return(result); }