Krink
Over the weekend and on monday I created an bunch of visual and non-visual C experiments. Here is one of the programs that came out particularly nicely. I’ve only bothered compiling it on OSX but it would be easy to port over to windows since it uses glut. You have a few choices for viewing:
Look at stills on flickr:
Watch the short video:
Download the Application:
Download the Xcode Project:
I don’t want to post all the code here since there are a few files and it would be kind of confusing – if you’d like to see all the code, download the Xcode project. I will highlight a few parts though:
Some code snippets:
Circle.h
1 2 3 4 5 6 7 8 9 10 11 12 13 | typedef struct Circle{ float x; float y; float vx; float vy; float dist; Color *col; int id; void (*update)(struct Circle *c); } Circle; Circle makeCircle(); static void update(Circle *c); |
The interesting thing here is the function pointer member of the struct. Later on in Circle.c we point all new Circle structs update member to Circle.c’s static update function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include "main.h" #include "Circle.h" Circle makeCircle(){ Circle c; c.x = rand() % width; c.y = rand() % height; c.vx = rnd() * 8 - 4; c.vy = rnd() * 8 - 4; c.dist = 10 + rnd() * 100; c.col = makeColor(); c.update = update; c.id = 0; return c; } static void update(Circle *c){ c->x += c->vx; c->y += c->vy; if (c->x > width) c->vx *= -1, c->x = width; if (c->y > height) c->vy *= -1, c->y = height; if (c->x < 0) c->vx *= -1, c->x = 0; if (c->y < 0) c->vy *= -1, c->y = 0; glVertex2f(c->x , c->y); } |
Here’s a snippet from main.h:
1 2 3 4 5 6 7 8 | typedef struct { float r; float g; float b; float a; } Color; extern Color *makeColor(); |
and then later in main.c we define makeColor():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | Color *makeColor(){ static Color colors[COLOR_NUM] = {{0.765, 0.902, 0.875, 0.2}, {0.039, 0.059, 0.075, 0.2}, {0.247, 0.251, 0.259, 0.2}, {0.345, 0.514, 0.549, 0.2}, {0.929, 0.878, 0.671, 0.2}, {0.851, 0.965, 1.000, 0.2}, {0.498, 0.247, 0.149, 0.2}, {0.090, 0.098, 0.078, 0.2}, {0.545, 0.584, 0.486, 0.2}, {0.157, 0.180, 0.133, 0.2}}; return &colors[rand() % COLOR_NUM]; } |
For some reason I decided to encapsulate all the colors into a function that would then spit out a pointer to a random value in the static colors array – so there are only every COLOR_NUM color struct instances no matter how many particles (Circle struct instances) there are. Lots of other ways to do this same thing I guess… I got the colors from my drawings, I speed coded a little AS3 to grab a few random values from a given MovieClip and write the struct initializations. The actionscript is funny because I coded it javascript style for some reason:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | var panel = addChild(new Sprite()); var bit = new BitmapData(sample.width, sample.height, false, 0); bit.draw(sample); var cols; stage.addEventListener(MouseEvent.CLICK, function(){ cols = "{"; for (var i = 0; i<10; i++){ var c = bit.getPixel(int(Math.random() * sample.width), int(Math.random() * sample.height)); cols += toArray(c); panel.graphics.beginFill(c); panel.graphics.drawRect(0, i * 20, 20, 20); } cols = cols.substr(0,cols.length-2) + "};"; trace(cols); }); var alph = 0.2; function toArray(c){ var r = (c >> 16) & 0xFF; r /= 0xFF; var g = (c >> 8) & 0xFF; g /= 0xFF; var b = c & 0xFF; b /= 0xFF; return "{"+r.toFixed(3)+", "+g.toFixed(3)+", "+b.toFixed(3)+", " + alph + "},\n"; } |