void DrawCrossing(TNode Crossing, bool IsJustPoint) { using (Graphics g = Graphics.FromImage(bitmap)) { MyFont = new Font("Courier New", (float)(0.3 * I2 / (x2p - x1p)), FontStyle.Bold); string s = Convert.ToString(Crossing.node_Name); Brush MyBr = SelectNode == Crossing ? Brushes.Yellow : Brushes.LightGreen; Pen MyP = SelectNode == Crossing ? Pens.Red : Pens.DarkGreen; int K = II(2 + x1p - 0); if (!IsJustPoint) { g.FillRectangle(MyBr, II(Crossing.node_x - 0) - K / 2, JJ(Crossing.node_y - 0) - K / 2, K, K); g.DrawRectangle(MyP, II(Crossing.node_x - 0) - K / 2, JJ(Crossing.node_y - 0) - K / 2, K, K); SizeF tempsize = g.MeasureString(s, MyFont); g.DrawString(s, MyFont, Brushes.Black, II(Crossing.node_x - 0) - tempsize.Width / 2, JJ(Crossing.node_y - 0) - tempsize.Height / 2); } else { g.FillEllipse(Brushes.LightGray, II(Crossing.node_x - 0) - K / 2, JJ(Crossing.node_y - 0) - K / 2, K, K); g.DrawEllipse(Pens.Silver, II(Crossing.node_x - 0) - K / 2, JJ(Crossing.node_y - 0) - K / 2, K, K); } } }
void DeleteDescendants(TNode Node) { //Проверка не нужна, т.к. в основном методе int Leng = Node.node_UnderNodes.Length; for (int i = 0; i < Leng; i++) { if (Node.node_UnderNodes[i].node_UnderNodes != null) { DeleteDescendants(Node.node_UnderNodes[i]); Node.node_UnderNodes[i].node_UnderNodes = null; DeleteAllEdges(Node.node_UnderNodes[i]); Nodes[ReturnNumber(Node.node_UnderNodes[i].node_Name)] = Node.node_UnderNodes[i] = null; } else { DeleteAllEdges(Node.node_UnderNodes[i]); Nodes[ReturnNumber(Node.node_UnderNodes[i].node_Name)] = Node.node_UnderNodes[i] = null; } } }
void DrawCity(TNode City, bool IsJustLine) { using (Graphics g = Graphics.FromImage(bitmap)) { MyFont = new Font("Courier New", (float)(20 * I2 / (x2p - x1p)), FontStyle.Bold); string s = Convert.ToString(City.node_Name); if (!IsJustLine) { Brush MyBr = SelectNode == City ? Brushes.Yellow : Brushes.LightBlue; Pen MyP = SelectNode == City ? Pens.Red : Pens.DarkOrange; int K = II(180 + x1p - 0); double CentX, CentY; FindCenter(City.node_Points, out CentX, out CentY); g.DrawPolygon(MyP, StructToPoints(City.node_Points).ToArray()); g.FillPolygon(MyBr, StructToPoints(City.node_Points).ToArray()); SizeF tempsize = g.MeasureString(s, MyFont); g.DrawString(s, MyFont, Brushes.Black, II(CentX - 0) - tempsize.Width / 2, JJ(CentY - 0) - tempsize.Height / 2); } else g.DrawPolygon(Pens.Gray, StructToPoints(City.node_Points).ToArray()); } }
//Черная магия с удалением связей public TEdge[] EdgeArrDeleted(TNode Node, string NeedToDelete) { TEdge[] Out = null; if (Node.node_Edge != null && Node.node_Edge.Length != 1) { Out = new TEdge[Node.node_Edge.Length - 1]; int Length = Node.node_Edge.Length, Position = 0; for (int i = 0; i < Length; i++) if (Node.node_Edge[i].edge_NameNode != NeedToDelete) Out[Position++] = Node.node_Edge[i]; int Pos = 0; while (NullCount(Out, out Pos) != 0) Out[Position++] = Node.node_Edge[Pos]; } return Out; }
//====================================================================== Парсер public void Loader(string Input) { string[] Mass = Input.Split('\n'); int Pos = 0; int NodesCount = int.Parse(Mass[Pos++]); Nodes = new TNode[NodesCount]; for (int i = 0; i < NodesCount; i++) { Nodes[i] = new TNode(); Nodes[i].node_Name = Mass[Pos++]; Nodes[i].node_x = double.Parse(Mass[Pos++]); Nodes[i].node_y = double.Parse(Mass[Pos++]); Nodes[i].node_IsDescendant = bool.Parse(Mass[Pos++]); Nodes[i].node_Visible = bool.Parse(Mass[Pos++]); Nodes[i].node_Level = int.Parse(Mass[Pos++]); Pos++; int EL = int.Parse(Mass[Pos++]); Nodes[i].node_Edge = new TEdge[EL]; for (int k = 0; k < EL; k++) { Nodes[i].node_Edge[k].edge_NameNode = Mass[Pos++]; Nodes[i].node_Edge[k].edge_Visible = bool.Parse(Mass[Pos++]); Nodes[i].node_Edge[k].edge_Level = int.Parse(Mass[Pos++]); } int UL = int.Parse(Mass[Pos++]); Nodes[i].node_UnderNodes = new TNode[UL]; int Temp = i; for (int f = 0; f < UL; f++) Nodes[i].node_UnderNodes[f] = Nodes[++Temp] = GetDistrictDescendants(ref Pos, Mass, ref Temp); i = Temp; } }
TNode GetDistrictDescendants(ref int Pos, string[] Mass, ref int IPos) { TNode District = new TNode(); District.node_Name = Mass[Pos++]; District.node_x = double.Parse(Mass[Pos++]); District.node_y = double.Parse(Mass[Pos++]); District.node_IsDescendant = bool.Parse(Mass[Pos++]); District.node_Visible = bool.Parse(Mass[Pos++]); District.node_Level = int.Parse(Mass[Pos++]); District.node_Ancestor = Mass[Pos++]; int EL = int.Parse(Mass[Pos++]); District.node_Edge = new TEdge[EL]; for (int i = 0; i < EL; i++) { District.node_Edge[i].edge_NameNode = Mass[Pos++]; District.node_Edge[i].edge_Visible = bool.Parse(Mass[Pos++]); District.node_Edge[i].edge_Level = int.Parse(Mass[Pos++]); } int UL = int.Parse(Mass[Pos++]); District.node_UnderNodes = new TNode[UL]; for (int i = 0; i < UL; i++) District.node_UnderNodes[i] = Nodes[++IPos] = GetCrossingDescendants(ref Pos, Mass); return District; }
void MovePolyObject(TNode Node, double dx, double dy) { if (Node.node_Level != 3) { if (Node.node_UnderNodes != null) { int L = Node.node_UnderNodes.Length; for (int i = 0; i < L; i++) MovePolyObject(Node.node_UnderNodes[i], dx, dy); } Node.node_Points = MoveLine(Node.node_Points, dx, dy); } else { Node.node_x += dx; Node.node_y += dy; if (Node.node_Edge != null) { int N = Node.node_Edge.Length; for (int k = 0; k < N; k++) Node.node_Edge[k].edge_Points = MoveLine(Node.node_Edge[k].edge_Points, dx, dy); } } }
public void AddDescendant(string Ancestor) { int N = ReturnNumber(Ancestor); TNode[] NewDescs = new TNode[0]; SelectNode.node_IsDescendant = true; SelectNode.node_Ancestor = Ancestor; if (Nodes[N].node_UnderNodes != null) { int L = Nodes[N].node_UnderNodes.Length; Array.Resize(ref NewDescs, L + 1); for (int i = 0; i < Nodes[N].node_UnderNodes.Length; i++) NewDescs[i] = Nodes[N].node_UnderNodes[i]; NewDescs[L] = SelectNode; Nodes[N].node_UnderNodes = NewDescs; } else { Array.Resize(ref NewDescs, 1); NewDescs[0] = SelectNode; Nodes[N].node_UnderNodes = NewDescs; } }
public void AddDistrictNode(int MouseX, int MouseY) { int N = Nodes.Length, l = 0; Array.Resize(ref Nodes, ++N); Array.Resize(ref NodeNamesArr, N); Nodes[N - 1] = new TNode(); string Name = null; for (int k = 0; k < N; k++) { bool Ok = true; Name = "Distr " + Convert.ToString(l); for (int i = 0; i < N; i++) if (Nodes[i].node_Name == Name) { Ok = false; break; } if (Ok) break; else l++; } Nodes[N - 1].node_Name = Name; Nodes[N - 1].node_x = XX(MouseX); Nodes[N - 1].node_y = YY(MouseY); Nodes[N - 1].node_Level = 2; NodeNamesArr[N - 1] = Name; Nodes[N - 1].node_Points = CurrentLine.edge_Points; int T = 0; TNode[] Undernodes = new TNode[T]; for (int i = 0; i < N; i++) { if (Nodes[i].node_Level == 3 && !Nodes[i].node_IsDescendant && IsPointInPolygon(CurrentLine.edge_Points, Nodes[i].node_x, Nodes[i].node_y)) { Array.Resize(ref Undernodes, ++T); Undernodes[T - 1] = Nodes[i]; Nodes[i].node_Ancestor = Nodes[N - 1].node_Name; Nodes[i].node_IsDescendant = true; } } if (T != 0) Nodes[N - 1].node_UnderNodes = Undernodes; }
// прочитать public void Read(string FileName) { ofs = 0; FileStream aFile = new FileStream(FileName, FileMode.Open); int N = (int)aFile.Length; byData = new byte[N]; aFile.Read(byData, 0, N); int L1 = DataInInt(); Nodes = new TNode[L1]; for (int i = 0; i <= L1 - 1; i++) { Nodes[i] = new TNode(); Nodes[i].x = DataInInt(); Nodes[i].y = DataInInt(); Nodes[i].name = DataInStr(); int L2 = DataInInt(); Nodes[i].Edge = new TEdge[L2]; if (L2 != 0) for (int j = 0; j <= L2 - 1; j++) { Nodes[i].Edge[j].x1c = DataInInt(); Nodes[i].Edge[j].x2c = DataInInt(); Nodes[i].Edge[j].yc = DataInInt(); Nodes[i].Edge[j].nameNode = DataInStr(); Nodes[i].Edge[j].color = Color.Silver; } } aFile.Close(); }
public void AddCrossing(int MouseX, int MouseY) { int N = Nodes.Length, l = 0; Array.Resize(ref Nodes, ++N); Array.Resize(ref NodeNamesArr, N); Nodes[N - 1] = new TNode(); string Name = null; for (int k = 0; k < N; k++) { bool Ok = true; Name = "Cross " + Convert.ToString(l); for (int i = 0; i < N; i++) if (Nodes[i].node_Name == Name) { Ok = false; break; } if (Ok) break; else l++; } Nodes[N - 1].node_Name = Name; Nodes[N - 1].node_x = XX(MouseX); Nodes[N - 1].node_y = YY(MouseY); Nodes[N - 1].node_Level = 3; NodeNamesArr[N - 1] = Name; }
public void DeleteNode() { int n = -1; bool ok = false; int Ln = Nodes.Length; while ((n < Ln - 1) && !ok) ok = Nodes[++n] == SelectNode; if (SelectNode.Edge != null) { Ln = SelectNode.Edge.Length; for (int i = 0; i < Ln; i++) { int NumNode = ReturnNumber(SelectNode.Edge[i].nameNode); int LN = Nodes[NumNode].Edge.Length; TEdge[] New = new TEdge[LN - 1]; for (int k = 0; k < LN; k++) if (ReturnNumber(Nodes[NumNode].Edge[k].nameNode) == n) { Nodes[NumNode].Edge[k] = new TEdge(); break; } int count = 0; for (int l = 0; l < LN; l++) if (Nodes[NumNode].Edge[l].nameNode != null) { New[count] = Nodes[NumNode].Edge[l]; count++; } Nodes[NumNode].Edge = New; } } Nodes[n] = null; SelectNode = null; Ln = Nodes.Length; TNode[] NewArr = new TNode[Ln - 1]; int Num = 0; for (int i = 0; i < Ln; i++) if (Nodes[i] != null) NewArr[Num++] = Nodes[i]; Nodes = NewArr; }
// добавить узел public void AddNode(int x, int y) { int N = Nodes.Length, l = 0; Array.Resize(ref Nodes, ++N); Nodes[N - 1] = new TNode(); string Name = null; for (int k = 0; k < N; k++) { bool Ok = true; Name = "Node " + Convert.ToString(l); for (int i = 0; i < N; i++) if (Nodes[i].name == Name) { Ok = false; break; } if (Ok) break; else l++; } Nodes[N - 1].name = Name; Nodes[N - 1].x = x; Nodes[N - 1].y = y; Nodes[N - 1].color = Color.White; }
void ResetNodesArray() { int Ln = Nodes.Length; int N = 0; TNode[] NewArr = new TNode[N]; int Num = 0; for (int j = 0; j < Ln; j++) if (Nodes[j] != null) { Array.Resize(ref NewArr, ++N); NewArr[Num++] = Nodes[j]; } Nodes = NewArr.Length != 0 ? NewArr : new TNode[0]; }
void DrawDistrict(TNode District, bool IsJustLine) { using (Graphics g = Graphics.FromImage(bitmap)) { MyFont = new Font("Courier New", (float)(6 * I2 / (x2p - x1p)), FontStyle.Bold); string s = Convert.ToString(District.node_Name); if (!IsJustLine) { Brush MyBr = SelectNode == District ? Brushes.Yellow : Brushes.GhostWhite; Pen MyP = SelectNode == District ? Pens.Red : Pens.Silver; int K = II(80 + x1p - 0); double CentX, CentY; FindCenter(District.node_Points, out CentX, out CentY); g.DrawPolygon(MyP, StructToPoints(District.node_Points).ToArray()); g.FillPolygon(MyBr, StructToPoints(District.node_Points).ToArray()); SizeF tempsize = g.MeasureString(s, MyFont); g.DrawString(s, MyFont, CurrentLevel == 2 ? Brushes.Gray : Brushes.Black, II(CentX - 0) - tempsize.Width / 2, JJ(CentY - 0) - tempsize.Height / 2); } else g.DrawPolygon(Pens.Gray, StructToPoints(District.node_Points).ToArray()); } }
public void DeleteAllEdges(TNode Node) { if (Node.node_Edge != null) { int NNum = ReturnNumber(Node.node_Name); int NL = Node.node_Edge.Length; for (int i = 0; i < NL; i++) { int Num = ReturnNumber(Node.node_Edge[i].edge_NameNode); Nodes[Num].node_Edge = EdgeArrDeleted(Nodes[Num], Node.node_Name); } } }
TNode GetCrossingDescendants(ref int Pos, string[] Mass) { TNode Crossing = new TNode(); Crossing.node_Name = Mass[Pos++]; Crossing.node_x = double.Parse(Mass[Pos++]); Crossing.node_y = double.Parse(Mass[Pos++]); Crossing.node_IsDescendant = bool.Parse(Mass[Pos++]); Crossing.node_Visible = bool.Parse(Mass[Pos++]); Crossing.node_Level = int.Parse(Mass[Pos++]); Crossing.node_Ancestor = Mass[Pos++]; int EL = int.Parse(Mass[Pos++]); Crossing.node_Edge = new TEdge[EL]; for (int i = 0; i < EL; i++) { Crossing.node_Edge[i].edge_NameNode = Mass[Pos++]; Crossing.node_Edge[i].edge_Visible = bool.Parse(Mass[Pos++]); Crossing.node_Edge[i].edge_Level = int.Parse(Mass[Pos++]); } return Crossing; }
public void DeleteNode() { int n = ReturnNumber(SelectNode.node_Name); if (SelectNode.node_UnderNodes != null) DeleteDescendants(SelectNode); if (SelectNode.node_Edge != null) DeleteAllEdges(SelectNode); if (SelectNode.node_IsDescendant) { bool Deleted = false; int K = Nodes.Length; for (int h = 0; h < K && !Deleted; h++) if (Nodes[h] != null && Nodes[h].node_Level == SelectNode.node_Level - 1) { int G = Nodes[h].node_UnderNodes.Length; for (int i = 0; i < G; i++) if (Nodes[h].node_UnderNodes[i].node_Name == SelectNode.node_Name) { Nodes[h].node_UnderNodes[i] = null; TNode[] NewArr; if (G - 1 != 0) { NewArr = new TNode[G - 1]; if (G - 1 != 0) { for (int y = 0, k = 0; y < G; y++) if (Nodes[h].node_UnderNodes[y] != null) NewArr[k++] = Nodes[h].node_UnderNodes[y]; Nodes[h].node_UnderNodes = NewArr; Deleted = true; break; } } else Nodes[h] = null; Deleted = true; break; } h += G; } } Nodes[n] = null; SelectNode = null; ResetNodesArray(); ResetNamesArr(); }
//Расширение: Двустороннее ребро void SetEdge(TNode First, TNode Second, int Level, int Count) { Random rnd = new Random(); string ID = rnd.Next(0, 1000000).ToString() + rnd.Next(-10000000, -1).ToString(); int n = ReturnNumber(First.node_Name); int L = 0; if (Second.node_Edge != null) L = Second.node_Edge.Length; Array.Resize(ref Second.node_Edge, ++L); Second.node_Edge[L - 1].edge_NameNode = Nodes[n].node_Name; Second.node_Edge[L - 1].edge_Level = Level; List<_edge_Points> Points = new List<_edge_Points>(); n = CurrentLine.edge_Points.Count; for (int i = 0; i < n; i++) Points.Add(CurrentLine.edge_Points[n - i - 1]); Second.node_Edge[L - 1].edge_Points = Points; Second.node_Edge[L - 1].edge_Rows = Count; Second.node_Edge[L - 1].edge_NameEdge = ID; Second.node_Edge[L - 1].edge_Marked_Name = false; n = ReturnNumber(Second.node_Name); L = 0; if (First.node_Edge != null) L = First.node_Edge.Length; Array.Resize(ref SelectNode.node_Edge, ++L); First.node_Edge[L - 1].edge_NameNode = Nodes[n].node_Name; First.node_Edge[L - 1].edge_Level = Level; First.node_Edge[L - 1].edge_Points = CurrentLine.edge_Points; First.node_Edge[L - 1].edge_Rows = Count; First.node_Edge[L - 1].edge_NameEdge = ID; First.node_Edge[L - 1].edge_Marked_Name = true; }
public void SetGroupInRegion(int Xold, int Yold, int Xnew, int Ynew, out string Error) { double x1 = XX(Xold), x2 = XX(Xnew), y1 = YY(Yold), y2 = YY(Ynew); Error = ""; int Length = Nodes.Length; TNode[] Group = new TNode[0]; int L = 0; int[] IDs = new int[0]; int K = 0; bool Ok = true; for (int i = 0; i < Length; i++) if (Nodes[i].node_Level == CurrentLevel && Nodes[i].node_x > x1 && Nodes[i].node_x < x2 && Nodes[i].node_y > y1 && Nodes[i].node_y < y2) { Array.Resize(ref IDs, ++K); IDs[K - 1] = i; if (Nodes[i].node_IsDescendant == true) Ok = false; } int Num = 0; Length = IDs.Length; if (K != 0 && Ok) { if (Ok) { if (CurrentLevel == 3) AddDistrictNode(II(x1 + (x2 - x1) / 2), JJ(y2 - (y2 - y1) / 2)); else if (CurrentLevel == 2) AddCityNode(II(x1 + (x2 - x1) / 2), JJ(y2 - (y2 - y1) / 2)); Num = Nodes.Length - 1; for (int i = 0; i < Length; i++) { Array.Resize(ref Group, ++L); Nodes[IDs[i]].node_IsDescendant = true; Nodes[IDs[i]].node_Ancestor = Nodes[Num].node_Name; Group[L - 1] = Nodes[IDs[i]]; } } else { for (int i = 0; i < Length; i++) if (Nodes[IDs[i]].node_IsDescendant == true) Error += Nodes[IDs[i]].node_Name + " "; } if (Ok) Nodes[Num].node_UnderNodes = Group; else { if (K != 0) { SelectNode = Nodes[Num]; DeleteNode(); } } } }