As I often need to experiment with visually represented matrices on a grid, I always have this B4J project ready to start prototyping.
Hopefully, it might be of interest to some of you.
Enjoy.
Hopefully, it might be of interest to some of you.
B4X:
#Region Project Attributes
#MainFormWidth: 600
#MainFormHeight: 600
#IgnoreWarnings: 12
#End Region
#Region Init
Sub Process_Globals
Type Grid(gridStep As Double, sizeX As Int, sizeY As Int, width As Double, height As Double, left As Double, right As Double, top As Double, btm As Double, matrix(,) As Int)
Type Point(x As Double, y As Double)
Private fx As JFX
Private MainForm As Form
Private cvs As Canvas
Private cvsCenterX As Double
Private cvsCenterY As Double
Private testGrid As Grid
Private MainLoop As Timer
Private colorMap As Map
End Sub
Sub AppStart (Form1 As Form, Args() As String)
MainForm = Form1
MainForm.Resizable = False
MainForm.Show
cvs.Initialize("cvs")
MainForm.RootPane.AddNode(cvs, 0, 0, MainForm.Width, MainForm.Height)
cvsCenterX = cvs.Width / 2
cvsCenterY = cvs.Height / 2
colorMap.Initialize
colorMap.Put(1, fx.Colors.Red)
colorMap.Put(2, fx.Colors.Green)
colorMap.Put(3, fx.Colors.Blue)
InitCode
MainLoop.Initialize("MainLoop", 16)
MainLoop.Enabled = True
End Sub
#End Region
#Region User Code
Sub InitCode
InitializeGrid(20, 20, 20)
'RandomlyPopulateGrid(10)
End Sub
Sub MainLoop_Tick
DrawAll
End Sub
#End Region
#Region User Functions
'Your stuff goes here
#End Region
#Region Utilities
'Returns the pixel center of the given cell
Sub GridToPixel(gridX As Int, gridY As Int) As Point
Dim p As Point : p.initialize
p.x = (testGrid.left + (gridX * testGrid.gridStep)) + (testGrid.gridStep / 2)
p.y = (testGrid.top + (gridY * testGrid.gridStep)) + (testGrid.gridStep / 2)
Return p
End Sub
'Returns the cell corresponding to the given pixel location
Sub PixelToGrid(x As Double, y As Double) As Point
Dim p As Point : p.initialize
p.x = Max(Min((-testGrid.left + x) / testGrid.gridStep, testGrid.sizeX - 1), 0)
p.y = Max(Min((-testGrid.top + y) / testGrid.gridStep, testGrid.sizeY - 1), 0)
Return p
End Sub
#End Region
#Region PreBaked Code
Sub InitializeGrid(sizeX As Int, sizeY As Int, gridStep As Double)
If gridStep <= 0 Then gridStep = 10
If sizeX <= 0 Or sizeY <= 0 Then
sizeX = cvs.Width / gridStep
sizeY = cvs.Height / gridStep
End If
testGrid.Initialize
testGrid.gridStep = gridStep
testGrid.sizeX = sizeX
testGrid.sizeY = sizeY
testGrid.width = sizeX * gridStep
testGrid.height = sizeY * gridStep
testGrid.left = cvsCenterX - (testGrid.width / 2)
testGrid.top = cvsCenterY - (testGrid.height / 2)
testGrid.right = testGrid.left + testGrid.width
testGrid.btm = testGrid.top + testGrid.height
Dim matrix(sizeX, sizeY) As Int : testGrid.matrix = matrix
End Sub
Sub RandomlyPopulateGrid(densityPercentage As Int)
Dim lowest = 1, highest As Int
For Each key In colorMap.Keys : highest = Max(highest, key) : Next
For x = 0 To testGrid.sizeX - 1
For y = 0 To testGrid.sizeY - 1
If Rnd(0, 101) > densityPercentage Then Continue
testGrid.matrix(x, y) = Rnd(lowest, highest + 1)
Next
Next
End Sub
Sub DrawAll
ClearCanvas
DrawCells
DrawGrid
End Sub
Sub DrawCells
Dim gX, gY As Double
For x = 0 To testGrid.sizeX - 1
gX = testGrid.left + (x * testGrid.gridStep)
For y = 0 To testGrid.sizeY - 1
gY = testGrid.top + (y * testGrid.gridStep)
If testGrid.matrix(x, y) > 0 Then
cvs.DrawRect(gX, gY, testGrid.gridStep, testGrid.gridStep, colorMap.Get(testGrid.matrix(x, y)), True, 0)
End If
Next
Next
End Sub
Sub ClearCanvas
cvs.ClearRect(0, 0, cvs.Width, cvs.Height)
End Sub
Sub DrawGrid
For x = testGrid.left To (testGrid.left + testGrid.width) Step testGrid.gridStep
cvs.DrawLine(x, testGrid.top, x, testGrid.btm, fx.Colors.DarkGray, 1)
Next
For y = testGrid.top To (testGrid.top + testGrid.height) Step testGrid.gridStep
cvs.DrawLine (testGrid.left, y, testGrid.right, y, fx.Colors.DarkGray, 1)
Next
End Sub
#End Region
#Region User Interface
Sub cvs_MousePressed(eventData As MouseEvent)
Dim p = PixelToGrid(eventData.X, eventData.Y) As Point
If eventData.PrimaryButtonDown Then testGrid.matrix(p.x, p.y) = 1 Else testGrid.matrix(p.x, p.y) = 0
End Sub
Sub cvs_MouseDragged(eventData As MouseEvent)
Dim p = PixelToGrid(eventData.X, eventData.Y) As Point
If eventData.PrimaryButtonDown Then testGrid.matrix(p.x, p.y) = 1 Else testGrid.matrix(p.x, p.y) = 0
End Sub
#End Region
Enjoy.
Attachments
Last edited: