The following post is about a related issue which uses a very similar technique, but I will also explain the encryption decryption method along the way.
Imagine you want to visit every pixel in an image in random order but you do not want to visit any pixel more than once. Obviously what you cannot to is to simply pick a series of random x/y coordinates and hope that you will hit non-visited pixels as often as possible. The problem is that even for a very small image of 100x100 pixels (which contains 10000 pixels) the probability that you hit a non-visited pixel will change from 100% (when you set the first pixel) to 0.01% (when you try to hit that last non-visited pixel) whilst you proceed through the image.
So another approach you might be tempted to try is to first store a list of all possible coordinates in an array then shuffle that list and finally visit the coordinates in the order they get served from that array. This will work and for small images it might even be okay to create and shuffle a list of 10000 elements. But when you get into areas of typically sized images this approach is definitely not optimum. Having to shuffle 480000 items in realtime doesn't sound like fun.
So what's the alternative? The one way to do it is actually being used internally by the Flash player - inside the notorious BitmapData.pixelDissolve() function. It uses a so called linear feedback shift register which is a really nifty numerical apparatus that produces a unique random-looking order of all integers between 1 and x. The only issue is that it's pretty hard to implement a random seed for this technique which is why you don't find that as a property in the Flash implementation. This means that for each image of the same dimension the order in which the pixels are visited will always be identical.
But there's obviously another option. Imagine an image like a gigantic 2-dimensional Rubic's Cube. Now shift each vertical pixel column by a different random amount up or down. Those pixels that end outside the image will wrap around and be reinserted on the other side. Repeat that process for all pixel rows. Then once more for the columns and for the rows again. This is the equivalent of randomly rotating a magic cube. Now the interesting part is that you will not loose a single pixel in this process. No pixel will be accidentaly overwritten by another one moving over it. This means each original pixel will still be there only on a different location. What's even nicer is that if you knew the exact order in which the columns and rows had been offset you could revert that process and unscramble the image when you just apply it backwards. That is what actually happens in the Peacock example above. BTW - this technique is not limited to bitmaps, you can use it to scramble and unscramble any kind of data.
But what I actually wanted to show you here is another class which employs no bitmapData, noise or displacementMap filters at all but just uses plain math to achieve a similar result: the CoordinateShuffler class will return you a list of uniquely shuffled coordinates for images of arbitrary sizes. Since it only needs to create two small lookup tables it is very lightweight and fast and should come handy whenver you want to check a part of an image's pixels randomly, spread elements over an image or create a random transition but want to make sure that in the end all pixels are covered.
In the demo you can set the random seed, the amount of horizontal + vertical shuffle rounds and the size of the lookup table which controls the amount of each column's and row's offset. The smaller the table size is the less random the shuffling will look, nevertheless this might be still interesting for certain graphical effects. The long slider controls the index, meaning "give me the next 500 random coordinates starting from index 10012". When you select "accumulate" it means "give me all random coordinates from index 0 up to index 53100".
In the end this might look like just a different kind of pixelDiffusion filter but believe me - it has many more interesting uses. For example the AutoPainter and the Stippling hubs inside of Peacock are using it, too.
]]>calculationMap.applyFilter( gameMap, rect, origin, neighbourBlur ); calculationMap.draw( gameMap, null, colorAdd, "add"); gameMap.paletteMap( calculationMap, rect, origin, zero, zero, rules );
Of course a few objects have to get initialized once, but then it's really just these 3 lines that do all the work. Here you go - click the canvas and press any key to reinitialize the canvas with random values:
]]>The bad news is that this nifty method will stop working as soon as your users upgrade to Flash Player version 10. In the new version copying to the clipboard is only allowed upon direct user interaction, meaning a mouse click on the SWF itself. A simple javascript call from the outside will not cut it. The only workaround I can think of is to create a small visible Flash button that you can place on the page.
If I wasn't on my way to Flash on the Beach this moment I'd love to provide you with a quick solution right here, but I'm pretty sure someone in the Flash community will volunteer to build a lightweight, stylable button that can be fed with dynamic data pretty soon.
Monday:
9:00 - Even though I'm a notorious keynote skipper this time I will check out Richard Galvan's Flash Now and in the Future sounds like a good way to get an overview over the latest developments.
10:15 - Stefan Richter with Building Collaborative Applications might have some ideas we could use for Aviary.
11:30 - Oh no - first conflict! I have make a decision between Branden Hall and Dr. Woohoo. I'm pretty sure Branden will have some great inspirations for coding or algorithms but on the other hand Drew's latest project which allows you to remote control all Adobe apps with Flash is so cool that I really want to see that, too.
13:30 - No question on the next one: years ago Andries Odendaal was one of my biggest inspirators and he hasn't appeared on any recent Flash conferences that I attended, so I will definitely go to his Exploitable acts of playfulness
14:45 - I guess I will check out Chris Orwig's The Art and Craft of Photographic Impact, maybe I can turn one or two ideas into new Peacock plugins.
16:00 - Natzke. Must I say more?
20:00 - James Patterson and a pint - is there a better way to finish the day?
Tuesday:
9:00 - Second day 9 am? That's usually a tough spot. But, hey - it's Aral who's talking. So I better don't have too much coffee before, otherwise I might get an overdose of energy during his presentation.
10:15 - Of course I'll be with Jeremy "Sweet Caroline" Thorp, soulmate, crooner, artist to see his fantastic Emergence talk a second time.
11:30 - Another conflict. Grant or Joa? Difficult decision. But as far as I remember I missed Grant last time, so I think I'll attend his Things Every ActionScript Developer Should Know.
13:30 - GMUNKICKDOWN 08.9
14:45 - A no-brainer: Hoss with Abstract Narrative
20:00 - Hanging out with Robert, having The Best 8 to 12 Hours of my Life
Wednesday
9:00 - that's what you get for being nice, Keith, the 9 am zombie slot. But I will stand by you to see some Advanced ActionScript Animation
10:15 - Sorry, Seb, but I'm always falling for the arts and Geoff Lillemon is a one-of-a-kind persona, so Stop and Smell the Internet is what I will do.
11:30 - Making noise with André.
13:30 - I'll probably skip this slot to get ready for my own talk, but maybe I'll have a glimpse of Rob's
14:45 - if I wasn't at my own Here be Pixels I definitely would check out Andreas Müller's Tools and techniques at Nanika - this guy is so damn talented it hurts.
16:00 - Oh, no - over already? Jonathan Harris with The Art of Surveillance and Self-Exposure sounds like a great closer.
]]>
Plastic Block Fishy from mpeutz on Vimeo.
So if you have got 3 minutes to spare it would be great if you first registered a voting account here (a step which you might not need since you have already voted for Aral): http://panelpicker.sxsw.com/users/register
(this account is only to make sure that people don't cheat when voting - you will not subscribe to any newsletter or advertising crap) and then giving your stars to the Aviary proposals here: http://panelpicker.sxsw.com/ideas/index/3/q:aviary
Oh my - I just realized that I'm one day late. Voting has closed already... So don't bother.
Fortunately voting has been extended until Sep 1st - thanks for letting me know Rick!
Thanks a lot!
So what can be done about it? Fortunately as a self-responsible grown-up you can override the default behaviour in the Firefox presets. These presets are opened by entering "about:config" in the location field. If you do this the first time you will see a warning page in which you confirm that any change will be your own fault, just like in real life.
After confirming this you will see a long list of potentially dangerous settings. Don't touch any except for the one called dom.disable_window_open_feature.location (this list is sorted alphabetically). The default value is "true", but we want to change it to "false" which is accomplished by simply double clicking the row. The line will turn bold in order to show you that this is not the safe default value anymore.
That's all. But don't come back crying to me if some nasty phisher cleared your bank account afterwards.
]]>As Ron mentions the AS3 code runs way slower than the native perlinNoise() method that Flash's BitmapData class offers, but on the other hand his class is true to the original version and offers real 3D Perlin Noise and the possibility to control the falloff factor. So the reason for my belated post now is that I couldn't help noticing several opportunities to optimize the code. As usual optimizing will definitely not make code look better or easier to understand but for stuff like PerlinNoise which you usually called several hundred or thousand times every little counts to make it perform faster.
I attacked the class at the usual optimization points:
- Unroll functions wherever possible - this is usually the biggest timesaver. almost every function call in an inner loop is poison for execution time. The reason for that is that internally every call causes tons of save-data-on-stack and get-data-from-stack operations which do not happen if you copy the code that the function processes right into your loop.
- Do type casting whenever dealing with arrays in Flash. Especially for the indices - so instead of v = p[i+5] say v = Number( p[int(i+5)] ). That doesn't look as nice but it helps
You can see the result of this optimization here On the left is the original class, on the right the optimized one which turns out to be twice as fast. I had hoped for more but that's all I could do.
You can download OptimizedPerlin.as here or right-click the example and choose "View source".
Anyways in order to save all those helpful people out there any more unnecessary work here is the barebones com.quasimondo.geom.ColorMatrix Version 2.1 for you to download - it's released under MIT License.
Compared to the AS2 version I have added several new methods and of course tried to use optimizations wherever possible. Two new methods that are especially interesting are:
rotateHue() which tries to preserve the luminance whilst changing the hue (which means this is the "correct" but calculation wise more complicated way of doing it).
applyColorDeficiency() which I ported back from the Javascript version that the guys at NoFunc created from my Actionscript version and which allows to preview images the way colorblind people would see it.
]]>
function snapClip( clip:DisplayObject ):BitmapData
{
var bounds:Rectangle = clip.getBounds( clip );
var bitmap:BitmapData = new BitmapData( int( bounds.width + 0.5 ), int( bounds.height + 0.5 ), true, 0 );
bitmap.draw( clip, new Matrix(1,0,0,1,-bounds.x,-bounds.y) );
return bitmap;
}
So if you have a spirite named "testclip" on your stage, this will take a (non-scaled, non-rotated) bitmap snapshot of it:
var bitmap:BitmapData = snapClip( testclip );
]]>Koen De Weggheleire has once more managed to gather a hot lineup of more than 30 top-notch presenters - among them Aral Balkan, Peter Elst, Dave Schroeder, Ralph Hauwert, Rob Chiu and Hoss Gifford, just to name a few. I, too, have the big pleasure to speak there for the second year in a row and I'm really looking forward to it, especially after Koen told me that my session is already full (attendees can prereserve seats online) - but don't worry there's always the chance that someone gets hit by a bus an overdose of belgium beer and decides to pass on his seat.
You can register for your free ticket here. See you in Kortrijk.
Node based editing means that instead of writing code you assemble a set of building blocks each with a specialized functionality on a canvas and "draw" the control flow or the dependencies by connecting those blocks with connector "cables". This allows you to create dynamic or interactive pieces in Flash without even having to know Actionscript.
The really great thing about Source Binder though is that it is infinitely extensible. The toolbox of available elements is not limited by what the developers put in but everyone can add new functionalities to it themselves. But it gets even better - instead of having to conform to a certain SDK and program classes especially for this tool Source Binder can simply attach to any Actionscript library out there - all one has to do is to use a wizard in which you declare some simple wrapper classes which tell Source Binder about the available methods and properties.
Currently there are already two popular libraries included: Papervision and the Wow physics engine. In his talk Balázs Serényi demonstrated how to build a 3d physics simulation with just a few mouse clicks. The clou was that the simulation was controlled with a WiiMote since SourceBinder also can make use of WiiFlash. And talking about physical computing: the wonderful Arduino Board is also available as a module already.
Still - if you are inclined to it you even are able to write Actionscript right within the tool (if you want to add extra functions to existing modules for example) and it will be compiled on-the-fly.
And the amazement doesn't stop here - of course you want to know what kind of output Source Binder produces. Well, there are two options: you can have a swf that you can just use straightforward or you can get real Actionscript. And I think here we are really onto something. Source Binder could be the missing bridge that Adobe burned down when AS3 was introduced and which left everybody who was (just) a happy AS1/AS2 on-the-side-coder and who was not able to pick up hardcode coding as easily back in slowland. Source Binder will allow people who are not programmers but still want to create fast AS3 based dynamic Flash to do exactly that. Sorry for sounding like a broken record, but I really see a new world opening up here
Source Binder is currently in a closed alpha but you can register on the site to apply for an account. Did I already mention that it will be free and AFAIK open source?
There have been some impressive examples in recent time of PONG made in 510 bytes or even in 349 bytes - so 5k is not really world record anymore. On the other hand - this file is from the good old Flash 5 days where there was no gzip compression available (with compression it already goes down to (1742 bytes). But this version is a two player game with keyboard control, it has sound, scoring and several different play modes. I guess that there is still some room for improvement, maybe one can get it down to 1k or so without loosing any features - feel free to give it a try. Here's the original Flash 5 FLA file.
]]>