private DirectedGraphViewModel CreateGraphViewModel(IGenome genome)
        {
            DirectedGraph digraph;

            float[]    weightArr;
            INodeIdMap nodeIdByIdxMap;

            if (genome is NeatGenome <double> neatGenomeDouble)
            {
                digraph        = neatGenomeDouble.DirectedGraph;
                weightArr      = ToFloatArray(neatGenomeDouble.GetDigraphWeightArray());
                nodeIdByIdxMap = neatGenomeDouble.NodeIndexByIdMap.CreateInverseMap();
            }
            else if (genome is NeatGenome <float> neatGenomeFloat)
            {
                digraph        = neatGenomeFloat.DirectedGraph;
                weightArr      = neatGenomeFloat.GetDigraphWeightArray();
                nodeIdByIdxMap = neatGenomeFloat.NodeIndexByIdMap.CreateInverseMap();
            }
            else
            {
                throw new InvalidOperationException("The genome object is not a NeatGenome.");
            }

            DirectedGraphViewModel graphViewModel = new DirectedGraphViewModel(digraph, weightArr, nodeIdByIdxMap);

            return(graphViewModel);
        }
Exemple #2
0
 /// <summary>
 /// Paint the nodes of a directed graph.
 /// </summary>
 /// <param name="model">The graph view model being painted.</param>
 /// <param name="state">A collection of working variables for painting a graph to a GDI+ surface.</param>
 protected virtual void PaintNodes(DirectedGraphViewModel model, PaintState state)
 {
     // Loop the nodes, painting each in turn.
     for (int i = 0; i < model.NodeIdByIdx.Count; i++)
     {
         int   id  = model.NodeIdByIdx.Map(i);
         Point pos = model.NodePosByIdx ![i];
        private static DirectedGraphViewModel CreateGraphViewModel()
        {
            // Simple acyclic graph.
            var connList = new List <WeightedDirectedConnection <float> >
            {
                new WeightedDirectedConnection <float>(0, 4, 1f),
                new WeightedDirectedConnection <float>(4, 5, 2f),
                new WeightedDirectedConnection <float>(5, 2, 3f),
                new WeightedDirectedConnection <float>(1, 2, 4f),
                new WeightedDirectedConnection <float>(2, 2, 5f),
                new WeightedDirectedConnection <float>(2, 3, 5f),
                new WeightedDirectedConnection <float>(2, 4, 5f),
                new WeightedDirectedConnection <float>(2, 5, 5f)
            };

            connList.Sort(WeightedDirectedConnectionComparer <float> .Default);

            // Create graph.
            var digraph = WeightedDirectedGraphBuilder <float> .Create(connList, 2, 2);

            // Create graph view model, and return.
            INodeIdMap             nodeIdByIdx    = CreateNodeIdByIdx(digraph.TotalNodeCount);
            DirectedGraphViewModel graphViewModel = new DirectedGraphViewModel(digraph, digraph.WeightArray, nodeIdByIdx);

            return(graphViewModel);
        }
Exemple #4
0
 /// <summary>
 /// Paint a directed graph.
 /// </summary>
 /// <param name="model">The graph view model to paint.</param>
 /// <param name="state">A collection of working variables for painting a graph to a GDI+ surface.</param>
 protected virtual void PaintGraph(DirectedGraphViewModel model, PaintState state)
 {
     // Paint all connections, followed by all nodes.
     // This way the slightly 'rough' positioning of the connection endpoints is overpainted by the nodes
     // to produce an overall good visual result.
     PaintConnections(model, state);
     PaintNodes(model, state);
 }
Exemple #5
0
        /// <summary>
        /// Paint a directed graph onto the a provided GDI+ surface.
        /// </summary>
        /// <param name="model">The graph view model to paint.</param>
        /// <param name="g">The GDI+ surface to paint on to.</param>
        /// <param name="viewportArea">An area within the GDI+ surface to paint the graph within.</param>
        /// <param name="zoomFactor">Zoom factor.</param>
        public void PaintGraph(
            DirectedGraphViewModel model,
            Graphics g,
            Rectangle viewportArea,
            float zoomFactor)
        {
            PaintState state = new(g, viewportArea, _settings.NodeDiameter, zoomFactor, model.DirectedGraph.TotalNodeCount);

            PaintGraph(model, state);
        }
Exemple #6
0
        private void button1_Click(object sender, EventArgs e)
        {
            var graphViewportPainter = new GraphViewportPainter();

            this.viewportControl1.ViewportPainter = graphViewportPainter;

            DirectedGraphViewModel graphViewModel = CreateGraphViewModel();

            graphViewportPainter.GraphViewModel = graphViewModel;

            this.viewportControl1.RepaintViewport();
            this.viewportControl1.Refresh();
        }
        public override void OnGenomeUpdated()
        {
            base.OnGenomeUpdated();

            // Take a local reference to avoid possible race conditions on the class field.
            IGenome genome = _genome;

            if (genome is null)
            {
                _graphViewportPainter.GraphViewModel = null;
            }
            else
            {
                DirectedGraphViewModel graphViewModel = CreateGraphViewModel(genome);
                _graphViewportPainter.GraphViewModel = graphViewModel;
            }

            // Repaint the viewport.
            viewportControl1.RepaintViewport();

            // Update the control/window to show the updated/repainted viewport.
            viewportControl1.Refresh();
        }
Exemple #8
0
        public void Display(DirectionalGraphRenderer renderer)
        {
            if (renderer.DirectedWindowVM.RegenerateGraphView == false)
            {
                return;
            }
            DirectedGraphViewModel vm = new DirectedGraphViewModel();
            double r = Math.Sqrt(Math.Pow(renderer.GraphControl.ActualHeight, 1.8) + Math.Pow(renderer.GraphControl.ActualWidth, 1.8)) / 20;


            for (int i = 0; i < renderer.Graph.NodesNr; ++i)
            {
                double ratio = (double)(renderer.Graph.NodeOrderInColumn(i)) / (double)(renderer.Graph.NodesInColumn(i) - 1);
                if (double.IsNaN(ratio) || double.IsInfinity(ratio))
                {
                    ratio = 0.0;
                }

                double x = r + (renderer.GraphControl.ActualWidth - 2 * r) * (double)(renderer.Graph.Columns[i]) / (double)(renderer.Graph.ColumnsCount());
                double y = r + (renderer.GraphControl.ActualHeight - 2 * r) * ratio;

                vm.Nodes.Add(new CircleViewModel()
                {
                    X          = x,
                    Y          = y,
                    Radius     = r,
                    Color      = new SolidColorBrush(Colors.Yellow),
                    Number     = i + 1,
                    NodeNumber = i
                });
            }


            for (int y = 0; y < renderer.Graph.NodesNr; ++y)
            {
                for (int x = 0; x < renderer.Graph.NodesNr; ++x)
                {
                    if (renderer.Graph.GetConnection(y, x) == false)
                    {
                        continue;
                    }

                    var ratio1 = (double)(renderer.Graph.NodeOrderInColumn(y)) / (double)(renderer.Graph.NodesInColumn(y) - 1);
                    var ratio2 = (double)(renderer.Graph.NodeOrderInColumn(x)) / (double)(renderer.Graph.NodesInColumn(x) - 1);
                    if (double.IsNaN(ratio1) || double.IsInfinity(ratio1))
                    {
                        ratio1 = 0.0;
                    }
                    if (double.IsNaN(ratio2) || double.IsInfinity(ratio2))
                    {
                        ratio2 = 0.0;
                    }

                    double x1 = r + (renderer.GraphControl.ActualWidth - 2 * r) * (double)(renderer.Graph.Columns[y]) / (double)(renderer.Graph.ColumnsCount());
                    double y1 = r + (renderer.GraphControl.ActualHeight - 2 * r) * ratio1;

                    double x2 = r + (renderer.GraphControl.ActualWidth - 2 * r) * (double)(renderer.Graph.Columns[x]) / (double)(renderer.Graph.ColumnsCount());
                    double y2 = r + (renderer.GraphControl.ActualHeight - 2 * r) * ratio2;


                    int maxFlow = 0;
                    foreach (var flow in renderer.Graph.weights)
                    {
                        if (flow > 2000000)
                        {
                            continue;
                        }
                        if (flow > maxFlow)
                        {
                            maxFlow = flow;
                        }
                    }

                    var abc = (float)renderer.Graph.getWeight(y, x);

                    float flowRatio = ((float)renderer.Graph.getWeight(y, x) / (float)maxFlow);
                    Color flowColor = Colors.Green;
                    if (flowRatio <= 1.1)
                    {
                        flowColor = Color.FromRgb((byte)0, (byte)0, (byte)(flowRatio * 255));
                    }

                    int thickness = 15;
                    if (flowRatio <= 1.1)
                    {
                        thickness = (int)abc;
                    }

                    LineViewModel lineVM = new LineViewModel()
                    {
                        X1        = x1,
                        Y1        = y1,
                        X2        = x2,
                        Y2        = y2,
                        StartNode = y,
                        EndNode   = x,
                        //Color = flowColor,
                        Hint      = string.Format("Flow {0}", abc),
                        Thickness = thickness
                    };

                    vm.Connections.Add(lineVM);
                    double a         = (y2 - y1) / (x2 - x1);
                    double b         = y2 / (a * x2);
                    double length    = Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
                    double newLength = length - r / 2;

                    double ratio = newLength / length;
                    double newX  = x1 + (x2 - x1) * ratio;
                    double newY  = y1 + (y2 - y1) * ratio;

                    TriangleViewModel triangleVm = new TriangleViewModel()
                    {
                        X     = newX - 10,
                        Y     = newY - 5,
                        Angle = lineVM.Angle * (180.0 / Math.PI) + 90.0
                    };

                    vm.Triangles.Add(triangleVm);
                }
            }

            renderer.GraphControl.VM = vm;
        }
        public void Display(DirectionalGraphRenderer renderer)
        {
            if (renderer.DirectedWindowVM.RegenerateGraphView == false)
            {
                return;
            }
            DirectedGraphViewModel vm = new DirectedGraphViewModel();
            double r = Math.Sqrt(Math.Pow(renderer.GraphControl.ActualHeight, 1.8) + Math.Pow(renderer.GraphControl.ActualWidth, 1.8)) / 20;


            for (int i = 0; i < renderer.Graph.NodesNr; ++i)
            {
                double arc = 2 * Math.PI / renderer.Graph.NodesNr * i;
                double x   = renderer.GraphControl.ActualWidth / 2 + (renderer.GraphControl.ActualWidth / 2 - r) * Math.Cos(arc);
                double y   = renderer.GraphControl.ActualHeight / 2 + (renderer.GraphControl.ActualHeight / 2 - r) * Math.Sin(arc);

                vm.Nodes.Add(new CircleViewModel()
                {
                    X          = x,
                    Y          = y,
                    Radius     = r,
                    Color      = new SolidColorBrush(Colors.Yellow),
                    Number     = i + 1,
                    NodeNumber = i
                });
            }


            for (int y = 0; y < renderer.Graph.NodesNr; ++y)
            {
                for (int x = 0; x < renderer.Graph.NodesNr; ++x)
                {
                    if (renderer.Graph.GetConnection(y, x) == false)
                    {
                        continue;
                    }
                    double arc1 = 2 * Math.PI / renderer.Graph.NodesNr * y;
                    double arc2 = 2 * Math.PI / renderer.Graph.NodesNr * x;

                    double x1 = renderer.GraphControl.ActualWidth / 2 + (renderer.GraphControl.ActualWidth / 2 - r) * Math.Cos(arc1);
                    double y1 = renderer.GraphControl.ActualHeight / 2 + (renderer.GraphControl.ActualHeight / 2 - r) * Math.Sin(arc1);

                    double x2 = renderer.GraphControl.ActualWidth / 2 + (renderer.GraphControl.ActualWidth / 2 - r) * Math.Cos(arc2);
                    double y2 = renderer.GraphControl.ActualHeight / 2 + (renderer.GraphControl.ActualHeight / 2 - r) * Math.Sin(arc2);

                    int weight = renderer.Graph.getWeight(y, x);

                    byte redBrightness = 0;
                    if (renderer.DirectedWindowVM.ShowWeights)
                    {
                        redBrightness = (byte)((Math.Abs(renderer.Graph.MaxWeight - renderer.Graph.MinWeight) - Math.Abs(renderer.Graph.MaxWeight - weight)) / (double)(Math.Abs(renderer.Graph.MaxWeight - renderer.Graph.MinWeight)) * 255.0);
                    }

                    LineViewModel lineVM = new LineViewModel()
                    {
                        X1        = x1,
                        Y1        = y1,
                        X2        = x2,
                        Y2        = y2,
                        StartNode = y,
                        EndNode   = x,
                        Color     = Color.FromRgb(redBrightness, 0, 0)
                    };
                    vm.Connections.Add(lineVM);
                    double a         = (y2 - y1) / (x2 - x1);
                    double b         = y2 / (a * x2);
                    double length    = Math.Sqrt(Math.Pow(x2 - x1, 2) + Math.Pow(y2 - y1, 2));
                    double newLength = length - r / 2;

                    double ratio = newLength / length;
                    double newX  = x1 + (x2 - x1) * ratio;
                    double newY  = y1 + (y2 - y1) * ratio;

                    TriangleViewModel triangleVm = new TriangleViewModel()
                    {
                        X     = newX - 10,
                        Y     = newY - 5,
                        Angle = lineVM.Angle * (180.0 / Math.PI) + 90.0
                    };

                    vm.Triangles.Add(triangleVm);

                    if (renderer.DirectedWindowVM.ShowWeights)
                    {
                        LineViewModel hintVM = new LineViewModel(lineVM)
                        {
                            Hint      = string.Format("Weight : {0}, {1} , {2}", weight, y, x),
                            Color     = Colors.Transparent,
                            Thickness = 8
                        };

                        vm.Connections.Add(hintVM);
                    }
                }
            }

            renderer.GraphControl.VM = vm;
        }