# bezier patch By Marius Watz: # http://www.openprocessing.org/sketch/57709 # Normal calculation added by Andres Colubri # Direct port of sample code by Paul Bourke. # Original code: http://paulbourke.net/geometry/bezier/ # # hit "spacebar" to generate a new shape and save current # NI=4 NJ=5 RESI=NI*10 RESJ=NJ*10 attr_accessor :outp, :inp, :normp, :auto_normals def setup size(1024, 768, P3D) @auto_normals = false build end def draw background(255) translate(width/2,height/2) smooth(8) lights #scale(0.9) rotate_y(map(mouse_x, 0, width, -PI, PI)) rotate_x(map(mouse_y, 0, height, -PI, PI)) no_stroke fill(192, 192, 192) ambient_light(100, 100, 100) ambient(40) specular(30) (0 ... RESI - 1).each do |i| beginShape(QUAD_STRIP) (0 ... RESJ).each do |j| if (!auto_normals) normal(*normp[i][j]) end vertex(*outp[i][j]) vertex(*outp[i+1][j]) end endShape end end def keyPressed if (key == ' ') save_frame("bezPatch.png") build end end def build @outp = [] @normp = [] @inp = [] uitang = PVector.new ujtang = PVector.new (0 ... NI).each do |i| row = Array.new (0 ... NJ).each do |j| row << PVector.new(i, j, (rand * 6) - 3) end inp << row end (0 ... RESI).each do |i| mui = i.fdiv(RESI - 1) row = [] row_n = [] (0 ... RESJ).each do |j| muj = j.fdiv(RESJ - 1) vect = PVector.new uitang.set(0, 0, 0) ujtang.set(0, 0, 0) (0 ... NI).each do |ki| bi = bezier_blend(ki, mui, NI) dbi = d_bezier_blend(ki, mui, NI) (0 ... NJ).each do |kj| bj = bezier_blend(kj, muj, NJ) dbj = d_bezier_blend(kj, muj, NJ) vect.x += (inp[ki][kj].x * bi * bj) vect.y += (inp[ki][kj].y * bi * bj) vect.z += (inp[ki][kj].z * bi * bj) uitang.x += (inp[ki][kj].x * dbi * bj) uitang.y += (inp[ki][kj].y * dbi * bj) uitang.z += (inp[ki][kj].z * dbi * bj) ujtang.x += (inp[ki][kj].x * bi * dbj) ujtang.y += (inp[ki][kj].y * bi * dbj) ujtang.z += (inp[ki][kj].z * bi * dbj) end end vect.add(PVector.new(-NI/2,-NJ/2,0)) vect.mult(100) row << vect.array() uitang.normalize ujtang.normalize row_n << uitang.cross(ujtang).array() end @outp << row @normp << row_n end end def bezier_blend( k, mu, n) blend = 1.0 nn = n kn = k nkn = n - k while (nn >= 1) blend *= nn nn -= 1 if (kn > 1) blend = blend.fdiv(kn) kn -= 1 end if (nkn > 1) blend = blend.fdiv(nkn) nkn -= 1 end end blend *= pow(mu, k.to_f) if (k > 0) blend *= pow(1-mu, (n - k).to_f) if (n - k > 0) return(blend) end def d_bezier_blend( k, mu, n) dblendf = 1.0 nn = n kn = k nkn = n - k while (nn >= 1) dblendf *= nn nn -= 1 if (kn > 1) dblendf = dblendf.fdiv(kn) kn -= 1 end if (nkn > 1) dblendf = dblendf.fdiv(nkn) nkn -= 1 end end fk = 1 dk = 0 fnk = 1 dnk = 0 if (k > 0) fk = pow(mu, k.to_f) dk = k * pow(mu, (k - 1).to_f) end if (n - k > 0) fnk = pow(1 - mu, (n - k).to_f) dnk = (k - n)*pow(1 - mu, (n - k - 1).to_f) end dblendf *= (dk * fnk + fk * dnk) return(dblendf) end
Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0
Showing posts with label bezier. Show all posts
Showing posts with label bezier. Show all posts
Thursday, 27 December 2012
Bezier Patch in ruby-processing
This is getting to be a habit? Another sketch by Marius Watz translated to ruby-processing. The main reason is that I've been working on updating ruby-processing to processing-2.0, and in the course of that I'm including some sketches included with the processing-2.0 distribution and this is just another. Both these sketches benefit from taking a different approach building arrays in ruby cf java. This one has benefited from bit more tuning, as there no real need for an arrays of PVector once the math has been done. Further it is so easy to just splat array to the vertex coordinates, don't you just love ruby.
Labels:
bezier,
ruby-processing
Subscribe to:
Posts (Atom)
Followers
About Me
- monkstone
- I have developed JRubyArt and propane new versions of ruby-processing for JRuby-9.1.5.0 and processing-3.2.2
