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

Showing posts with label pseudo 3D. Show all posts
Showing posts with label pseudo 3D. Show all posts

Wednesday, 14 April 2010

An Translation Exercise (Very Clever Pseudo 3D Animation)

I've created a little ruby script for myself that translates (somewhat imperfectly) vanilla processing (ie. *.pde files) to ruby processing. Here is the tidied up version of a cool sketch I found on open-processing.

# Made by Jared "BlueThen" C.
# November 5, 2009.
# www.bluethen.com
# translated to ruby processing by monkstone April 14 2010
# variable a is used for determining the shape's y position, coupled with the distance they are from the center.
# setup(), the first function called when the applet is started

attr_reader :a, :y

def setup()
  @a = 0
  @y = 0
  # the applet is set to 500 pixels by 500 pixels
  size(500, 500)
  # RGB mode set to maximum of 6, since we'll be using 6 colors. 0 for black, 6 for white, and everything in between.
  color_mode(RGB, 6)
  # The stroke color is used to determine the border color of each quadrilateral.
  stroke(0)
  # frame rate is set to 30.
  frame_rate(30)
end

def draw()

  # a is decreased by 0.08. it represents the amount of radians the height of our boxes changes, and their speed.
  # if we did nothing to a, then none of our shapes will move, so a is a key component in our formulas.

  @a -= 0.08
  # screen is cleared and background is set to 6 (white).
  background(6)  

  # (x, z) is the ground, while y is vertical)  
  (-7..7).each do |x# loop over range for the x axis
    (-7..7).each do |z# loop over range for the z axis
    
      # The y variable is set to determine the height of the box.
      # We use formula radius * cos(angle) to determine this.
      # Since cosine, when graphed, creates a wave, we can use this to have the boxes transition from small to big smoothly.
      # The radius pretty much stands for our range. cosine alone will return values between -1 and 1, so we multiply this
      # by 24 to increase this value. the formula will return something in between -24 and 24.
      # The angle is in radians. an entire loop (circle) is 2PI radians, or roughly 6.283185.
      # distance is used to create the circular effect. it makes the boxes of the same radius around the center similar.
      # The distance ranges from 0 to 7, so 0.55 * distance will be between 0 and 3.85. this will make the highest and lowest
      # box a little more than half a loop's difference. a is added on, (subtracted if you want to be technical, since a is
      # negative), to provide some sort of change for each frame. if we don't include '+ a' in the algorithm, the boxes would
      # be still.
    
      @y = (24 * cos(0.55 * distance(x,z,0,0) + a)).round()
    
    
      # These are 2 coordinate variations for each quadrilateral.
      # since they can be found in 4 different quadrants (+ and - for x, and + and - for z),
      # we'll only need 2 coordinates for each quadrilateral (but we'll need to pair them up differently
      # for this to work fully).
      #
      # Multiplying the x and z variables by 17 will space them 17 pixels apart.
      # The 8.5 will determine half the width of the box ()
      # 8.5 is used because it is half of 17. since 8.5 is added one way, and 8.5 is subtracted the other way, the total
      # width of each box is 17. this will eliminate any sort of spacing in between each box.
      #
      # If you enable no_stroke(), then the whole thing will appear as one 3d shape. try it.
    
      xm = x * 17 - 8.5
      xt = x * 17 + 8.5
      zm = z * 17 - 8.5
      zt = z * 17 + 8.5
    
      # We use an integer to define the width and height of the window. this is used to save resources on further calculating
      halfw = width/2
      halfh = height/2
    
    
      # Here is where all the isometric calculating is done.
      # We take our 4 coordinates for each quadrilateral, and find their (x,y) coordinates using an isometric formula.
      # You'll probably find a similar formula used in some of my other isometric animations. however, I normally use
      # these in a function. to avoid using repetitive calculation (for each coordinate of each quadrilateral, which
      # would be 3 quads * 4 coords * 3 dimensions = 36 calculations).
      #
      # Formerly, the isometric formula was ((x - z) * cos(radians(30)) + width/2, (x + z) * sin(radians(30)) - y + height/2).
      # However, the cosine and sine are constant, so they could be precalculated. cosine of 30 degrees returns roughly 0.866,
      # which can round to 1, leaving it out would have little artifacts (unless placed side_by_side to accurate versions, where
      # everything would appear wider in this version) sine of 30 returns 0.5.
      #
      # We left out subtracting the y value, since this changes for each quadrilateral coordinate. (-40 for the base, and our y
      # variable) these are later subtracted in the actual quad().
    
      isox1 = (xm - zm + halfw).round
      isoy1 = ((xm + zm) * 0.5 + halfh).round
      isox2 = (xm - zt + halfw).round
      isoy2 = ((xm + zt) * 0.5 + halfh).round
      isox3 = (xt - zt + halfw).round
      isoy3 = ((xt + zt) * 0.5 + halfh).round
      isox4 = (xt - zm + halfw).round
      isoy4 = ((xt + zm) * 0.5 + halfh).round
    
      #the side quads. 2 and 4 is used for the coloring of each of these quads
      fill(2)
      quad(isox2, isoy2 - y, isox3, isoy3 - y, isox3, isoy3 + 40, isox2, isoy2 + 40)
      fill(4)
      quad(isox3, isoy3 - y, isox4, isoy4 - y, isox4, isoy4 + 40, isox3, isoy3 + 40)
    
    
      # the top quadrilateral.
      # y, which ranges between -24 and 24, multiplied by 0.05 ranges between -1.2 and 1.2
      # we add 4 to get the values up to between 2.8 and 5.2.
      # this is a very fair shade of grays, since it doesn't become one extreme or the other.
    
      fill(4 + y * 0.05)
      quad(isox1, isoy1 - y, isox2, isoy2 - y, isox3, isoy3 - y, isox4, isoy4 - y)
    end
  end
end

# the distance formula
def distance(x, y, cx, cy)
  sqrt(sq(cx - x) + sq(cy - y))
end







One of the problems with my script is that it turns all '-' to '_' also it can't cope with C++ style multi-line comments they should probably be banned anyway!!!

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