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: CanadaPosts: 1109 |
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: AustraliaPosts: 2135 |
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 KingdomPosts: 9115 |
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 KingdomPosts: 9115 |
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: NetherlandsPosts: 4234 |
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: CanadaPosts: 1109 |
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: CanadaPosts: 368 |
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 |