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