Category: digital


Digital Sketch

1. July 2010 - 09:59 Uhr
Digital Sketch

Nightly Sketch Nr. 241

After some messing around with the  SimpleParticleSystem by Daniel Schiffman, the resulting applet could be conviced to generate a kind of fur texture.  If you’re interested in the tweaked processing source code, you’ll find it here.

3 Kommentare » | digital

Nervous Spot

15. June 2010 - 19:40 Uhr

This movie requires Flash Player 9

Playing around with AS3, perhaps somebody wants to take the code and make a proper Rorschach test ;-) :

/*
Copyright (c) 2010 Ingmar Drewing

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

package {
import flash.display.*;
import flash.utils.*;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.BlurFilter;
import flash.geom.*;

[SWF(backgroundColor="#FFFFFF",frameRate="60",width="460",height="460")]

public class Spot extends Sprite {
private var W:int;
private var H:int;
private var rendering:Boolean = false;
private var dots:Array = new Array();
private var canvas:Bitmap = new Bitmap();
private var range:int = 80;
private var bg_colour:Number = 0xFFFFFF;
private var centerpoint:Point;
private var sync_x:Number;
private var sync_y:Number;
private var check_interval:int;

private var colour:Number = 0×000000;

public function Spot () {
init();
}

private function init():void{
H = stage.stageHeight;
W = stage.stageWidth;
centerpoint = new Point( W/2, H/2 );
sync_x = W/2;
sync_y = H/2;

for ( var dx:int = 1 ; dx < W; dx+=10 ){
for ( var dy:int = 1 ; dy < H; dy+=20 ){
var d:Point = new Point( dx, dy );
dots.push(d);
}
}

addChild( canvas );
render();
stage.addEventListener( MouseEvent.MOUSE_MOVE,
start_following_mouse );
}

private function stop_following_mouse( e:Event ):void{
removeEventListener( Event.ENTER_FRAME, mouse_sync );
sync_x = W/2;
sync_y = H/2;
stage.addEventListener( MouseEvent.MOUSE_MOVE,
start_following_mouse );
check_interval = setInterval( check_render_necessity, 500 );
}

private function check_render_necessity():void{
var dx:Number = sync_x - centerpoint.x;
var dy:Number = sync_y - centerpoint.y;
var distance:Number = Math.sqrt( dx*dx + dy*dy );
if ( distance < 1 ){
stop_rendering();
clearInterval( check_interval );
}
}

private function start_following_mouse( e:MouseEvent=null ):void{
clearInterval( check_interval );
start_rendering();
stage.removeEventListener( MouseEvent.MOUSE_MOVE,
start_following_mouse );
stage.addEventListener( Event.MOUSE_LEAVE, stop_following_mouse );
addEventListener( Event.ENTER_FRAME, mouse_sync );
}

private function mouse_sync( e:Event ):void{
sync_x = mouseX;
sync_y = mouseY;
}

private function start_rendering():void{
if ( !rendering ){
rendering = true ;
addEventListener( Event.ENTER_FRAME , render );
}
}

private function stop_rendering():void{
if ( rendering ){
rendering = false ;
removeEventListener( Event.ENTER_FRAME , render );
}
}

private function render( e:Event=null ):void{
centerpoint.x = sync_x - ( sync_x - centerpoint.x )*5/6 ;
centerpoint.y = sync_y - ( sync_y - centerpoint.y )*5/6 ;
var bd:BitmapData = new BitmapData( W, H, false, bg_colour );
bd.lock();

for each ( var dot:Point in dots ){
var dx:Number = dot.x - centerpoint.x ;
var dy:Number = dot.y - centerpoint.y ;
var distance:Number = Math.sqrt( dx*dx + dy*dy );

if ( distance < range ){
var r:int = (1-distance/range) *1000;

var current_x:int = dot.x;
var current_y:int = dot.y;
for( var i:int = 0; i < r; i++){
bd.setPixel(current_x, current_y, colour);
var randX:Number = Math.random();
if ( randX < .33 ){ current_x -=1; } else if ( randX >=.33 && randX < .66 ){
current_x +=1;
}
var randY:Number = Math.random();
if ( randY < .33 ){ current_y -=1; } else if ( randY >=.33 && randY < .66 ){
current_y +=1;
}
}
}
}

bd.unlock();
canvas.bitmapData = bd;
}
}
}

1 Kommentar » | digital

Rogue Revisited

5. December 2009 - 22:44 Uhr

Back in the early 1990ies I had an Atari 520 st. I have to admit, that I used it mainly to play games like “Wings of Death” or “Fusion”.

Another game I really liked was Rogue, a single player fantasy adventure game. The dungeon was randomly generated for every new game. Though there was a finite number of magical items, potions and scrolls, one never knew which effect a certain item had until it was identified either by a spell or by using it (the latter method had it’s drawbacks, since there were also cursed items). This kind of randomness caused a very high degree of replayability.

Somewhere in early 2008 I found out that rogue is older than I assumed. It has been initially written in the early 80ies for Unix machines. The moment I read about this, I started to search for a playable version to use on my desktop computer (I am mainly using ubuntu). And I found it – it’s part of the package “bsdgames-nonfree” :)

It’s still fun to play and having learned to use vim (a very sophistacated text-editor) I noticed that the ASCII-version of Rogue used the same keys to move the hero around, which move the cursor in vim.

If you haven’t seen the game yet, have a look – it’s a part of gaming history and influenced a lot of younger games.

http://en.wikipedia.org/wiki/Rogue_(computer_game)

Kommentieren » | digital

Building a Preloader with ActionScript 3 using mxmlc and the Frame Pragma

23. September 2009 - 13:56 Uhr

Good news: you really don’t need the timeline to build a preloader. The technique is described in detail at bit-101. In short it works like this:

1. put this before the definition of your main class:

[Frame(factoryClass="myPackage.MyPreloadClass")]

The code above tells the mxmlc to take the given (custom) class under myPackage.MyPreloadClass and use it as a Preloader (there is some more background info about the Frame-pragma on the adobe-blog).

2. Write your preloader-class, extending the MovieClip-Class (since you need something with frames and sprites don’t have them). See bit-101 for an example-class.

3. That’s it. Er … well, not completely, since if you need to load some other stuff, say for example depending on a CMS-generated XML-File, the path to which is handed to your swf using flashvars, you will no longer get the the flashvars with

LoaderInfo(mainClass.root.loaderInfo).parameters

but with

LoaderInfo(preloader.root.loaderInfo).parameters

where “preloader” is a reference to the preloader-instance – that’s why I am passing a reference to the Preloader as a parameter when instantiating my main class.

5. Now your preloader would still think everything is ready, once the swf is completely loaded. That’s not the case, since you still lack the stuff defined by your on-the-fly-cms-generated XML.

My solution is to pass my main class a callback-function as another parameter, which tells the preloader when the loading is really done.

In principle the passing of a preloader-reference to the main class would suffice, but then the function triggering the end of the loader-animation would have to be defined public …

Kommentieren » | digital

Manipulating Bitmap Images with ActionScript 3

8. September 2009 - 19:40 Uhr

I’ve been recently working on a project which involved the manipulation of bitmap data at runtime. The swf would be communicating with a content management system, which only provided coloured images. But since the images needed to be displayed in greyscale as well as in colour, the swf had to do the trick.

In ActionScript you need to use the ColorMatrixFilter to manipulate these properties. A procedure which can be mind boggling and definitely is error-prone.

After a little searching I found the extremely handy class ColorMatrix.as written by ActionScript grandmaster Grant Skinner. You’ll find some examples on his blog and the class itself hosted on google code.

The usage is fairly simple, though you need to take care of the order of the function calls:

import com.gskinner.geom.ColorMatrix;
import flash.filters.ColorMatrixFilter;
import flash.display.Sprite;

/* ... some other code in between ...*/

var c:ColorMatrix = new ColorMatrix();
c.adjustBrightness(100);
c.adjustSaturation(-100);
c.adjustContrast(-50);

var cmf:ColorMatrixFilter = new ColorMatrixFilter();
cmf.matrix = cm;

// The following bitmapData is the BitmapData-Object
/  derived from an imagefile,
// which is loaded at runtime:

var bmp:Bitmap =  new Bitmap(bitmapData) ;

var s:Sprite = new Sprite();
s.addChild( bmp );
s.filters=[cmf];

// that's it.

It’s a breeze and works like a charm. Just keep in mind, that these lines:

c.adjustBrightness(100);
c.adjustSaturation(-100);
c.adjustContrast(-50);

will result in a different image compared to the product of these lines:

c.adjustSaturation(-100);
c.adjustContrast(-50);
c.adjustBrightness(100);

Kommentieren » | digital

Praise To A Perl Module

25. August 2009 - 20:15 Uhr

For as long as our design agency owns a fileserver, which is approximately three years, a little program written in Perl eases our daily lives at the office. It makes heavy use of Linux::Inotify2, an immensely useful module.

We have a samba-share on our fileserver, which contains a directory for each of our clients. Whenever anyone in our office creates a new folder inside this directory its name ist automatically checked and a three letter acronym is generated from the clients name. This abbrevation will be used internally to identify files related to the client given.

Once the new folder ist created it itself is also watched by the program and whenever a project folder is created within this clients folder, a directory hierearchy is copied into the project directory which looks similar to this:

00_communication
01_projectmanagement
02_design
03_implementation
04_final

This is very helpful, since nobody has to remember to create a “corporate folder structure”, which can also be understood by his or her co-workers. This is crucial if, for example, a client requests data while one of our colleagues is on vacation (and in this business you always need to find such things instantly).

With Perl being the almighty programming language it is, the usefulness of the module doesn’t end at here. You can really trigger anything with it. One could create a folder which synchronises its contents with a remote directory on a ftp-server the moment sombody drops data into it.  Or you can have the system email you about an activity regarding certain files, regarding security issues and the like.

The possibilities are endless.

2 Kommentare » | digital

Random Colour Combinations

15. August 2009 - 11:45 Uhr

The briefings and strategic information supplied at the start of a design project define the aim for the “look and feel” to be developed. Thus it’s initially defined what the viewer should sense while being exposed to the product, but not how these sensations will be generated. It’s defined how the appearance shall be “aesthetically read”, but not how it is “written”.

I found the best way for me to start developing a fitting design is by finding combinations of colours generating a target mood. Not being a pure synaesthetic by nature I am using language as a means to describe the recepted-aesthetic-to-be in terms like dry, cold, traditional, technical, etc. Next, I am “going back” in the perceptional process, looking for colours and colour combinations which trigger these sensations.
A similar approach can be used to find shapes, but I found the the emotional impact of colour being much stronger and thus working better for this purpose.

Still, colour itself has its limitations, since the number of colours is finite, whereas the number of shapes is infinite. Hence the search for combinations of colours, whose number is finite as well – but larger by far. It’s a bit like using colours as letters or words while “writing” the design.

Some years ago I wrote a little Perl program to support this development process. It’s a tool to generate random combinations of colours, written to keep from getting stuck in the same combinations over and over again. It’s primitive on a technical level, but still useful:
colourcombiner.pl

Feel free to download, use and modify the source code:
colourcombiner

P.S.: There is a brillant book from Josef Albers: “Interaction of Colour”.

Kommentieren » | design, digital

From ActionScript to Processing: In Quest for the Push-Method

1. August 2009 - 12:32 Uhr

Dabbling into processing (coming from ActionScript 3) one of the first things I was looking for was an equivalent of Array.push() and its relatives to store and manage a growing amount of objects during runtime. Astonished I realized that there is no such thing.

After some searching the java Vector-class presented itsalf as a possible surrogat for an AS-like array. Processing being a kind of a “wrapper” for java you can use java classes inside it, like this:

import java.util.Vector;
Vector a = new Vector();
void setup () {}

void draw (){
   a.add(new Dot( random(200), random(200)));
}

class Dot {
  float x,y;
  public Dot ( float x_param, float y_param ){
    x = x_param;
    y = y_param;
  }
}

The vector is not exactly the same as an array in AS (or Perl), but it’s close – see this for details.

Kommentieren » | digital

Dryer Drawings – Increasing Productivity using Smartphones

20. July 2009 - 20:12 Uhr

You might think of smartphones as the yuppie-toys they are. Yet, whenever a technological invention is set free to roam within our daily lives, unintended uses (and unexpected usefulness) almost immediately emerge.

A historical example for this phenomenon is the creation of template files, i. e. the use of computer documents which serve as prototypes for a whole class of documents. Concerning office applications there are templates for invoices, confirmations, etc. pp.. This feature was not invented by a software company, but by the users – or rather by paying attention how people used the software.

Software development and – in my oppinion more important – distribution changed a lot since these early days. The growing availability of computer equipment (plus connectivity and power), enables ever more people to participate in the creation and publishing of software and data. It radically changed the rules of production and use for nearly any digitalisable good one can think of.

Combined with mobile devices (smartphones) it does something more: a few days ago I was sitting in a launderette, waiting for the machine to finish drying my clothes. This takes usually somewhat between twenty and forty minutes – a timespan formerly too short to accomplish anything useful.

Of course, I could carry a book with me and read a bit, but I could hardly do something productive. Now with my smartphone I can make use of the time. Obviously checking and answering mails is a task the device has been designed for. But thanks to independent developers I can also use it to sketch, using a simple drawing program. Thus the smartphone increases my efficiency. It helps using the most precious resource in existence more efficiently: lifetime.

The resulting “dryer drawing” is a simple, rather crude, sketch, but it serves as a means to record an idea:

It’s these tiny increases in productivity and otherwise lost creative outputs, which might cause further growth of productivity, worldwide. Imagine this little gain multiplied with several billions – imagine the population of the now underdeveloped regions getting a hold on these means.

Okay, maybe I did get a bit swept away with the hype. Still, the potential is there. What do you think?

Kommentieren » | digital, drawing

How to write a (very, very, very) simple dimetric 3D-display using ActionScript 3

12. July 2009 - 16:00 Uhr

When expressing oneself in 3D there are lots and lots of frameworks and APIs, each of which having one or more drawbacks in terms of performance and/or portability (or availability, depending on the programming language/environment).

Regarding the web papervision was (and is) very helpfull. Still, one has to carry around a lot of code, which in some cases isn’t really needed. Plus the needs towards “real” 3D are not always there. Sometimes a simple dimetric display would do the job – but this needs to be “faked” within papervision, since it lacks an axonometric mode. Thus, on several occasions I ended up using a vast distance between the camera and the shown objects in combination with an equally big zoom to reduce perspective distortion.

Some projects really don’t need any advanced technique. No displacement- or bumpmapping, no texturing, no lighting, no translucency, etc. Just displaying coloured geometric primitives would suffice.

These simple geometric structures are made of planes, which in turn are made of lines, which are defined by points (speaking of a polygonal model). And there we are at the bottom, ready to go up again: The core class has to be a class describing a point within the three dimensional space.

package simple3D {
    class SpacePoint{
        public var x:Number;
        public var y:Number;
        public var z:Number;

         public function SpacePoint (param_x:Number,
                                     param_y:Number,
                                     param_z:Number) {
             x = param_x;
             y = param_y;
             z = param_z;
        }
    }
}

This is pretty plain. We need three properties to define the position of the point within a 3D-space. The type of the variables must be Number, because we might want to tween the point using a nifty tweening class like the Caurina Tweener, for example.

A class defining a point in three dimensional space is all very well, but it would still be pointless if we can’t project the point to a two dimensional display like a screen. So let’s add a method for projection to our SpacePoint-class:

        public function project ():Point {

            var x2D:Number = ORIGIN_X + x * X_INFLUENCE_BY_X
                                      + z * X_INFLUENCE_BY_Z ;

            var y2D:Number = ORIGIN_Y - y
                                      - x * Y_INFLUENCE_BY_X
                                      + z * Y_INFLUENCE_BY_Z ;

            return new Point(x2D,y2D);
        }

Let’s have a closer look at this method. We need two numbers to define the projection of the 3D-point: x2D and y2D, which we will use to instantiate and return a 2D-Point, using the built-in class flash.geom.Point.

ORIGIN_X

and

ORIGIN_Y

are defining the position of the 3D-origin within the 2D-projection.

x

is simply the x-property of the SpacePoint which needs to be scaled with a factor

0 < X_INFLUENCE_BY_X < 1

because we do not want the x-axis of the 3D-space to be identical with the x-axis of the 2D-space.

z

is the z-property of the SpacePoint. It has no direct correspondent within the 2D-space, but it influences both x and y of the 2D-point.

The words written in uppercase are constants. They are identical for the projection of all our points, because we want all the points to reside in the same three dimensional space. The constants may be (and indeed are) declared static.
One of the advantages of this rather primitive looking approach is, that we can easily turn our dimetric projection into an isometric or any other axonometric projection by simply changing these constants before we compile the code.

Now that our SpacePoint class is ready to use let’s write some code for it.

var square_xy:Array = new Array();

// creating and storing the 3D-points for a xy-square
square_xy.push( new SpacePoint( 0,   0,   0 ) );
square_xy.push( new SpacePoint( 0,   200, 0 ) );
square_xy.push( new SpacePoint( 200, 200, 0 ) );
square_xy.push( new SpacePoint( 200, 0,   0 ) );

The code above simply instantiates an array and fills it with four SpacePoints. Since we now have a bunch of points neatly wrapped up inside an array, let’s write a function which takes the points and connects them:

    // we might want to be able to define the colour of the lines
    // to be drawn. Let's add a colour-parameter:

       private function connect_points( points:Array,
                                         colour:Number ):void{

            var last_point:Point = points[ points.length - 1 ].project();
            var start_x:Number = last_point.x;
            var start_y:Number = last_point.y;

            // moving the drawing positioning to the last point.
            // this is simply for the sake of convenience - this way
            // we can simply loop through our array and call the
            // lineTo-method, without need for a an if-clause:

            graphics.moveTo( start_x, start_y );
            graphics.lineStyle( 1, colour );

          // actually connecting the dots:

         for each ( var p3D:SpacePoint in points ) {
             var point_2D:Point =  p3D.project();
             graphics.lineTo( point_2D.x, point_2D.y );
         }
    }

Since the Main class must extend the Sprite class (or MovieClip class) in Action Script 3 we can use the drawing-API of the Main class directly to connect our points.

Add a the functioncall to our Main class like this:

connect_points( square_xy, 0xFF0000 );

… and compiling the code, the result looks like this:

The resulting dimetric projection of our first square

The resulting dimetric projection of our first square

Lets have some more squares to get a better idea of our chosen projection method:

            // Omne trinum perfectum:
            var square_xy:Array = new Array();
            var square_xz:Array = new Array();
            var square_yz:Array = new Array();

            // creating and storing the 3D-points for a xy-square
            square_xy.push( new SpacePoint( 0,   0,   0 ) );
            square_xy.push( new SpacePoint( 0,   200, 0 ) );
            square_xy.push( new SpacePoint( 200, 200, 0 ) );
            square_xy.push( new SpacePoint( 200, 0,   0 ) );

            // creating and storing the 3D-points for a xz-square
            square_xz.push( new SpacePoint( 0,    0,   0 ) );
            square_xz.push( new SpacePoint( 0,    0, 200 ) );
            square_xz.push( new SpacePoint( 200, 0, 200 ) );
            square_xz.push( new SpacePoint( 200, 0,   0 ) );

            // creating and storing the 3D-points for a yz-square
            square_yz.push( new SpacePoint( 0,   0,   0 ) );
            square_yz.push( new SpacePoint( 0,   0, 200 ) );
            square_yz.push( new SpacePoint( 0, 200, 200 ) );
            square_yz.push( new SpacePoint( 0, 200,   0 ) );

            // actually drawing the square-outlines in different colours
            connect_points( square_xy, 0xFF0000 );
            connect_points( square_xz, 0x00FF00 );
            connect_points( square_yz, 0x0000FF );

And here is the rendering on the screen:

three_projected_squares

Three squares in our three dimensional space, projected to the screen

That’s it – we have a means to create a projection. Still, the code (zip including a compiled swf) creates only one image and doesn’t update it.

To achive a kind of animated projection we would need to implement some further functionality – e.g. a function to clear and redraw the display, which could be implemented as a “Listener” (AS-Jargon for objects following the Observer-Pattern)  of an ENTER_FRAME-Event.

It would also be nice to have a method measuring the distance from a point to the image plane, plus a function to sort the 3D-Objects depending on their distance to it (thus implementing a realistic overlapping).

As mentioned above, I strongly recommend the Caurina Tweener for programmatical animation, which in my opinion offers all the functionality programmatical animation needs.

Kommentieren » | digital

« Ältere Einträge