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
-
- VIP Livecode Opensource Backer
- Posts: 3999
- Joined: Sun Jan 07, 2007 9:12 pm
- Location: Bochum, Germany
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 mouseUp
Bernd
-
- VIP Livecode Opensource Backer
- Posts: 3999
- Joined: Sun Jan 07, 2007 9:12 pm
- Location: Bochum, Germany
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 mouseUp
Kind regards
Bernd
-
- VIP Livecode Opensource Backer
- Posts: 2718
- Joined: Sat Dec 22, 2007 5:35 pm
- Location: Genève
- Contact:
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
-
- VIP Livecode Opensource Backer
- Posts: 3999
- Joined: Sun Jan 07, 2007 9:12 pm
- Location: Bochum, Germany
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 283 times
-
- VIP Livecode Opensource Backer
- Posts: 2262
- Joined: Thu Feb 28, 2013 11:52 pm
- Location: Göttingen, DE
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 mouseUp
Code: 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 repeat
shiftLock happens
-
- VIP Livecode Opensource Backer
- Posts: 3999
- Joined: Sun Jan 07, 2007 9:12 pm
- Location: Bochum, Germany
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 repeat
Code: Select all
repeat the num of grcs -- of this card
delete grc 1
end repeat
apparently livecode reevaluates the number of graphics each time when doing
Code: Select all
repeat with h = the number of graphics
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
-
- VIP Livecode Opensource Backer
- Posts: 3999
- Joined: Sun Jan 07, 2007 9:12 pm
- Location: Bochum, Germany
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 294 times
-
- VIP Livecode Opensource Backer
- Posts: 2262
- Joined: Thu Feb 28, 2013 11:52 pm
- Location: Göttingen, DE
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
-
- VIP Livecode Opensource Backer
- Posts: 3999
- Joined: Sun Jan 07, 2007 9:12 pm
- Location: Bochum, Germany
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.
-
- VIP Livecode Opensource Backer
- Posts: 3999
- Joined: Sun Jan 07, 2007 9:12 pm
- Location: Bochum, Germany
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
-
- VIP Livecode Opensource Backer
- Posts: 2262
- Joined: Thu Feb 28, 2013 11:52 pm
- Location: Göttingen, DE
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
-
- VIP Livecode Opensource Backer
- Posts: 3999
- Joined: Sun Jan 07, 2007 9:12 pm
- Location: Bochum, Germany
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