Recently I've been looking at Povray, pyprocessing, and cfdg (version 3.0) as tools for creating digital images. I have branched two separate blogs where I mainly explore jruby + processing and processing.py

Friday, 24 July 2009

Starfield with CFDG (revised)

I'm a bit confused there this new directive (similar to tile since release version of 2.2) that you can apply that sets the virtual size of your image (or so I thought), that can produced a cropped image. So I gave it a go with my revised starfield (a few spiky stars), I set the size to 600 X 600 assuming with default settings I would get a cropped image of 500 x 500, ie more stars in the middle but I got the reverse. So being quite pragmatic I set the size to to 200 x 200 and ran the rule, and I got the cropped image I was looking for!!! PS: the x and y values of the size directive are supposed to set the center of the image, but don't make any assumptions about that, I needed to set them both to 0; may'be because of my rules....
   1:startshape starfield
2:size {s 205 154 x 0 y 0} // to crop your image, does not work the way I expected it to
3:background{hue 240 b -0.9 sat 1} // dark blue background
4:rule starfield{ // 5 times create white stars
5:5*{}either{x 2} // empty directive seems OK
6:}
7:
8:// create two instances of star rotate both and flip one
9:rule both{
10:star{rotate 30}
11:star{rotate -30 flip 90}
12:}
13:
14:// multiple either, create a star
15:rule either{
16:star{}
17:}
18:
19:// or create a star and flip it
20:rule either{
21:star{flip 90}
22:}
23:
24:// base star is a translated circle
25:rule star {
26:CIRCLE{b 1} // set star brightness at terminal seems to be safer
27:translate{size 0.91 y 59.2}
28:}
29:
30:// spiky star is a translated circle base star with spikes
31:rule star 0.3 {
32:CIRCLE{b 1} // set star brightness at terminal seems to be safer
33:translate{size 0.99 y 59.2}
34:spike{r 45}
35:spike{s 0.7}
36:}
37:
38:// multiple translate rules adds more randomness
39:rule translate {star {rotate 126}}
40:rule translate {
41:star{rotate 127}
42:}
43:
44:rule translate {both{}}
45:rule translate {star {rotate -110 flip 90}}
46:
47:path spike {
48: 4 * {r 90} {
49: MOVETO {x 0 y 0}
50: LINETO {y 1.5}
51: }
52: STROKE {s 2 b 1 p roundcap }
53:}





Now there's a further twist to this I wanted to produce a screen saver sized version. So entered the desired height and width options via the command line, and what appeared to be happening was the program ignored the external entered size (for the purpose of cropping).
So on the basis of my experience I would say if you want a cropped image, then set the size in your rules file to less than 500. Conversely if for some peculiar reason you want to effectively shrink your image on the canvas set the dimensions in the rules file to greater than 500 (you would have to be a bit mad to do it though). Note I have now updated my jedit mode, but it still can't differentiate between size directive and size attribute (most people use 's' for attribute anyway) and I have uploaded it to JEdit.org where you can to download a copy of my mode file.
Follow the link to other downloads then modes the file you want is cfdg.xml. Once downloaded follow instructions in jEdit help to install it. Whilst I was at it also uploaded a revised processing.xml mode (all I did was to update the syntax toxi did all the hard work of setting it up, but he gave me the OK to upload the revised version at jEdit).

Wednesday, 15 July 2009

Generating Multiple Images from One Rule

There are some cfdg rule files that you might want to run a number of times so I've created a little python script to automate the process.
   1:#!/usr/bin/env python2.5
2:'''
3:Utility to call cfdg file
4:'''
5:import sys, getopt
6:from subprocess import Popen
7:from subprocess import PIPE
8:# set following variables to suit your environment
9:cfdg = "/usr/bin/cfdg"
10:temp_folder = "/home/tux/tmp/"
11:start_file = "start.cfdg" # default file
12:kid_folder = "kids/"
13:empty_count = 0
14:
15:def help_message():
16: '''handle usage'''
17: print '''run_rules.py [cfgd file]
18:Options --help --displays this help message
19: -w [width]
20: -h [height]
21: --width=[width]
22: --height=[height]'''
23: return 0
24:
25:def call_cfdg(cfdg_file, count = 0, width=500, height=500):
26: """
27: Call cfdg file cfdg file.cfdg file.png
28: """
29: out = temp_folder + kid_folder + str(count) + '.png'
30: p1 = Popen([cfdg, '-w', str(width), '-h', str(height), cfdg_file, out], stdout=PIPE)
31: p2 = Popen(['grep', ' 0 '], stdin=p1.stdout, stdout=PIPE)
32: output = p2.communicate()[0]
33: if len(output) > 3:
34: # no shapes have been produced so delete png file and try again
35: global empty_count
36: empty_count += 1
37: p3 = Popen(["rm", out], stdout=sys.stderr)
38: while empty_count < 50:
39: call_cfdg(cfdg_file, count, width, height)
40: # call cfdg again until we reach an empty_count of 50
41: p1.wait()
42:
43:def check_args(a_list, width, height):
44: cfdg_file = start_file # default cfdg file
45: if len(a_list) == 1:
46: cfdg_file = a_list[0]
47: for i in range(0, 10):
48: if width == 0:
49: call_cfdg(cfdg_file, i) # use default
50: else:
51: call_cfdg(cfdg_file, i, width, height)
52:
53:def main():
54: '''
55: Is the main function
56: '''
57: sys.setrecursionlimit(100) # safety net
58: width = 0
59: height = 0
60: try:
61: options, args = getopt.getopt(sys.argv[1:], 'w:h:', ['help', 'width=', 'height='])
62: for a in options[:]:
63: if a[0] == '--help' and a[1] == '':
64: options.remove(a)
65: help_message()
66: sys.exit(0)
67: for a in options[:]:
68: if a[0] == '-w' and a[1] != '':
69: options.remove(a)
70: width = a[1]
71: break
72: if a[0] == '--width' and a[1] != '':
73: options.remove(a)
74: width = a[1]
75: break
76: for a in options[:]:
77: if a[0] == '-h' and a[1] != '':
78: options.remove(a)
79: height = a[1]
80: break
81: if a[0] == '--height' and a[1] != '':
82: options.remove(a)
83: height = a[1]
84: break
85: check_args(args, width, height)
86: except getopt.GetoptError:
87: sys.stdout = sys.stderr
88: help_message()
89: except RuntimeError:
90: sys.stdout = sys.stderr
91: return 0
92:
93:if __name__ == "__main__":
94: sys.exit(main())


The main feature of this script is it checks for images with no shapes, and re-runs script up to 50 times (500 in total as a maximum). Perhaps a bit excessive but you should either end up with 10 images with at least one shape or no images. You can also specify width and height, however be sure to know how complicated the rules are, it can take quite a time to run some rules, also other rules have no real random features. Good examples to run are trees, where the random nature of the branches makes it worth running the scripts several times.

Saturday, 11 July 2009

Automated Mutating of Context Free Rules

There exists a tool for the automated mutation of your rules file, this can be downloaded from http://www.wickedbean.co.uk/cfdg/index.html.
It consist of a c++ file a Makefile and a python script. The python script is designed to be modified to fit your local setup, however I needed to modify the c++ and Makefile to get it to compile. My compiler is getting a bit fussy (gcc 4.3.2) prefers to be called as g++ when compiling c++, complains about anonymous structs and the comparison of signed and unsigned integers etc. But the main problem was the #includes which needed updating/amending to include:-
#include <ctime>
#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <cstring>

This may be specific to the gnu compiler but I doubt it (by the way you can just name the structs, they are not nested and it does no harm, and it does stop the compiler from complaining, usually a good thing, after all the guys that wrote the compilers are a lot brighter than the average hacker).

Initially I tried it out with the test example of a very simple rule that produces a single black square that slowly evolves to produce a group of squares on a bit of a tilt.
Here is the starting cfdg file sans randomising values (that are necessary for the mutation, but are quoted at beginning of file, so do not affect cfdg operations)

   1:startshape box
2:rule box {
3:SQUARE{ }
4:}


After several generations of intelligent (well I think so) selection this is rule you get:
   1:startshape box
2:rule box {
3:6*{x 0.997317 s 0.996725 }
4:SQUARE{r 0.999948 flip 0.997377 }
5:1*{h 0.998266 }
6:SQUARE{y 0.999894 z 0.996235 flip 0.998095 }
7:}
8:rule R1697921991440238347 {
9:}


The go.py script is set up to display the results as a gwenview slide show (I can confirm that it works equally well with feh) so after viewing the results you just need to remember the index value result you liked, then enter that value as the parent of a new generation of mutated children (a ghastly thought). From simple beginnings complexity will arise. Of course with the random nature of cfdg the saved rule may not generate exactly what you want when you run it again, so saving the image might be a good idea!!!
Seems to fall over if you start off with too complicated a set of rules.
I would recommend something fairly simple but including mix of both and either type rules, see previous post. I got radically different results on each go let alone each generation, it doesn't seem to take much to tip the balance. Sometimes all squares sometimes a mix of squares and circles. Here is one such starting rule I tried earlier:-
   1:startshape random
2:rule random {
3:either{}
4:}
5:rule either{
6:CIRCLE{s 1 x 1 b 1 hue 360 sat 1}
7:}
8:rule either{
9:SQUARE{s 1 x 1 b 1 hue 220 sat 1}
10:}
11:rule either{
12:both{}
13:}
14:rule both{
15:CIRCLE{s 1 x 1 b 1 hue 360 sat 1}
16:SQUARE{s 1 x 1 b 1 hue 220 sat 1}
17:}


Which evolved with a bit of selection pressure to give:-
   1:startshape both
2:rule random {
3:}
4:rule either {
5:SQUARE{x 0.99859 s 1.00378 r 1.00062 b 0.996975 h 219.799 sat 1.0038 flip 1.00382 }
6:TRIANGLE{y 0.998851 s 1.00263 }
7:1*{b 0.999472 skew 0.998291 0.998976 }
8:CIRCLE{s 0.997799 flip 1.00161 }
9:}
10:rule either {
11:both{r 1.00019 b 0.998818 sat 1.00008 }
12:CIRCLE{}
13:SQUARE{y 1.00053 }
14:}
15:rule both {
16:CIRCLE{x 0.998878 s 1.00458 b 1.00698 h 358.756 sat 0.998698 }
17:1*{x 0.99717 z 0.997329 r 1.00341 }
18:SQUARE{x 1.00534 s 1.00349 h 220.191 flip 1.00302 skew 1.00375 1.00032 }
19:either{s 0.998295 }
20:}

Yielding the following image (its a bit of fun really, how did the triangle creep in?).


Here is an image and another rule set that I generated, that perfectly illustrates the importance of saving the image (if you liked it) as the rules produce sufficiently random results that you will be a long time running the rules to produce the horn shape. Gives me the idea to create a script just to re-run the same rule, without 'genetic' modification.



   1:startshape random
2:rule random {
3:1*{flip 1.00015 }
4:both{z 0.998358 s 1.00082 h 359.708 sat 0.996078 flip 0.998614 }
5:either{x 1.00037 s 1.00178 h 1.00006 skew 1 1.00138 }
6:}
7:rule either {
8:CIRCLE{}
9:}
10:rule either {
11:2*{s 1.00195 }
12:translate{y 0.997974 s 1.00127 }
13:}
14:rule both {
15:either{}
16:SQUARE{s 0.9669 r 0.99898 b 0.997186 h 218.95 sat 1.00311 flip 0.998008 skew 1.00472 0.999026 }
17:1*{}
18:TRIANGLE{x 1.00006 sat 0.993161 flip 1.00098 }
19:TRIANGLE{b 1.00181 h 359.502 sat 1.00049 }
20:}
21:rule translate {
22:1*{skew 0.998559 1 }
23:either{x 0.997803 y 1.00134 z 1.0016 s 0.999745 r 45.0287 h 0.998107 sat 0.999604 flip 1.00223 skew 1.00107 0.998019 }
24:SQUARE{}
25:}
26:rule R7964349831326658285 {
27:TRIANGLE{}
28:}


It seem as though there was a bit of debate about what was and was not possible in doing genetic transformations a couple of years ago on the CFDG wiki follow the link to read the debate, PS the creator of this tool was Andrew Borrell as you will read.

Friday, 10 July 2009

Graphical Alternative

Messing with inkscape for my previous blog reminded me of a little diversion I took, trying out a graphical tool to create similar images to those from a context free rule; using an entirely graphical tool. The software is a kind of plugin for Inkscape (kind off βeta but usable). The plugin in is even more in the βeta mould but usable, and may only work on linux.
The link is here http://linux.softpedia.com/get/Multimedia/Graphics/Gdadin-42074.shtml with the very necessary video tutorials starting here http://freaknet.org/alpt/src/gdadin/lessons/lesson1.html. I would say only try it out if you can't get your head around the cfdg rules, and would like to create similar art. Its probably 10 time quicker to write and test a set of cfdg rules.

Thursday, 9 July 2009

Random Starfield Using CFDG

Here is some rule set that I copied that I can't attribute, because I lost the url, basically the original was producing black circles on a white background, and then inverting the image to produce the desired light stars, using photoshop (WHY?) and then copying the image onto itself to get more stars (WHY?).
Here I have used a loop to create more stars, and originally specified a black background with bright stars (code revised 10 July 2009).
Also the original had crazy names like PLANT for starfield, so I guess the code had already been hacked from some other project? PS if you want to combine cfdg images within gimp (or photoshop if you must) then why not create a transparent background layer line 2 would be background {a -1}, ie no alpha layer. When I did this I found out that I had inadvertently created some black stars, which could easily be corrected using an image manipulation program. However I think I have corrected this now. Originally I put brightness directive in my loop, now it is placed in CIRCLE terminal, empty directive in loop seems OK (any y or x adjustment here would destroy randomness). Whilst I was at it I changed the background from black to dark blue (I've still got a lot to learn).
Code:
   1:startshape starfield
2:background{hue 240 b -0.9 sat 1} // dark blue background
3:rule starfield{ // 5 times create white stars
4:5*{}either{x 2} // empty directive seems OK
5:}
6:// create two instances of star rotate both and flip one
7:rule both{
8:star{rotate 30}
9:star{rotate -30 flip 90}
10:}
11:// multiple either, create a star
12:rule either{
13:star{}
14:}
15:// or create a star and flip it
16:rule either{
17:star{flip 90}
18:}
19:// base star is a translated circle
20:rule star {
21:CIRCLE{b 1} // set star brightness at terminal seems to be safer
22:translate{size 0.91 y 24.6}
23:}
24:// multiple translate rules adds more randomness
25:rule translate {star {rotate 126}}
26:rule translate {
27:star{rotate 127}
28:}
29:rule translate {both{}}
30:rule translate {star {rotate -110 flip 90}}


A Random Starfield Image


The use of the either & both as names of rules seems to be a common idiom within cfdg. Combinations of these rules produce much randomness. I suppose an alternative would be to use 'branch & fork', instead of 'either & both', in keeping with conceptualizing the rules as tree of options? Funny how a lot of the art ends up describing a tree or a spiral (might be nice to a spiral twist to the starfield).

Wednesday, 1 July 2009

Defeating the object

As part of my experimentation with context free, I wanted to see if I could produce a more realistic Mondrian, without converting an image file. I think I've proved it can be done, it is a bit tedious (though could be improved by using a python script to generate the rules, therefore might be a starting point for experiments with cfdg for 'little people'). What I've done is specify row by row (à la image to cfdg script), replaces a ca. 5000 line script with something a bit more elegant, nevertheless very constrained, hence defeating context free concept.

Here's the code:

   1:startshape mondrian
2:
3:rule mondrian{
4:top{y 10}
5:first{}
6:middle_row{y -1}
7:second{y -2}
8:top{y -12}
9:}
10:
11:rule first_colors{
12:border{}
13:part_row{x 1}
14:border{x 11}
15:part_row{x 12 hue 360 sat 1}
16:border{x 22}
17:}
18:
19:rule second_colors{
20:border{}
21:part_row{x 1 hue 60 sat 1}
22:border{x 11}
23:part_row{x 12 hue 360 sat 1}
24:border{x 22}
25:}
26:// increment y
27:rule first{
28:10 * {y 1}first_colors{}
29:}
30:// decrement y
31:rule second{
32:10 * {y -1}second_colors{}
33:}
34:
35:rule middle_row{
36:12 *{x 1}border{}
37:part_row{x 12 hue 360 sat 1}
38:border{x 22}
39:}
40:
41:rule top{
42:23 *{x 1}border{}
43:}
44:
45:rule part_row{
46:10 * {x 1}SQUARE{ s 1 b 1 }
47:}
48:
49:rule border{
50:SQUARE{ s 1 b -1 }
51:}


and the result



However this exercise did make me a bit more familiar with the context free syntax, and also occasioned this perverse idea; why not change the SQUARE to be implemented as a grid of CIRCLES, now that is something context free excels at.
Here is my code:

   1:startshape mondrian
2:
3:rule mondrian{
4:top{y 10}
5:first{}
6:middle_row{y -1}
7:second{y -2}
8:top{y -12}
9:}
10:
11:rule first_colors{
12:border{}
13:part_row{x 1}
14:border{x 11}
15:part_row{x 12 hue 360 sat 1}
16:border{x 22}
17:}
18:
19:rule second_colors{
20:border{}
21:part_row{x 1 hue 60 sat 1}
22:border{x 11}
23:part_row{x 12 hue 360 sat 1}
24:border{x 22}
25:}
26:// increment y
27:rule first{
28:10 * {y 1}first_colors{}
29:}
30:// decrement y
31:rule second{
32:10 * {y -1}second_colors{}
33:}
34:
35:rule middle_row{
36:12 *{x 1}border{}
37:part_row{x 12 hue 360 sat 1}
38:border{x 22}
39:}
40:
41:rule top{
42:23 *{x 1}border{}
43:}
44:
45:rule part_row{
46:10 * {x 1}square{ s 1 b 1 }
47:}
48:
49:rule border{
50:square{ s 1 b -1 }
51:}
52:
53:rule square{
54:2 * {y 0.5}{
55:2 * {x 0.5}
56:CIRCLE{s 0.5}
57:}
58:}


Followers

Blog Archive

About Me

My photo
Pembrokeshire, United Kingdom
I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2