Experiments with ruby-processing (processing-2.2.1) and JRubyArt for processing-3.0

Friday, 6 March 2015

Bezier patch sketch in JRubyArt

Occasionally I see people trawling over really old sketches in this blog, and I wonder what are they thinking? when program versions (ie newer ruby-processing versions) change or there are new opportunities such as JRubyArt, why not look at the "hot" stuff. Anyway I revised this sketch for JRubyArt (no need to import :vecmath it is built in)....
Sketch also makes use of AppRender to make for direct conversion from Vec3D to vertex/normal.
# 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, :renderer

def setup
  sketch_title 'Bezier Patch'
  ArcBall.init(self)
  @auto_normals = false
  @renderer = AppRender.new(self)
  build
end

def draw
  background(255)
  smooth(8)
  lights
  no_stroke
  fill(192, 192, 192)
  define_lights
  lights
  (0...RESI - 1).each do |i|
    begin_shape(QUAD_STRIP)
    (0...RESJ).each do |j|
      normp[i][j].to_normal(renderer) unless auto_normals
      outp[i][j].to_vertex(renderer)
      outp[i + 1][j].to_vertex(renderer)
    end
    end_shape
  end
end

def settings
  size(1024, 768, P3D)
end

def define_lights
  ambient_light(60, 60, 60)
  point_light(30, 30, 30, 0, 0, 0)
  directional_light(40, 40, 50, 1, 0, 0)
  spot_light(30, 30, 30, 0, 40, 200, 0, -0.5, 0.5, PI / 2, 2)
end


def key_pressed
  return unless key == ' '
  save_frame('bez_patch.png')
  build
end

def build
  @outp = []
  @normp = []
  @inp = []
  uitang = Vec3D.new
  ujtang = Vec3D.new
  (0...NI).each do |i|
    row = []
    (0...NJ).each do |j|
      row << Vec3D.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 = Vec3D.new
      uitang = Vec3D.new
      ujtang = Vec3D.new
      (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 += Vec3D.new(-NI / 2, -NJ / 2, 0)
      vect *= 100
      row << vect
      uitang.normalize!
      row_n << uitang.cross(ujtang.normalize)
    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 *= mu**k.to_f if k > 0
  return blend * (1 - mu)**(n - k).to_f if n - k > 0
  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 = mu**k.to_f
    dk = k * mu**(k - 1).to_f
  end
  if n - k > 0
    fnk = (1 - mu)**(n - k).to_f
    dnk = (k - n) * (1 - mu)**(n - k - 1).to_f
  end
  dblendf * (dk * fnk + fk * dnk)
end

No comments:

Post a Comment

Followers

About Me

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