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

Sunday, 9 August 2009

Ruby script for cfdg

Well the pre-processor tool is all very well, but you have to be careful writing your define macro, so I thought hmmmmmmmmmmmn! why not use a ruby script (I can think easier in ruby than I can in python, python may be very correct, but I think it is often counter-intuitive, obviously suits Guido/Alex Martelli, great libraries though). Another plus point with ruby vs 'C' pre-compiler approach is no silly radian to degree conversions required, the calculations are done in ruby (note: set precision to suit yourself).
   1 # cfdg_writer.rb
2
3 B = 1.4
4
5 def start(name = "shape")
6 "startshape %s" % name
7 end
8 def simple_rule(rule_name, path_name, parms = "")
9 "rule %s{\n %s{%s}\n}" % [rule_name, path_name, parms]
10 end
11 def two_path_rule(rule_name, path_name, path_two, parms = "")
12 "rule %s{\n %s{%s}\n %s{%s}\n}" % [rule_name, path_name, parms, path_two, parms]
13 end
14 def calculate_x(theta)
15 Math.cos(theta)*Math.exp(theta/Math.tan(B))
16 end
17 def calculate_y(theta)
18 Math.sin(theta)*Math.exp(theta/Math.tan(B))
19 end
20 def move_to(xp, yp)
21 " MOVETO{x %0.4f y %0.4f}" % [xp, yp]
22 end
23 def line_to(xp, yp)
24 " LINETO{x %0.4f y %0.4f}" % [xp, yp]
25 end
26
27 def stroke(param = "")
28 puts " STROKE{%s}" % param
29 end
30
31 def create_shell(path_name)
32 puts "path %s{\n" % path_name
33 puts move_to(0, 0)
34 for step in 0 ... 400
35 puts line_to(calculate_x(step/10.0), calculate_y(step/10.0))
36 end
37 stroke("b 1 hue 360 sat 1 width 7")
38 puts "}"
39 end
40
41 def create_segments(path_name)
42 puts "path %s{\n" % path_name
43
44 for step in 7 ... 41
45 puts move_to(calculate_x(step - 7), calculate_y(step - 7))
46 puts line_to(calculate_x(step), calculate_y(step))
47 end
48 stroke("b 1 hue 220 sat 1 width 5")
49 puts "}"
50 end
51
52 path_name = "spiral"
53 second_path_name = "segments"
54 shape_name = "nautilus"
55 puts start(shape_name)
56 puts "background{b -1}"
57 puts two_path_rule(shape_name, second_path_name, path_name, "r 185 flip 90")
58 create_shell(path_name) # internal puts
59 create_segments(second_path_name)
60


Very crude I know I just piped result to the file rather than console (advantage send result to console first to check output).

ruby cfdg_writer.rb > nautilus.cfdg

When you run the rule in the cfdg program this is what you get, a nice smooth curve (no CURVETO required), best viewed at full size 1000 x 1000. NB in line 32 I have divided by a float to force a float result from my division.



Now I have handed amend my cfdg file to make sure the segment and curve join only a little gap. Script saves masses of typing.... it would be nice to get CURVE to work on the segments.
However this is clearly not the way to draw a nautilus in context free, Mountain View Mark has put me right over at the Context Free Art Gallery, where I posted my nautilus under the author name 'monkstone'. However there is something to be said for the elegance of the single thickness line (you are forced toward a tapering line with the cfdg approach).

No comments:

Post a Comment

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