*Jeremy Ashkenas had a neat trick that enables use of non-camelcase in ruby-processing, but of course that can cause namespace space issues, possibly more so in python?*). In the interest of being more pythonic, and to reduce the overhead of function calls (

*pythonistas seem to worry about this*) I now access the TPoint instance variables x and y directly.

Returning to python from ruby/java, it is the ruby features that I miss; it is so easy to use attr_accessor & attr_reader to define the access to variables in ruby. Further you really know where you stand regarding access to an objects variables in ruby (private unless exposed) I find the python global access to be both a bit inelegant and awkward.

Take processing sketches for example, where if you want to set something up (say a new instance of a class for example) in the setup() function, and then access it in the draw() loop you need to declare that variable as a global (

*in setup*). For ruby, I generally favour just using attr_reader, then you know if you need to assign the variable you must use the sigil version of the variable.

Here is the revised sketch:-

1 """ 2 alhambra.py by Martin Prout 3 A third stab at converting my Alhambra tiling sketch to processing.py (overwites 2nd) 4 Utilizes a custom lightweight TPoint (to replace the more fattening PVector) 5 """ 6importmath 7fromtpointimportTPoint 8 9 xValues=[100, 300, 500, 700] 10 yValues=[50*math.sqrt(3), 150*math.sqrt(3), 250*math.sqrt(3), 350*math.sqrt(3)] 11 12 13defsetup():14 """ 15 processing setup 16 """ 17 size(700, 650)18 background(21, 15, 72)19 smooth()20 render()21 saveFrame("alhambra.png")22 23 24defdraw_hexagon(xpos, ypos, sz, theta):25 """ 26 hexagon draw function 27 """ 28 beginShape()29foriinrange(0, 6):30 vertex(xpos+sz*math.cos((math.pi/3*i)+theta), ypos+sz*math.sin((math.pi/3*i)+theta)); 31 endShape(CLOSE)32 33 34defdraw_triangle(x0, y0, sz, coluer, disp):35 """ 36 Wavy triangle draw function 37 """ 38 # Set the three initial triangle points, thereafter calculate mid points, and 39 # quarter points. Then adjust the bezier curve control points. 40 pts=[] 41 pts.append(TPoint(x0, y0-sz/math.sqrt(3)))# A (A, B and C are the triangle points) 42 pts.append(TPoint(x0-0.5*sz, y0+(math.sqrt(3)*sz)/6))# B 43 pts.append(TPoint(x0+0.5*sz, y0+(math.sqrt(3)*sz)/6))# C 44 pts.append(pts[0].mid_point(pts[1]))# Ab (Ab, Bc and Ca are the triangle mid points) 45 pts.append(pts[1].mid_point(pts[2]))# Bc 46 pts.append(pts[0].mid_point(pts[2]))# Ca 47 pts.append(pts[0].mid_point(pts[3]))# Aba (Aba ... are the triangle quarter points) 48 adjust_bezier(pts[6], math.pi/3, disp*sz)# Aba 49 pts.append(pts[3].mid_point(pts[1]))# Abb 50 adjust_bezier(pts[7], math.pi/3,-disp*sz)# Abb 51 pts.append(pts[1].mid_point(pts[4]))52 adjust_bezier(pts[8], math.pi/2,-disp*sz)53 pts.append(pts[4].mid_point(pts[2]))54 adjust_bezier(pts[9], math.pi/2, disp*sz)55 pts.append(pts[2].mid_point(pts[5]))56 adjust_bezier(pts[10],-math.pi/3,-disp*sz)57 pts.append(pts[5].mid_point(pts[0]))58 adjust_bezier(pts[11],-math.pi/3, disp*sz)59 # render triangle 60 fill(coluer)61 beginShape()62 vertex(pts[0].x, pts[0].y)63 bezierVertex(pts[0].x, pts[0].y, pts[6].x, pts[6].y, pts[3].x, pts[3].y)64 bezierVertex(pts[3].x, pts[3].y, pts[7].x, pts[7].y, pts[1].x, pts[1].y)65 bezierVertex(pts[1].x, pts[1].y, pts[8].x, pts[8].y, pts[4].x, pts[4].y)66 bezierVertex(pts[4].x, pts[4].y, pts[9].x, pts[9].y, pts[2].x, pts[2].y)67 bezierVertex(pts[2].x, pts[2].y, pts[10].x, pts[10].y, pts[5].x, pts[5].y)68 bezierVertex(pts[5].x, pts[5].y, pts[11].x, pts[11].y, pts[0].x, pts[0].y)69 endShape(CLOSE)70 # set color and render a small hexagon 71 fill(255)72 draw_hexagon(x0+4, y0, sz*0.214, 0)73 74 75defadjust_bezier(bzpoint, theta, disp):76 """ 77 Adjust the Bezier control point 78 """ 79 bzpoint.add(TPoint(math.cos(theta)*disp, math.sin(theta)*disp))80 81defrender():82 """ 83 Tesselate the wavy triangles 84 """ 85forcolumninrange(0,len(xValues)):86forrowinrange(0,len(yValues)):87if(row%2==0):88if(column%3==0):89 draw_triangle(xValues[column], yValues[row], 200, color(255, 0, 0), 0.32)90else:91 draw_triangle(xValues[column], yValues[row], 200, color(255, 0, 255), 0.32)92elif((column-2)%3==0):93 draw_triangle(xValues[column]-100, yValues[row], 200, color(255, 0, 0), 0.32)94else:95 draw_triangle(xValues[column]-100, yValues[row], 200, color(255, 0, 255), 0.32)96 97defdraw():98 """ 99 Is the processing draw loop 100 """ 101pass

Here is the revised TPoint class (no accessors, public attributes)

1 """ 2 tpoint.py is module that contains my lighweight TPoint class 3 avoids accessors by having public attributes (as python default) 4 """ 5 6classTPoint(object):7 """ 8 A lightweight convenience class to store triangle point data 9 With a function to return new instance a the mid point between 10 two TPoint objects 11 """ 12 13def__init__(self, x=0, y=0):14 """ 15 Initialise the new TPoint object 16 """ 17self.x=x 18self.y=y 19 20 21defmid_point(self, tvector):22 """ 23 Calculate the mid point between this and another tvector 24 returns a new TVector representing the mid point 25 """ 26returnTPoint((self.x+tvector.x)/2,(self.y+tvector.y)/2)27 28defadd(self, tvector):29 """ 30 Adds tvector TPoints to self 31 """ 32self.x+=tvector.x 33self.y+=tvector.y

## No comments:

## Post a Comment