Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 21:41 26 Nov 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : MMBasic: Expand MATH, 2D Arrays and Drawing

Author Message
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1109
Posted: 04:39am 11 Jan 2024
Copy link to clipboard 
Print this post

I would like to offer some new commands, and possible changes/additions to existing ones for consideration.

The main purpose is to allow 2D arrays for many of the drawing commands that accept arrays for x and y coordinates. My offered suggestions fall into 2 categories. The first relates to drawing commands such as PIXEL,LINE,CIRCLE and POLYGON. (Circle is likely less important, but it looks cool.) The second category relates to MATH commands to help manipulate these arrays.

Consider the command
POLYGON n, xarray%(),yarray%() [, bordercolour] [,fillcolour]
My idea is that it be possible to combine "xarray%()" and "yarray%()" into one 2D array "array%(somesize,1)" (assuming OPTION BASE 0.) The commands for PIXEL and LINE, maybe CIRCLE and others would be similar. Yes, this can be replicated with the SLICE command easily enough - my attached demo program does just that.

Some added or altered MATH commands would make handling these arrays that much easier and faster. The missing command MATH ROTATE2D would be very useful. The other convenient commands would be MATH SCALE2D and MATH TRANSLATE2D. These differ slightly from the existing equivalent in that x and y scale and offset values need not be the same.

The attached demo program implements these commands in MMBasic, although not with the full flexibility that similar firmware commands exhibit - mainly because I can't figure out how to pass a variable that may or may not be an array.

The idea for these commands comes from examining porting Rocks in Space to the PicoMite and Stan's idea to draw items on the fly, instead of pre-created sprites that use huge amounts of memory.

I would also like to suggest a small change to the POLYGON command. Currently, this command will automatically close the polygon. The size parameter could be changed so that negative values mean "Do not close." This feature would be very useful for drawing graphs. The data is in a 2D array, you just POLYGON -n,array2D() and bam, there it is.

Thanks for your consideration

ps. It would be nice if the BOUND() function returned 0, or maybe -1, when applied to a simple variable. Is there a way to determine the length of a string? Not the current number of characters, but the length.

==========
A side question, does FRAMEBUFFER LAYER not work in mode 1?

' 2D Command Demo
' by Vegipete, Jan 2024

mode 2 ' otherwise FRAMEBUFFER LAYER doesn't work
Option DEFAULT INTEGER
Option LCDPANEL NOCONSOLE
Option angle degrees

Const NUMSIDES = 7

dim desc$(10) length 50
desc$(1) = "A regular polygon"
desc$(2) = "Same polygon, draw vertices only"
desc$(3) = "Draw circles at the vertices"
desc$(4) = "Lines from the vertices"
desc$(5) = "Polygon and lines"
desc$(6) = ""
Dim float vert(NUMSIDES-1,1), v1(NUMSIDES-1,1)
Dim float ang

CLS 0
FRAMEBUFFER Layer
FRAMEBUFFER Write L : CLS 0

' Generate a regular polygon
r = 25 : ang = 360/NUMSIDES
For i=0 To NUMSIDES-1:vert(i,0)=r*Sin(i*ang):vert(i,1)=r*Cos(i*ang):Next

for i = 1 to 5
 FRAMEBUFFER Write L : CLS 0
 text 20,20,desc$(i)
 FRAMEBUFFER Write N
 PerformStuff(vert(),i)
 Pause 1000
next
FRAMEBUFFER close
end

Sub PerformStuff(vert() As Float,d)
 Local i,n = Bound(vert())
 Local float v1(n,1)   ' local working copy of vertex cloud
 Local float v2(n,1)

 For i=1 To 100
   Math Scale vert(),1,v1()      ' copy to working
   Math2DArrayScale(v1(),i/20,i/20)   ' scale copy of vertex cloud
   Math2DArrayRotate(v1(),i*3.6) ' rotate it
   Math2DArrayAdd(v1(),MM.HRes/2,MM.VRes/2)    ' translate it
   
   CLS
   Select Case d
     Case 1
       Polygon2d(NUMSIDES,v1(),RGB(white),RGB(black))
     Case 2
       Pixel2d(v1(),RGB(white))
     Case 3
       Circle2d(v1(),1+i/2,RGB(white))
     Case 4
       Math Set 0,v2()
       Math2DArrayAdd(v2(),MM.HRes/2+(i-50)*4,MM.VRes/2)
       Line2d(v1(),v2(),RGB(white))
     Case 5
       Math Set 0,v2()
       Math2DArrayAdd(v2(),MM.HRes/2+(i-50)*4,MM.VRes/2)
       Line2d(v1(),v2(),RGB(white))
       Polygon2d(NUMSIDES,v1(),RGB(white),RGB(black))
   End Select
   Pause 50
 Next

End Sub

' Drawing routines similar to firmware but accept 2D array
'
' Draw a polygon using data from a 2D array
Sub Polygon2d(n,coor() As Float,c1,c2)
 Local float x(n-1),y(n-1)
 Math slice coor(),,0,x()  ' yank out x axis data
 Math slice coor(),,1,y()  '  and y axis data
 Polygon n,x(),y(),c1      ' use built in function
End Sub

' Draw a pixel cloud using data from a 2D array
Sub Pixel2d(coor() As Float,c1)
 Local n = Bound(coor())
 Local float x(n),y(n)
 Math slice coor(),,0,x()  ' yank out x axis data
 Math slice coor(),,1,y()  '  and y axis data
 Pixel x(),y(),c1      ' use built in function
End Sub

' Draw a circle cloud using data from a 2D array
Sub Circle2d(coor() As Float,r As Float,c1)
 Local n = Bound(coor())
 Local float x(n),y(n),rs(n)
 Math slice coor(),,0,x()  ' yank out x axis data
 Math slice coor(),,1,y()  '  and y axis data
 Math set r,rs()           ' all radii the same
 Circle x(),y(),rs(),,,c1      ' use built in function
End Sub

' Draw a line cloud using data from a pair of 2D arrays
Sub Line2d(b() As Float,e() As Float,c1)
 Local n = Bound(b())
 Local float x1(n),y1(n),x2(n),y2(n)
 Math slice b(),,0,x1()
 Math slice b(),,1,y1()
 Math slice e(),,0,x2()
 Math slice e(),,1,y2()
 Line x1(),y1(),x2(),y2(),,c1  ' use built in function
End Sub

' Math functions that manipulate 2D arrays as coordinates
'
' Scale array, x and y scaling factors can be different
Sub Math2DArrayScale(arry() As float,x As float,y As float)
 Local n = Bound(arry())
 Local float t(n)
 Math slice arry(),,0,t()
 Math scale t(),x,t()
 Math insert arry(),,0,t()
 Math slice arry(),,1,t()
 Math scale t(),y,t()
 Math insert arry(),,1,t()
End Sub

' Translate array
Sub Math2DArrayAdd(arry() As float,x As float,y As float)
 Local n = Bound(arry())
 Local float t(n)
 Math slice arry(),,0,t()
 Math add t(),x,t()
 Math insert arry(),,0,t()
 Math slice arry(),,1,t()
 Math add t(),y,t()
 Math insert arry(),,1,t()
End Sub

' Rotate coordinate pairs in array
Sub Math2DArrayRotate(arry() As float,ang As float)
 Local i,n
 Local float tmp,sa,ca

 n = Bound(arry())
 sa = Sin(ang) : ca = Cos(ang)
 For i = 0 To n
   tmp = arry(i,0)
   arry(i,0) = tmp * ca - arry(i,1) * sa
   arry(i,1) = tmp * sa + arry(i,1) * ca
 Next
End Sub


Edited 2024-01-11 14:40 by vegipete
Visit Vegipete's *Mite Library for cool programs.
 
phil99

Guru

Joined: 11/02/2018
Location: Australia
Posts: 2135
Posted: 05:37am 11 Jan 2024
Copy link to clipboard 
Print this post

  Quote  I would also like to suggest a small change to the POLYGON command. Currently, this command will automatically close the polygon. The size parameter could be changed so that negative values mean "Do not close." This feature would be very useful for drawing graphs.
While waiting for that, a work-around might be adding vertical lines to the start and finish down to the x axis which closes the polygon. It could then be filled for maximum effect.

For your proposal, as Fill would not be possible a negative Fill value could be the "Do not close." parameter.
Edited 2024-01-11 15:40 by phil99
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9115
Posted: 08:53am 11 Jan 2024
Copy link to clipboard 
Print this post

It isn't sensible to change existing drawing commands for obvious reasons. I can look at a math rotate command which would also take separate x an y arrays, together with the X an y coordinates of the point to rotate around.
Overloading the polygon command for non-closed elements doesn't make sense but I'll look at another variant of the line command.
The layer buffer isn't automatically implemented in mode 1. I don't know if I have enough CPU cycles to do it, but I'll look at it.
I'm not intending to change the bound function.
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 9115
Posted: 08:53am 11 Jan 2024
Copy link to clipboard 
Print this post

It isn't sensible to change existing drawing commands for obvious reasons. I can look at a math rotate command which would also take separate x an y arrays, together with the X an y coordinates of the point to rotate around.
Overloading the polygon command for non-closed elements doesn't make sense but I'll look at another variant of the line command.
The layer buffer isn't automatically implemented in mode 1. I don't know if I have enough CPU cycles to do it, but I'll look at it.
I'm not intending to change the bound function.
 
Volhout
Guru

Joined: 05/03/2018
Location: Netherlands
Posts: 4234
Posted: 09:39am 11 Jan 2024
Copy link to clipboard 
Print this post

Peter,

I am not sure what vegipete is suggesting helps my project in any way.

1/ We have "MATH SCALE", "MATH ADD" and recently "MATH SHIFT" that apply a multiplication or addition or bit shift to any value in an array. I could use a "MATH AND" to do a logic AND to every value in an array. Or maybe this can be arranged more universal in a format where you present a formula that is applied to every value.

MATH MATH (AND &h230012),a%(),b%()
MATH MATH (SQRT()),a(),b()

Volhout
Edited 2024-01-12 00:30 by Volhout
PicomiteVGA PETSCII ROBOTS
 
vegipete

Guru

Joined: 29/01/2013
Location: Canada
Posts: 1109
Posted: 08:04pm 11 Jan 2024
Copy link to clipboard 
Print this post

MATH ROTATE with separate arrays for x and y would work fine. I was concerned about the possible number of parameters - 2 in arrays, 2 out arrays, plus center x & y and rotation angle.

A related thought about slicing. Would it be possible to "auto-slice" for commands that work with arrays. For example
Pixel array(,0),array(,1),col
where array is dimmed at least as (n,1).
Visit Vegipete's *Mite Library for cool programs.
 
PeteCotton

Guru

Joined: 13/08/2020
Location: Canada
Posts: 368
Posted: 05:08pm 12 Jan 2024
Copy link to clipboard 
Print this post

  matherp said  I can look at a math rotate command which would also take separate x an y arrays, together with the X an y coordinates of the point to rotate around.


At the risk of taking a mile when offered an inch, but would it make sense to include scale as an optional parameter (default=1) into this function as well?

It requires the same steps as rotate (move x,y co-ordinate to relative zero, perform rotate [perform scale], move x,y back from relative zero). That would allow people to zoom in/out 2D polygons at the same time as spinning them.
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024