Archive for the ‘experiment’ Category

In Your Own Words

Saturday, February 13th, 2010

All along I was planning to do something with the circular wander that involved, surprise surprise, text. After seeing Neuroproductions beautiful Alice in Wonderland I snapped into action.

So, click the image below… You can punch in your (or another) Twitter handle, specify the number of “wanders”, click GO and watch the twitter profile pic being drawn by the tweets of the profile pics proud owner. The default is 10 wanders, but 40 or 50 run smooth if you’re impatient :D



So how did I get there? Like this. The following images are a random selection of people I follow on Twitter, rendered as I was progressing with the code.

I started off with just squares, which looked kind of nifty:


Here is @inspirit


@makc3d


My homie @theflashbum

I then moved on to text. I started off using regular TextField :

The mighty @wefail

While fun to watch, the text was practically unreadable, so I increased the font size and added a GlowFilter to create a fake stroke:

Here’s a full size detail, the text was too big (tough to recognize the image), but damn, the black text with white stroke all piled up like that looks hott!

I had some difficulty with the spacing of the text, so I moved on to the TextEngine instead of TextFields… immediately I ran into some bugs…


My old friend @sjespers

Totally unreadable, but kewl :D

I then got the text engine code working:


The ever inspiring @quasimondo

The problem with having a white or black stroke, is that in dark (or light) areas, the text is once again totally unreadable.

So I figured I would alternate the stroke color. If red<128 && green<128 && blue<128, I set the stroke to white, otherwise it's black:


Rock on @derschmale

The last adjustment was to set the alpha of the glowfilter to .3 . I was happy enough with that result to call it a day and blog :)


The guy I keep somehow not catching at conferences @flashaddict

Update:

I added a “save image” feature to the demo. I used the inbuilt JPGEncoder, so it’s slow, I know there are faster alternatives, but no time ;)


Click here for the demo:

Update2:

I thought it would be fun to have a gradient in the characters instead of a solid color. Instead of grabbing the pixel which corresponds to the center of the new character, I grab one from the “top center” and “bottom center” of the new character. The result isn’t necessarily more “recognizeable”, but looks nice. I also added a couple more controls : font size, background color and font. That’s right, you can now render your image with Comic Sans! Rejoice!


A designer from work with a colorful profile pic @farfields

Northern Lights Circular Wander Demo

Tuesday, January 5th, 2010

This was a fun quickie. I’ve always wanted to try creating Northern Lights with Actionscript, and here was a good excuse. I’ve seen the real deal in Finland, and though my demo doesn’t act (or look) exactly like aurora borealis, it does use the Circular Wander Class I blogged about last week ;) The code is pretty straight forward, the “trick” being that I take the y value of the “leader” (an instance of CircularWander), and cast that to the Z value of all the following particles. A little Blur, and voila. Then for lack of inspiration, I made it into a sound visualizer.

I used this random Image from Flickr as my source of inspiration:

Here’s a screenshot of the demo.


Click image to see demo WARNING: 3megs… there’s an embedded sound file…

Here be the source files (without the .mp3, that would be file sharing?!)

I just added the code to the CircularWander.zip from the previous blog entry…

Hope you like it!

Circular Wander

Thursday, December 31st, 2009


click here for the source code It’s relatively clean, even contains some comments.

I get about 20 fps with 3000 small particles (radius1). This can vary depending on other settings like max/min degree of rotation…

So how did this come about? Funny you should ask…

While working at Sony Back in 2003, I made an “all around preloader”, which was to be used for flash showcases, apps, tutorials etc. At the moment Sony was using these “blobs” in their branding:

you make it a sony

Armed with Flash6, I used the drawing API to make it into a dynamic animation:


sony loader
Click image to see it in its never ending glory ;)

That’s the only working version I could find. There is an FLA, but I dare not open it.

Unfortunately, the loader never saw the light of day, as Sony rebranded within weeks of me finishing the code :D

The most interesting aspect of the loader was the random movement of the blobs. It’s not what I wanted. I wanted the circular wander motion. Time just ran out back then. Every now and then I’ve pondered going back to the problem. I was inspired to finally get off my ass by Grant Skinners recent post about his Wander Class. So it took me 7 years…

The basic premise is simple:

circular wander explanation 1

Any particle travelling along the perimeter of a circle, can “smoothly” switch circles, as long as the next ones center is along a line perpendicular to the particles current moving direction.

The problem is, how do you restrict this movement to stay within a given rectangle?

The solution is easy to see when visualizing it:

circular wander explanation 2

There are a few “maximum circle sizes” along the blue “axis line” which fit the wandering bounds. Once the radii of those circles are discovered, it’s just a matter of randomly selecting a point along the line, between the “maximums”.

But how to find those magical maximum radii?

There are probably several ways. After blankly staring at a few sketches, I was suddenly reminded of my Highschool Math teacher Mr. Rosko. He would say the term “Isosceles Triangle” in a tone of voice, that sounded like it was something that could get you laid.

Needless to say I never tried that one on the ladies, but for this baby, it did just the trick.

Not only do isosceles triangles have two equal angles, they also have two sides that are the same length.

Now, let’s look at another mindblowing illustration:

circular wander explanation 3

In other words, due to the nature of a circle, an isosceles triangle appears between the current position of the particle, the maximum radius center, and the edge of a boundary. So at this point, here’s what we know about that triangle:

  • All the angles in the triangle. These can be deciphered with simple arithmetic.
  • The point currently occupied by the particle.
  • The equation of the line between the particle, and the new center.
  • The X (or y) of the point which intersects with the bounds.

In a nutshell, we pwn that sob.

There was some trials and tribulations with maintaining the correct direction when switching circles, and choosing the best circle for the job… more about that if you look at the code :)

enjoy!

an approach to triangulating polygons with holes

Friday, June 12th, 2009

I know this has been done before, probably much more efficiently, but I had an idea wednesday and had to pursue it to its conclusion :)

The other day Katopz pointed me to this snippet which triangulates polygons. I’ve also seen an approach to ear cutting by nicoptere.

I figured that by converting an “O” into a “C” leaves me with two polygons which are easy to triangulate. Allow me to elaborate:

So the idea is just to cut out a rectangle (two triangles), which connects the polygon and the hole. Triangulate the “cut shape” and then concat the extra two triangles to it. But which rectangle to choose?

I wrote a class called PolygonWithHoles.as . This contains a polygon (Vector.<Point>), and holes (Vector.<Vector.<Point>>). The idea is too loop through the “holes” one at a time (cue beavis and butthead). The safest bet is to find the shortest “connection” between a point on the main polygon and the hole (done by looping and using Point.dist()).

This too has one stipulation. In order to have a rectangle, the code has to find the “shortest connection” either before or after our initially picked “shortest connection”.

Once the “cut out rectangle” has been discovered, the perimeter of the main polygon and the hole are merged through a few loops. If there are more holes, the now modified main shape is chopped again and again, eventually resulting in a “hole free” polygon. This can then be triangulated, and the “removed rectangles” are appended as sets of triangles.


Click image for demo


This approach seems to work well over 90% of the time. A few characters in some fonts do throw an error… not sure why. The triangulation is pretty fast, you can see this in the tracebox in the demo. The vectorization of the text is the slow bit.

The next step, of course, is to extrude the characters using textures :) Maybe even add shading some day…

The code is more or less legible this time, eventually I hope to clean this up into some sort of an API… Once again, the download is a zip of my always expanding “FindBitmapPixelOutline” project… download it’s latest incarnation here. The project you want to look at is “TriangulationTest.mxml”. Warning, it’s 6 megs with tons of crap you probably don’t want :D

.

Dynamic text with phong shading using Stok3d

Tuesday, June 9th, 2009

Yesterday David DerSchmale Lenaerts released Stok3d into the wild. When he showed me the demos, I immediately felt (you guessed it) STOKED!

Naturally my first question was : "does it support transparency?!", and with a resounding yes, I just had to try this with text :D

I wanted to generate the texture maps dynamically. It's not quite there yet, but not bad for a quick experiment :)

This took three steps:

  1. Create the diffuse map by generating a text field, taking a bitmap data snapshot of it and adding some bevel to it.
  2. Create the normal map by repeating the previous step, only using Red and Blue colors, with slightly different bevel settings.
  3. Create the specular map by extracting "outlines" using convolution filter.

These three bitmaps look like this:

Here's the code for generating them:

Actionscript:
  1. var font_size:uint=140;
  2. var tf:TextFormat=new TextFormat("Arial",font_size,0xac8ea9,true);
  3. var diffuse:BitmapData=createTextLineBitmapDataFromTextFormat("STOK3D",tf);
  4. diffuse.applyFilter(diffuse,new Rectangle(0,0,diffuse.width,diffuse.height),new Point(),new BevelFilter(5,45,0xFFFFFF,1,0x00,1,10,10,3,3));
  5. _diffuse_map=new Bitmap(diffuse);
  6.  
  7. tf=new TextFormat("Arial",font_size,0xbf6cde,true);
  8. var normal:BitmapData=createTextLineBitmapDataFromTextFormat("STOK3D",tf);
  9. normal.applyFilter(normal,new Rectangle(0,0,normal.width,normal.height),new Point(),new BevelFilter(5,45,0x89a1f9,1,0xFF00FF,1,12,12,3,3));
  10. _normal_map=new Bitmap(normal);
  11.  
  12. tf=new TextFormat("Arial",font_size,0xFFFFFF,true);
  13. var specular:BitmapData=createTextLineBitmapDataFromTextFormat("STOK3D",tf);
  14. specular.applyFilter(specular,new Rectangle(0,0,normal.width,normal.height),new Point(),new BevelFilter(5,45,0x999999,1,0x00,1,0,0));
  15. specular.applyFilter(specular,new Rectangle(0,0,normal.width,normal.height),new Point(),
  16.                                             new ConvolutionFilter(3,3,new Array(0,20,0,20,-80,20,0,20,0),10));
  17. specular.applyFilter(specular,new Rectangle(0,0,normal.width,normal.height),new Point(),new BlurFilter(2,2,2));
  18. _specular_map=new Bitmap(specular);

Then I just grabbed Davids demo code and replaced his textures with mine... and voila:

click image for demo:


storm image from http://www.flickr.com/photos/digitaltool/2569963337/

For some reason the demo doesn't start everytime. Just refresh a few times and you should be STOKED! ;) Also, the specular lights go black sometimes. I'm convinced this is just due to my happy go lucky texture generation, but David claims he needs to look at his code.

check the demo

download the demo as project. This is just my demo file, you'll need to fetch the Stok3d code from google (see link above);

I have to say, Stok3d is pretty damn cool! Sweet work herr schmale :thumbsup: :pirate:

.