A grid of rectangles
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller
A grid of rectangles
Hi All,
Look this stack with a script to create a grid
of colored rectangles.
How could we make this script much faster
for grids of greater size? (like 256 or 512)
Thanks in advance!
Alejandro
			
			
									
									
						Look this stack with a script to create a grid
of colored rectangles.
How could we make this script much faster
for grids of greater size? (like 256 or 512)
Thanks in advance!
Alejandro
Re: A grid of rectangles
Hi Alejandro,
try this script for the "Create Grid" button
and this for the "Erase Grig" button
Kind regards
Bernd
			
			
									
									
						try this script for the "Create Grid" button
Code: Select all
on mouseUp
   set the cursor to busy
   send "mouseup" to button "Erase Grid"
   lock screen
   put 170 into hLoc
   put 20 into vLoc
   put the label of button "myGridspacing" of this card into tgridSpacing
   put the label of button "myGridsize" of this card into tgridSize
   set the width of the templateGraphic to tGridSpacing
   set the height of the templateGraphic to tGridSpacing
   set the filled of the templateGraphic to true
   set the lineSize of the templateGraphic to empty
   lock messages
   repeat with j = 1 to tgridSize
      repeat with k = 1 to tgridSize
         set the backcolor of the templateGraphic to any item of "red,green,blue,yellow,orange,purple,white"
         set the loc of the templateGraphic to hLoc + (k * tgridSpacing),vLoc
         create graphic 
      end repeat
      put vLoc + tgridSpacing into vLoc
   end repeat
   
   unlock messages
   unlock screen
end mouseUp
Code: Select all
on mouseUp
   set the cursor to busy
   lock screen
   lock messages
   repeat with h = the number of graphics of this card down to 1
      delete graphic h of this card
   end repeat
   lock messages
   unlock screen
end mouseUpBernd
Re: A grid of rectangles
Hi Alejandro,
if you don`t mind to create the graphics in a group then deletion of the graphics would be much faster.
Here are the scripts
for "Create Grid" button
for "Erase Grid" button
If you use the templateGraphic approach then you should reset the templateGraphic before using it and reset the templateGraphic again after you used it. I did that in this post, forgot to add it in the previous one.
Kind regards
Bernd
			
			
									
									
						if you don`t mind to create the graphics in a group then deletion of the graphics would be much faster.
Here are the scripts
for "Create Grid" button
Code: Select all
on mouseUp
   set the cursor to busy
   lock screen
   lock messages
   if there is a group "checkerBoard" then delete group "checkerBoard"
   reset the templateGraphic
   
   put 170 into hLoc
   put 20 into vLoc
   put the label of button "myGridspacing" of this card into tgridSpacing
   put the label of button "myGridsize" of this card into tgridSize
   set the width of the templateGraphic to tGridSpacing
   set the height of the templateGraphic to tGridSpacing
   set the filled of the templateGraphic to true
   set the lineSize of the templateGraphic to empty
   create group "checkerBoard"
   
   repeat with j = 1 to tgridSize
      repeat with k = 1 to tgridSize
         set the backcolor of the templateGraphic to any item of "red,green,blue,yellow,orange,purple,white"
         set the loc of the templateGraphic to hLoc + (k * tgridSpacing),vLoc
         create graphic in group "checkerBoard"
      end repeat
      put vLoc + tgridSpacing into vLoc
   end repeat
   
   reset the templateGraphic
   unlock messages
   unlock screen
end mouseUp
Code: Select all
on mouseUp
   set the cursor to busy
   lock screen
   lock messages
   if there is a group "checkerBoard" then delete group "checkerBoard"
   lock messages
   unlock screen
end mouseUpKind regards
Bernd
Re: A grid of rectangles
Hi Alejandro and Bernd,
I began with a clone approach but Bernd's way is faster, like its author.
1268 milliseconds for a 64X64 grid (7505 with the first version)
Kind regards
			
			
									
									I began with a clone approach but Bernd's way is faster, like its author.
1268 milliseconds for a 64X64 grid (7505 with the first version)
Kind regards
https://alternatic.ch
						Re: A grid of rectangles
Salut Jean-Marc,
@Alejandro,
if you don't necessarily need graphics for the grid then here is a version that does an image with the same appearence as the graphics grid. The advantage is that you don't create a gazillion graphics but only one image. Of course it then is, well, just an image.
Kind regards
Bernd
Edit: I forgot to mention that the coloname to RGB conversion is in a custom property of the card as an array. This means you can use any valid colorName in the variable for colors to fill the grid.
			
							@Alejandro,
if you don't necessarily need graphics for the grid then here is a version that does an image with the same appearence as the graphics grid. The advantage is that you don't create a gazillion graphics but only one image. Of course it then is, well, just an image.
Kind regards
Bernd
Edit: I forgot to mention that the coloname to RGB conversion is in a custom property of the card as an array. This means you can use any valid colorName in the variable for colors to fill the grid.
- Attachments
 - 
			
		
		
				
- Create Grid Image.livecode.zip
 - (7.48 KiB) Downloaded 387 times
 
 
Re: A grid of rectangles
Hi all,
that's an impressive demo of using "the template graphic" here.
Bernd, your first script runs here much faster than your 'grouping-script', using for deletion the following:
This script, using as parameters
= a grid size of 64 (= 64*64 = 4096 objects)
= a gridspacing of 20
runs here, on a medium fast machine (2.5 GHz),
in 80 millisecs with LC 7/8, in 40 millisecs with LC 6.
So, creating objects in a group is much slower. But the grouping possibly has several advantages later on, when working with the objects. TMHO it still depends on the project, what's *effectively* better/faster.
EDIT. WARNING.
If you choose a gridSize of 256 or more then you exceed with the number of objects (256^2 or more) the "limit of LiveCode" which is 65535 (=2^16-1). This is still in LC 8 and will 'silently' not execute (parts of) the above scripts.
Then you should replace in both scripts:
			
			
									
									that's an impressive demo of using "the template graphic" here.
Bernd, your first script runs here much faster than your 'grouping-script', using for deletion the following:
Code: Select all
-- delete all graphics
-- button "Erase Grid"
on mouseUp
  lock screen; lock messages
  repeat the num of grcs -- of this card
    delete grc 1
  end repeat
  unlock messages; unlock screen
end mouseUpCode: Select all
-- Bernd's script slightly modified
-- button "Create Grid"
on mouseUp
  put the millisecs into m1
  put 120 into hLoc
  put 20 into vLoc
  
  set cursor to watch
  lock screen; lock messages
  -- in case you test with grouping
  if there is a grp "checkerboard" then delete grp "checkerboard"
  set the randomseed to the seconds
  ---use now a simple deletion 'inline':
  repeat the num of grcs -- of this card
    delete grc 1
  end repeat
  ---
  reset the templateGraphic
  
  put the label of button "myGridspacing" into tgridSpacing
  put the label of button "myGridsize" into tgridSize
  set the width of the templateGraphic to tGridSpacing
  set the height of the templateGraphic to tGridSpacing
  set the lineSize of the templateGraphic to 0
  set the filled of the templateGraphic to true
  --set the style of the templateGraphic to "rectangle"
  -- Try this, looks nice:
  set the style of the templateGraphic to "oval"
  --   set the style of the templateGraphic to "regular"
  --   set the polysides of the templateGraphic to "3"
  --   set the angle of the templateGraphic to "-90"
  repeat with j = 1 to tgridSize
    repeat with k = 1 to tgridSize
      set the backcolor of the templateGraphic to any item of \
            "red,green,blue,yellow,orange,purple,white"
      set the loc of the templateGraphic to hLoc + (k * tgridSpacing),vLoc
      -- create graphic in grp "checkerboard" -- slower
      create graphic
    end repeat
    add tgridSpacing to vLoc
  end repeat
  reset the templateGraphic
  put the millisecs-m1 into fld "info"
  unlock messages; unlock screen
end mouseUp= a grid size of 64 (= 64*64 = 4096 objects)
= a gridspacing of 20
runs here, on a medium fast machine (2.5 GHz),
in 80 millisecs with LC 7/8, in 40 millisecs with LC 6.
So, creating objects in a group is much slower. But the grouping possibly has several advantages later on, when working with the objects. TMHO it still depends on the project, what's *effectively* better/faster.
EDIT. WARNING.
If you choose a gridSize of 256 or more then you exceed with the number of objects (256^2 or more) the "limit of LiveCode" which is 65535 (=2^16-1). This is still in LC 8 and will 'silently' not execute (parts of) the above scripts.
Then you should replace in both scripts:
Code: Select all
--replace the lines:
  repeat the num of grcs -- of this card
    delete grc 1 -- of this card
  end repeat
 
-- with the slower but safer lines:
  repeat while there is a grc 1 -- of this card
    delete grc 1 -- of this card
  end repeatshiftLock happens
						Re: A grid of rectangles
Hi Hermann,
that looks very nice, your effects.
I did not really benchmark this, it was benchmarking by feeling.
what got me to use a group was twofold: first the original deletion was really slow. Deleting a group is nearly instantaneous.
I use
instead of your 
your code is a lot faster than mine.
apparently livecode reevaluates the number of graphics each time when doing
Your observation that creating a graphic in a group is much slower than directly to the card surprises me by the magnitude of the effect.
The net effect of deleting the group, recreating it and placing the graphics into the group was a lot faster than the old deletion handler.
That is why I did not notice the stark difference in execution time for creating graphics in a group.
Again I did what Alejandro said: make it much faster.
 And so it was.
A second argument for a group was that it makes it a lot easier to move around. Although dragging a group in the IDE with that many graphics is very slow.
I think Alejandro should say what the use case is and if he really needs graphics. He speaks of up to 512 * 512 cells. That this will probably choke Livecode. So I looked again into doing this using ImageData. I will post below my improved version which creates a 64 by 64 grid with cell width 20 in around 130 milliseconds. This compares quite favorably with using graphics.
A 256 by 256 grid cell size 20 take about 2100 milliseconds and does not choke Livecode. All time for 8.1.1 RC 1 on 2.5 MHz Intel core i5.
Thanks for looking into this.
Kind regards
Bernd
			
			
									
									
						that looks very nice, your effects.
I did not really benchmark this, it was benchmarking by feeling.
what got me to use a group was twofold: first the original deletion was really slow. Deleting a group is nearly instantaneous.
I use
Code: Select all
repeat with h = the number of graphics of this card down to 1
      delete graphic h of this card
   end repeatCode: Select all
repeat the num of grcs -- of this card
    delete grc 1
  end repeatapparently livecode reevaluates the number of graphics each time when doing
Code: Select all
repeat with h = the number of graphicsThe net effect of deleting the group, recreating it and placing the graphics into the group was a lot faster than the old deletion handler.
That is why I did not notice the stark difference in execution time for creating graphics in a group.
Again I did what Alejandro said: make it much faster.
A second argument for a group was that it makes it a lot easier to move around. Although dragging a group in the IDE with that many graphics is very slow.
I think Alejandro should say what the use case is and if he really needs graphics. He speaks of up to 512 * 512 cells. That this will probably choke Livecode. So I looked again into doing this using ImageData. I will post below my improved version which creates a 64 by 64 grid with cell width 20 in around 130 milliseconds. This compares quite favorably with using graphics.
A 256 by 256 grid cell size 20 take about 2100 milliseconds and does not choke Livecode. All time for 8.1.1 RC 1 on 2.5 MHz Intel core i5.
Thanks for looking into this.
Kind regards
Bernd
Re: A grid of rectangles
Here is an improved grid using imageData and an image.
It is about 30 percent faster than the former one. Posted above. The rest is identical.
The faster code is in button "Create GridImageII".
Kind regards
Bernd
			
							It is about 30 percent faster than the former one. Posted above. The rest is identical.
The faster code is in button "Create GridImageII".
Kind regards
Bernd
- Attachments
 - 
			
		
		
				
- Create Grid Image II.livecode.zip
 - hurry, hurry, make an image
 - (7.85 KiB) Downloaded 387 times
 
 
Re: A grid of rectangles
Bernd,
your first graphic script I used above is here still faster than "Create GridImage II"?
[for gridsize 256, gridspacing 20 at about 1 second]
Obviuosly the gridspacing has by enlarging the size of the image more impact than in the graphics solution.
Perhaps: If you make a one-pixel grid (temporary gridspacing=1), set the resizeQuality of your image to "normal", and then resize by factor gridspacing?
This should result in an identical output, but may result in a faster runtime?
Hermann
Edit. Set the resizeQuality of the image to "good" and we have, with slightly more cpu-time, this well-known nice blur-effect (see also http://forums.livecode.com/viewtopic.ph ... 51#p141051 and the link there).
			
							
			
									
									your first graphic script I used above is here still faster than "Create GridImage II"?
[for gridsize 256, gridspacing 20 at about 1 second]
Obviuosly the gridspacing has by enlarging the size of the image more impact than in the graphics solution.
Perhaps: If you make a one-pixel grid (temporary gridspacing=1), set the resizeQuality of your image to "normal", and then resize by factor gridspacing?
This should result in an identical output, but may result in a faster runtime?
Hermann
Edit. Set the resizeQuality of the image to "good" and we have, with slightly more cpu-time, this well-known nice blur-effect (see also http://forums.livecode.com/viewtopic.ph ... 51#p141051 and the link there).
shiftLock happens
						Re: A grid of rectangles
Hermann,
Button "Create ImageII" roughly 2100 milliseconds.
Producing a 5120 by 5120 pixel image.
Button "Create Grid" -> graphic roughly 1500 milliseconds for 65536 graphics. I noticed I could not delete the graphics with your button unless I deleted 1 graphic manually.
But at "reasonable" dimensions image is still quite fast.
Your idea to reduce the cellSize to 1 and then rescale is brilliant.
It reduces the time for a 256 by 256 gridSize with a cell size of 20 to roughly 350 milliseconds from 2100. No discernible difference in image Quality.
Here is the script I used
make a new button with this script in stack "Create Image II"
Kind regards
Bernd
			
			
									
									
						Button "Create ImageII" roughly 2100 milliseconds.
Producing a 5120 by 5120 pixel image.
Button "Create Grid" -> graphic roughly 1500 milliseconds for 65536 graphics. I noticed I could not delete the graphics with your button unless I deleted 1 graphic manually.
But at "reasonable" dimensions image is still quite fast.
Your idea to reduce the cellSize to 1 and then rescale is brilliant.
It reduces the time for a 256 by 256 gridSize with a cell size of 20 to roughly 350 milliseconds from 2100. No discernible difference in image Quality.
Here is the script I used
Code: Select all
on mouseUp
   set the cursor to busy
   lock screen
   lock messages
   put the milliseconds into tTime
   
   if not (there is an image "testImg") then create image "testImg"
   
   local tAlpha
   put numToByte(255) into tAlpha
   
   put the cColorNameToRGB of this card into tTranslateColorA
   
   -- get RGB values
   local tColorNames
   put "red,green,blue,yellow,orange,purple,white" into tColorNames
   
   local tColorA
   local tR; local tG; local tB; local tTriplet
   
   repeat for each item aColor in tColorNames
      put tTranslateColorA[aColor] into tTriplet
      put numToByte(item 1 of tTriplet) into tR
      put numToByte(item 2 of tTriplet) into tG
      put numToByte(item 3 of tTriplet) into tB
      put tAlpha & tR & tG & tB into tColorA[aColor]
   end repeat
   
   
   put the label of button "myGridspacing" into tCellWidth
   put the label of button "myGridsize" into tNoOfCells
   put tCellWidth * tNoOfCells into tPixelWidth
   put 1 into tempCellWidth
   put the keys of tColorA into tKeys
   
   local tOneLIneOfCellA
   
   repeat for each key aColorByte in tColorA
      repeat tCellWidth
         put tColorA[aColorByte] after tOneLineOfCellA[aColorByte]
      end repeat
   end repeat
   
   put "" into tAllPixel
   repeat tNoOfCells
      put giveOnCellHeightData(tNoOfCells, tempCellWidth, tOneLineOfCellA) into tOneCellHeight
      put tOneCellHeight after tAllPixel
      put ""  into tOneCellHeight
   end repeat
   
   set the width of image "testImg" to tPixelWidth
   set the height of image "testImg" to tNoOfCells
   
   set the imageData of img "testImg" to tAllPixel
   
   set the height of img "testImg" to tPixelWidth
   set the topLeft of image "testImg" to 150,30
   unlock messages
   unlock screen
   put the milliseconds - tTime
end mouseUp
private function giveOnCellHeightData @tNoOfCells, @tempCellWidth, @tOneLineOfCellA
   put the keys of tOneLineOfCellA into tKeys
   repeat tNoOfCells
      put "" into tCell1PxHeightColor
      put any line of tKeys into tKey
      put tOneLineOfCellA[tKey] after tCell1PxHeightColor
      put tCell1PxHeightColor after t1PixLine
   end repeat
   repeat tempCellWidth
      put t1PixLine after tOneCellHeight
   end repeat
   return tOneCellHeight
end giveOnCellHeightData
Kind regards
Bernd
Re: A grid of rectangles
Hi Bernd and Hermann,
This script that I posted was created with a purely didactic purpose. It's part of a stack that explain visually (and step-by-step) the kind of mathematical operations used to create and modify bitmap images.
I am grateful surprised by the optimizations that two LiveCode professionals could make to a simple handler.
Lock messages is the kind of optimization that always slips out of my mind. I have to test if this code would optimize the creation of graphics in the stack EpsImportv05c.
After watching how fast your scripts could handle the creation of bitmaps, I just keep wondering if the results posted in this old thread are still valid and current:
http://forums.livecode.com/viewtopic.php?f=6&t=8918
In 2016, LiveCode is much faster than 5 years ago and it's source code have been optimized many times since then. For example, the problem exposed in this another thread was solved in LiveCode 6.5.x and now renders as the Lingo and Photoshop example.
Test this by yourself. Download the file named "Image_Effects.zip" from a message in page 1 of this thread and test the stack using LiveCode 6.5.x.or later.
I found no differences, using a Posterization of 6, with the Photoshop and Director's image posted in page 1 of this thread: http://forums.livecode.com/viewtopic.php?f=32&t=8993
Al
			
			
													This script that I posted was created with a purely didactic purpose. It's part of a stack that explain visually (and step-by-step) the kind of mathematical operations used to create and modify bitmap images.
I am grateful surprised by the optimizations that two LiveCode professionals could make to a simple handler.
Lock messages is the kind of optimization that always slips out of my mind. I have to test if this code would optimize the creation of graphics in the stack EpsImportv05c.
After watching how fast your scripts could handle the creation of bitmaps, I just keep wondering if the results posted in this old thread are still valid and current:
http://forums.livecode.com/viewtopic.php?f=6&t=8918
In 2016, LiveCode is much faster than 5 years ago and it's source code have been optimized many times since then. For example, the problem exposed in this another thread was solved in LiveCode 6.5.x and now renders as the Lingo and Photoshop example.
Test this by yourself. Download the file named "Image_Effects.zip" from a message in page 1 of this thread and test the stack using LiveCode 6.5.x.or later.
I found no differences, using a Posterization of 6, with the Photoshop and Director's image posted in page 1 of this thread: http://forums.livecode.com/viewtopic.php?f=32&t=8993
Al
					Last edited by capellan on Mon Oct 10, 2016 1:36 am, edited 1 time in total.
									
			
									
						Re: A grid of rectangles
Hi Alejandro,
this is a special case of imageData manipulation that lends itself to optimization.
Unfortunately not all imageData operation are faster in 8.x compared to 6.x. Iterating over every pixel is slower than it used to be. And in most cases of image manipulation you have to do that. Certain optimizations are possible on a case by case basis. This has to be done differently for every type of image manipulation.
The "worst case" is convolve where you are forced to go through byteToNum and numToByte over and over again.
But in many cases a little optimization helps.
The script may not be so obvious afterwards though...
Kind regards
Bernd
			
			
									
									
						this is a special case of imageData manipulation that lends itself to optimization.
Unfortunately not all imageData operation are faster in 8.x compared to 6.x. Iterating over every pixel is slower than it used to be. And in most cases of image manipulation you have to do that. Certain optimizations are possible on a case by case basis. This has to be done differently for every type of image manipulation.
The "worst case" is convolve where you are forced to go through byteToNum and numToByte over and over again.
But in many cases a little optimization helps.
The script may not be so obvious afterwards though...
Kind regards
Bernd
Re: A grid of rectangles
Use imageJIT ...bn wrote:The "worst case" is convolve where you are forced to go through byteToNum and numToByte over and over again.
http://forums.livecode.com/viewtopic.ph ... 32#p143932
shiftLock happens
						Re: A grid of rectangles
I understand. Looks like a little help from LiveCode Engine could help a great length in bitmap edition and creation.
If both of you could add to LC Engine just one function for bitmap manipulation,
Which would you choose?
1) A function to replace the pixels of the imagedata of an image
with the pixels of another image (starting at any location within
the imagedata). (i.e. paste an image into other image)
2) A function to copy (and distort) the pixels of the imagedata of an image
within four coordinates (like a trapezoid) or three points (like a triangle)
of another image.
Al
			
			
									
									
						If both of you could add to LC Engine just one function for bitmap manipulation,
Which would you choose?
1) A function to replace the pixels of the imagedata of an image
with the pixels of another image (starting at any location within
the imagedata). (i.e. paste an image into other image)
2) A function to copy (and distort) the pixels of the imagedata of an image
within four coordinates (like a trapezoid) or three points (like a triangle)
of another image.
Al
Re: A grid of rectangles
neither really. More basic. A speed-up in byte iteration would go a long way.1) A function to replace the pixels of the imagedata of an image
with the pixels of another image (starting at any location within
the imagedata). (i.e. paste an image into other image)
2) A function to copy (and distort) the pixels of the imagedata of an image
within four coordinates (like a trapezoid) or three points (like a triangle)
of another image.
as far as your question is concerned:
1. is not that hard to do and quite fast since you could insert wholesale imagedate. Or just use snapshots, that is the easiest and fastest.
see this topic: http://forums.livecode.com/viewtopic.ph ... +watermark
2. is a special case with little use to me.
Kind regards
Bernd
