예제 #1
0
        public void SwapVertex()
        {
            CGraphVertex tmp = this.start;

            this.start = this.end;
            this.end   = tmp;
        }
예제 #2
0
        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();
        }
예제 #3
0
 //поле данных
 //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;
 }
예제 #4
0
        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();
        }
예제 #5
0
 public void AddTop(List <CGraphVertex> list, CGraphVertex top)
 {
     if (top != null)
     {
         list.Add(top);
         top.Highlight = true;
         panel1.Invalidate();
     }
 }
예제 #6
0
        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();
        }
예제 #7
0
        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;
                    }
                }
            }
        }
예제 #8
0
 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);
 }
예제 #9
0
 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);
 }
예제 #10
0
 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);
 }
예제 #11
0
        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();
            }
        }
예제 #12
0
 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;
 }
예제 #13
0
 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);
         }
     }
 }
예제 #14
0
        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;
            }
        }
예제 #15
0
        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();
        }
예제 #16
0
        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;
                    }
                }
            }
        }
예제 #17
0
        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);
                    }
                }
            }
        }
예제 #18
0
 public void AddVertex(CGraphVertex top)
 {
     Tops.Add(top);
 }
예제 #19
0
 public void AddEdge(CGraphVertex x, CGraphVertex y)
 {
     Edges.Add(new CGraphEdge(x, y));
 }
예제 #20
0
 private void HighlightTop(CGraphVertex top)
 {
     top.Highlight = !top.Highlight;
 }