From b6bc2d592fec3b75bb104f23529f7bb5ef3fbab3 Mon Sep 17 00:00:00 2001
From: Paul-Winpenny <92634321+Paul-Winpenny@users.noreply.github.com>
Date: Wed, 30 Oct 2024 19:19:30 +0000
Subject: [PATCH] Graph now displays on screen (and algorithm for polar
 coordinates).

---
 App/RobobinApp/Models/Graph.cs                | 35 +++++++++++++
 .../ViewModels/MainPageViewModel.cs           | 52 ++++++++++++++++++-
 App/RobobinApp/Views/CentreGraph.xaml.cs      | 49 ++++++++++++++---
 App/RobobinApp/Views/MainPage.xaml            |  3 ++
 App/RobobinApp/Views/MainPage.xaml.cs         | 12 ++++-
 5 files changed, 140 insertions(+), 11 deletions(-)
 create mode 100644 App/RobobinApp/Models/Graph.cs

diff --git a/App/RobobinApp/Models/Graph.cs b/App/RobobinApp/Models/Graph.cs
new file mode 100644
index 00000000..414492e4
--- /dev/null
+++ b/App/RobobinApp/Models/Graph.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Robobin.Models
+{
+    public class Node
+    {
+        public string Name { get; set; }
+        public float X { get; set; }
+        public float Y { get; set; }
+
+        public Node(string name, float x, float y)
+        {
+            Name = name;
+            X = x;
+            Y = y;
+        }
+    }
+
+    public class Graph
+    {
+        public List<Node> Nodes { get; set; }
+        public (float magnitude, float angle)[,] AdjacencyMatrix { get; set; }
+
+        public Graph(List<Node> nodes, (float, float)[,] adjacencyMatrix)
+        {
+            Nodes = nodes;
+            AdjacencyMatrix = adjacencyMatrix;
+        }
+    }
+
+}
diff --git a/App/RobobinApp/ViewModels/MainPageViewModel.cs b/App/RobobinApp/ViewModels/MainPageViewModel.cs
index 784b9504..2841d931 100644
--- a/App/RobobinApp/ViewModels/MainPageViewModel.cs
+++ b/App/RobobinApp/ViewModels/MainPageViewModel.cs
@@ -2,6 +2,7 @@ using System.ComponentModel;
 using System.Runtime.CompilerServices;
 using System.Windows.Input;
 using Microsoft.Maui.Controls;
+using Robobin.Models;
 using RobobinApp.Views;
 using Shiny.BluetoothLE;
 
@@ -13,15 +14,62 @@ namespace RobobinApp.ViewModels
     {
         private bool _isBusy;
         private string _statusMessage;
-   
+        public Graph Graph { get; private set; }
         public ICommand ConnectToRobobinCommand { get; }
 
         public MainPageViewModel()
         {
-
             ConnectToRobobinCommand = new Command(async () => await OnConnectToRobobin());
+
+            // Create nodes with X and Y coordinates
+            var nodes = new List<Node>
+            {
+                new Node("N1", 100, 100), // Example coordinates
+                new Node("N2", 200, 100),
+                new Node("N3", 150, 200),
+            };
+
+            // Create an empty adjacency matrix for three nodes
+            var adjacencyMatrix = new (float, float)[,]
+            {
+                { (0, 0),            (100, 0),         (111.80f, 63.44f) },
+                { (100, 180),        (0, 0),           (111.80f, 116.57f) },
+                { (111.80f, -116.56f), (111.80f, -63.43f), (0, 0) }
+               };
+
+            // Create graph
+            Graph = new Graph(nodes, adjacencyMatrix);
         }
+        public static (float magnitude, float angle)[,] CalculatePolarConnections(List<Node> nodes, bool[,] connections)
+        {
+            int nodeCount = nodes.Count;
+            var polarMatrix = new (float magnitude, float angle)[nodeCount, nodeCount];
 
+            for (int i = 0; i < nodeCount; i++)
+            {
+                for (int j = 0; j < nodeCount; j++)
+                {
+                    if (i == j || !connections[i, j])
+                    {
+                        polarMatrix[i, j] = (0, 0);
+                        continue;
+                    }
+
+        
+                    float dx = nodes[j].X - nodes[i].X;
+                    float dy = nodes[j].Y - nodes[i].Y;
+
+     
+                    float magnitude = (float)Math.Sqrt(dx * dx + dy * dy);
+
+                    float angle = (float)(Math.Atan2(dy, dx) * (180 / Math.PI));
+
+                    polarMatrix[i, j] = (magnitude, angle);
+                }
+            }
+
+            return polarMatrix;
+        }
         public bool IsBusy
         {
             get => _isBusy;
diff --git a/App/RobobinApp/Views/CentreGraph.xaml.cs b/App/RobobinApp/Views/CentreGraph.xaml.cs
index 201b4a14..53a9a02c 100644
--- a/App/RobobinApp/Views/CentreGraph.xaml.cs
+++ b/App/RobobinApp/Views/CentreGraph.xaml.cs
@@ -1,23 +1,56 @@
 using Microsoft.Maui.Graphics;
+using Robobin.Models;
+using RobobinApp.Models; // Ensure you have the correct namespace for your Models
 
 namespace RobobinApp.Views
 {
     public class GraphicsDrawable : IDrawable
     {
+        private Graph _graph;
+
+        // Method to set the graph data
+        public void SetGraph(Graph graph)
+        {
+            _graph = graph;
+        }
+
         public void Draw(ICanvas canvas, RectF dirtyRect)
         {
+            if (_graph == null) return;
+
             // Set the background color
-            canvas.FillColor = Colors.LightPink; // Change to your desired color
+            canvas.FillColor = Colors.LightPink;
             canvas.FillRectangle(dirtyRect);
 
-            // Draw some graphics (for example, a circle)
-            canvas.FillColor = Colors.Red;
-            canvas.FillCircle(dirtyRect.Center.X, dirtyRect.Center.Y, 50);
+            // Draw nodes and edges
+            const float nodeRadius = 10; // Radius for nodes
+
+            foreach (var node in _graph.Nodes)
+            {
+                // Draw the node
+                canvas.FillColor = Colors.Red;
+                canvas.FillCircle(node.X, node.Y, nodeRadius);
+                canvas.DrawString(node.Name, node.X + 12, node.Y - 5, HorizontalAlignment.Left);
+
+                // Draw edges based on the adjacency matrix
+                for (int j = 0; j < _graph.Nodes.Count; j++)
+                {
+                    var (magnitude, angle) = _graph.AdjacencyMatrix[_graph.Nodes.IndexOf(node), j];
+
+                    // Only draw if there's a valid connection (magnitude > 0)
+                    if (magnitude > 0)
+                    {
+                        // Calculate the target node's coordinates based on the angle and magnitude
+                        float targetX = node.X + magnitude * MathF.Cos(MathF.PI * (angle / 180));
+                        float targetY = node.Y + magnitude * MathF.Sin(MathF.PI * (angle / 180));
 
-            // Example of drawing text
-            canvas.FontSize = 24;
-            canvas.FillColor = Colors.Black;
-            canvas.DrawString("Hello, GraphicsView!", dirtyRect.Center.X, dirtyRect.Center.Y, HorizontalAlignment.Center);
+                        // Draw edge
+                        canvas.StrokeColor = Colors.Black;
+                        canvas.StrokeSize = 2;
+                        canvas.DrawLine(node.X, node.Y, targetX, targetY); // Draw edge
+                    }
+                }
+            }
         }
     }
 }
diff --git a/App/RobobinApp/Views/MainPage.xaml b/App/RobobinApp/Views/MainPage.xaml
index 0504ed59..d771d9da 100644
--- a/App/RobobinApp/Views/MainPage.xaml
+++ b/App/RobobinApp/Views/MainPage.xaml
@@ -36,6 +36,7 @@
                 <Button Text="Setup" Command="{Binding ConnectToRobobinCommand}"/>
             </HorizontalStackLayout>
 
+            <local:SideBox HeaderTitle="Queue:" />
             <local:SideBox HeaderTitle="Status:" />
         </VerticalStackLayout>
 
@@ -56,6 +57,8 @@
                 <Button Text="Info" />
             </HorizontalStackLayout>
             <local:SideBox HeaderTitle="Mode:" />
+            <local:SideBox HeaderTitle="Admin:" />
+
         </VerticalStackLayout>
     </Grid>
 </ContentPage>
diff --git a/App/RobobinApp/Views/MainPage.xaml.cs b/App/RobobinApp/Views/MainPage.xaml.cs
index 849c5421..6a20095e 100644
--- a/App/RobobinApp/Views/MainPage.xaml.cs
+++ b/App/RobobinApp/Views/MainPage.xaml.cs
@@ -1,5 +1,6 @@
 using Microsoft.Maui.Controls;
-using Microsoft.Extensions.DependencyInjection;
+using RobobinApp.ViewModels; 
+using RobobinApp.Models; 
 
 namespace RobobinApp.Views
 {
@@ -8,6 +9,15 @@ namespace RobobinApp.Views
         public MainPage()
         {
             InitializeComponent();
+
+            // Get the drawable from resources
+            var drawable = (GraphicsDrawable)Resources["drawable"];
+
+            // Set the graph in the drawable using the existing BindingContext
+            if (BindingContext is MainPageViewModel viewModel)
+            {
+                drawable.SetGraph(viewModel.Graph);
+            }
         }
     }
 }
-- 
GitLab