public void SwapVertex() { CGraphVertex tmp = this.start; this.start = this.end; this.end = tmp; }
private void Step2() { PutMessage("Обработка:" + Environment.NewLine); if (stack.Count == 0) { foreach (var t in graph.Tops) { if (t.VertexColor == Color.Transparent) { stack.Push(t); AddMessage("Больше нет вершин, достижимых данным обходом" + Environment.NewLine); AddMessage("Возьмем следующую непомеченную вершину: " + t.id.ToString()); t.Highlight = true; return; } } } if (stack.Count == 0) { numberOfAction++; Step3(); return; } CGraphVertex d = stack.Peek(); d.Highlight = true; d.VertexColor = Color.Transparent; foreach (var edge in graph.Edges) { if (edge.start == d && edge.end.VertexColor == Color.Transparent) { AddMessage("Найдем первую вершину, связанную с вершиной " + d.id.ToString() + Environment.NewLine); AddMessage("Добавим вершину " + edge.end.id.ToString() + " в обрабатываемые."); d.Highlight = false; d.VertexColor = Color.Orange; edge.end.Highlight = true; toolStripStatusLabel3.Text += " " + edge.end.id.ToString(); stack.Push(edge.end); return; } } AddMessage("У вершины " + d.id.ToString() + " больше нет непосещенных соседних вершин." + Environment.NewLine); AddMessage("Добавим вершину " + d.id.ToString() + " в список порядка обработки."); order.Push(stack.Pop()); d.VertexColor = Color.DarkRed; d.Highlight = false; int p = toolStripStatusLabel3.Text.LastIndexOf(' '); string s = toolStripStatusLabel3.Text; if (p >= 0) { toolStripStatusLabel3.Text = s.Substring(0, p); } toolStripStatusLabel4.Text += " " + d.id.ToString(); }
//поле данных //public int Length; //private CGraphVertex Start; //private CGraphVertex End; //public PointF x; // public PointF y; //public bool highlight; //конструктор public CGraphEdge(CGraphVertex x, CGraphVertex y) { start = x; end = y; Highlight = false; EdgeColor = Color.Transparent; }
public void Connect(CGraphEdge edge) { Pen pen = new Pen(Brushes.Black, 2); int z; CGraphVertex top1 = edge.start; CGraphVertex top2 = edge.end; if (top1.X < top2.X) { z = 1; } else { z = -1; } double x1 = z * 11 / Math.Sqrt(1 + Math.Pow((top2.Y - top1.Y), 2) / Math.Pow((top2.X - top1.X), 2)) + top1.X; double x2 = (-z) * 11 / Math.Sqrt(1 + Math.Pow((top2.Y - top1.Y), 2) / Math.Pow((top2.X - top1.X), 2)) + top2.X; double y1 = ((x1 - top1.X) * (top2.Y - top1.Y)) / (top2.X - top1.X) + top1.Y; double y2 = ((x2 - top2.X) * (top2.Y - top1.Y)) / (top2.X - top1.X) + top2.Y; edge.X = new Point((int)x1, (int)y1); edge.Y = new Point((int)x2, (int)y2); if (edge.EdgeColor != Color.Transparent) { g.Graphics.DrawLine(new Pen(edge.EdgeColor, 6), new PointF((int)x1, (int)y1), new PointF((int)x2, (int)y2)); } if (edge.Highlight) { Pen pen2 = new Pen(Color.Red, 2); double len = Math.Sqrt((y1 - y2) * (y1 - y2) + (x2 - x1) * (x2 - x1)); double nx = 5 * (y1 - y2) / (len); //вектор нормали с длинной 3 double ny = 5 * (x2 - x1) / (len); g.Graphics.DrawLine(pen2, new PointF((int)(x1 + nx), (int)(y1 + ny)), new PointF((int)(x2 + nx), (int)(y2 + ny))); g.Graphics.DrawLine(pen2, new PointF((int)(x1 - nx), (int)(y1 - ny)), new PointF((int)(x2 - nx), (int)(y2 - ny))); //g.Graphics.DrawLine(pen2, new PointF((int) x1, (int) y1), new PointF((int) x2, (int) y2)); } g.Graphics.DrawLine(pen, new PointF((int)x1, (int)y1), new PointF((int)x2, (int)y2)); if (isDirectedGraph) { var angle = Math.Atan2(y2 - y1, x2 - x1); var p2 = new Pen(pen.Color, 6) { EndCap = LineCap.ArrowAnchor }; g.Graphics.DrawLine(p2, (float)x2, (float)y2, (float)x2 + (float)(Math.Cos(angle)), (float)y2 + (float)(Math.Sin(angle))); } panel1.Invalidate(); }
public void AddTop(List <CGraphVertex> list, CGraphVertex top) { if (top != null) { list.Add(top); top.Highlight = true; panel1.Invalidate(); } }
private void Step5() { PutMessage("Поиск компонент:" + Environment.NewLine); if (stack.Count == 0) { connectetComponentsCount++; while (order.Count > 0) { var t = order.Pop(); if (t.VertexColor == Color.Transparent) { stack.Push(t); AddMessage( "Больше нет вершин, достижимых данным обходом. Получили новую компоненту сильной связности." + Environment.NewLine); AddMessage("Возьмем следующую непомеченную вершину: " + t.id.ToString()); t.Highlight = true; return; } } } if (stack.Count == 0) { numberOfAction++; Step6(); return; } CGraphVertex d = stack.Peek(); DeleteTopsHighlight(); d.Highlight = true; d.VertexColor = GetColor(connectetComponentsCount); foreach (var edge in graph.Edges) { if (edge.start == d && edge.end.VertexColor == Color.Transparent) { AddMessage("Найдем первую вершину, связанную с вершиной " + d.id.ToString() + Environment.NewLine); AddMessage("Добавим вершину " + edge.end.id.ToString() + " в обрабатываемые."); d.Highlight = false; edge.EdgeColor = d.VertexColor; edge.end.Highlight = true; toolStripStatusLabel3.Text += " " + edge.end.id.ToString(); stack.Push(edge.end); return; } } AddMessage("У вершины " + d.id.ToString() + " больше нет соседних непосещенных вершин." + Environment.NewLine); AddMessage("Исключим эту вершину из обработки."); stack.Pop(); }
private void Step2N() { PutMessage("Обработка:" + Environment.NewLine); if (queue.Count == 0) { connectetComponentsCount++; foreach (var t in graph.Tops) { if (t.VertexColor == Color.Transparent) { queue.Enqueue(t); AddMessage("Больше нет вершин, принадлежащих данной компоненте связности" + Environment.NewLine); AddMessage("Возьмем следующую непомеченную вершину: " + t.id.ToString()); t.Highlight = true; return; } } } if (queue.Count == 0) { numberOfAction++; Step3N(); return; } CGraphVertex d = queue.Dequeue(); d.VertexColor = GetColor(connectetComponentsCount); d.Highlight = false; toolStripStatusLabel3.Text = d.id.ToString(); AddMessage("Просмотрим все рёбра, связанные с вершиной " + d.id.ToString() + Environment.NewLine); AddMessage("Отметим достижимые вершины."); foreach (var edge in graph.Edges) { if ((edge.start == d || edge.end == d) && edge.EdgeColor == Color.Transparent) { edge.EdgeColor = d.VertexColor; if (edge.start != d) { queue.Enqueue(edge.start); edge.start.Highlight = true; } if (edge.end != d) { queue.Enqueue(edge.end); edge.end.Highlight = true; } } } }
public CGraphEdge IfEdgeExistEnd(CGraphVertex en) { for (int j = 0; j < graph.Edges.Count; j++) { if (graph.Edges[j].end == en) { return(graph.Edges[j]); } } return(null); }
public CGraphEdge IfEdgeExist(CGraphVertex st) { for (int j = 0; j < graph.Edges.Count; j++) { if (graph.Edges[j].start == st) { return(graph.Edges[j]); } } return(null); }
public bool IfEdgeExist(CGraphVertex st, CGraphVertex en) { for (int j = 0; j < graph.Edges.Count; j++) { if (graph.Edges[j].start == st && graph.Edges[j].end == en) { return(true); } } return(false); }
private void panel1_MouseDoubleClick(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left && checkBox1.Enabled) { var tmp = new CGraphVertex(e.X, e.Y) { id = graph.Tops.Count }; graph.AddVertex(tmp); DrawVertex(tmp, tmp.id.ToString()); panel1.Invalidate(); } }
public void Clear() { numberOfAction = 0; chosenEdges = new List <CGraphEdge>(); chosenTops = new List <CGraphVertex>(); queue = new Queue <CGraphVertex>(); tGraph = new CGraph(); stack = new Stack <CGraphVertex>(); order = new Stack <CGraphVertex>(); connectetComponentsCount = 0; toolStripStatusLabel3.Text = ""; toolStripStatusLabel4.Text = ""; extraEdges = null; toAdd = null; startTop = null; }
private void DeleteTop(CGraphVertex top) { for (int i = 0; i < graph.Tops.Count; i++) { if (graph.Tops[i] == top) { while (IfEdgeExist(graph.Tops[i]) != null) { DeleteEdge(IfEdgeExist(graph.Tops[i])); } while (IfEdgeExistEnd(graph.Tops[i]) != null) { DeleteEdge(IfEdgeExistEnd(graph.Tops[i])); } graph.Tops.RemoveAt(i); } } }
private void panel1_MouseUp(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { if (ifDown) { isMoving = false; ifDown = false; move.X = e.X; move.Y = e.Y; } } else if (lineToCursor != null && checkBox1.Enabled && e.Button == MouseButtons.Right) { for (int i = 0; i < graph.Tops.Count; i++) { if (e.X >= graph.Tops[i].X - rad && e.X <= graph.Tops[i].X + rad && e.Y >= graph.Tops[i].Y - rad && e.Y <= graph.Tops[i].Y + rad) { if (!IfEdgeExist(connect, graph.Tops[i]) && connect != graph.Tops[i]) { graph.AddEdge(lineToCursor.start, graph.Tops[i]); } panel1.Invalidate(); break; } } graph.Edges.Remove(lineToCursor); if (connect != null) { connect.Highlight = false; } connect = null; lineToCursor = null; } }
public void DrawVertex(CGraphVertex top, string str) { Pen pen = new Pen(Brushes.Black, 2); Font font = new Font("Ariel", 11, FontStyle.Bold); if (top.VertexColor != Color.Transparent) { g.Graphics.FillEllipse(new SolidBrush(top.VertexColor), top.X - rad, top.Y - rad, 22, 22); } if (top.Highlight) { //g.Graphics.FillEllipse(new SolidBrush(Color.LimeGreen), top.X - rad, top.Y - rad, 22, 22); g.Graphics.DrawEllipse(new Pen(Color.Red, 2), top.X - rad - 3, top.Y - rad - 3, 28, 28); //g.Graphics.FillRectangle(new SolidBrush(Color.LimeGreen), top.X - rad, top.Y - rad, 22, 22); } g.Graphics.DrawEllipse(pen, top.X - rad, top.Y - rad, 22, 22); g.Graphics.DrawString(str, font, Brushes.Black, top.X - rad, top.Y - 9); panel1.Invalidate(); }
private void panel1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Left) { for (int i = 0; i < graph.Tops.Count; i++) { if (e.X >= graph.Tops[i].X - rad && e.X <= graph.Tops[i].X + rad && e.Y >= graph.Tops[i].Y - rad && e.Y <= graph.Tops[i].Y + rad) { move = graph.Tops[i]; ifDown = true; break; } } } else if (e.Button == MouseButtons.Right && checkBox1.Enabled) { for (int i = 0; i < graph.Tops.Count; i++) { if (e.X >= graph.Tops[i].X - rad && e.X <= graph.Tops[i].X + rad && e.Y >= graph.Tops[i].Y - rad && e.Y <= graph.Tops[i].Y + rad) { connect = graph.Tops[i]; connect.Highlight = true; cursorPoint = new CGraphVertex(e.X, e.Y); lineToCursor = new CGraphEdge(connect, cursorPoint); graph.Edges.Add(lineToCursor); panel1.Invalidate(); break; } } } }
private void panel1_MouseClick(object sender, MouseEventArgs e) { if (checkBox1.Enabled) { if (e.Button == MouseButtons.Right) { /* for (int i = 0; i < graph.Tops.Count; i++) * if (e.X >= graph.Tops[i].X - rad && e.X <= graph.Tops[i].X + rad && * e.Y >= graph.Tops[i].Y - rad && * e.Y <= graph.Tops[i].Y + rad) * { * if (connect != null) * { * if (!IfEdgeExist(connect, graph.Tops[i]) && connect != graph.Tops[i]) * { * //graph.AddEdge(connect, graph.Tops[i]); * connect.Highlight = false; * connect = null; * } * else if (connect == graph.Tops[i]) * { * connect.Highlight = false; * connect = null; * } * } * else * { * connect = graph.Tops[i]; * connect.Highlight = true; * } * * panel1.Invalidate(); * break; * }*/ } else { try { for (int i = 0; i < graph.Tops.Count; i++) { if (e.X >= graph.Tops[i].X - rad && e.X <= graph.Tops[i].X + rad && e.Y >= graph.Tops[i].Y - rad && e.Y <= graph.Tops[i].Y + rad && !isMoving) { if (isChoosing) { startTop = graph.Tops[i]; Step1(); isChoosing = false; } else { HighlightTop(graph.Tops[i]); panel1.Invalidate(); } } } for (int i = 0; i < graph.Edges.Count; i++) { float cx1 = graph.Edges[i].X.X; float cx2 = graph.Edges[i].Y.X; float cy1 = graph.Edges[i].X.Y; float cy2 = graph.Edges[i].Y.Y; if (cy2 - cy1 != 0) { double A = (double)(cy2 - cy1) / (double)(cx2 - cx1); double B = (cx1 * cy1 - cx1 * cy2) / (cx2 - cx1) + cy1; if (!isMoving && e.Y >= A * e.X + B - 6 && e.Y <= A * e.X + B + 6 && e.X <= Math.Max(cx2, cx1) && e.X >= Math.Min(cx2, cx1) && e.Y <= Math.Max(cy2, cy1) && e.Y >= Math.Min(cy2, cy1)) { if (isMoving) { Cursor = Cursors.UpArrow; } HighlightEdge(graph.Edges[i]); panel1.Invalidate(); } } } } catch (Exception exception) { Console.Error.WriteLine(exception.StackTrace); } } } }
public void AddVertex(CGraphVertex top) { Tops.Add(top); }
public void AddEdge(CGraphVertex x, CGraphVertex y) { Edges.Add(new CGraphEdge(x, y)); }
private void HighlightTop(CGraphVertex top) { top.Highlight = !top.Highlight; }