From 2d7c482dc7f3fa39cd00b935278636584bf84341 Mon Sep 17 00:00:00 2001 From: Matt Aimonetti Date: Tue, 13 Jul 2010 00:18:19 -0700 Subject: [PATCH] new particle example and more bug fixes --- README.md | 3 +- examples/canvas_example.rb | 3 -- examples/particle_example.rb | 79 ++++++++++++++++++++++++++++++++++++ lib/canvas.rb | 9 ++-- lib/elements/particle.rb | 10 ++--- lib/elements/rope.rb | 12 +++--- 6 files changed, 96 insertions(+), 20 deletions(-) create mode 100644 examples/particle_example.rb diff --git a/README.md b/README.md index 8b48333..84c8542 100644 --- a/README.md +++ b/README.md @@ -104,4 +104,5 @@ You can see a list of examples in the examples folder, but here is a quick sampl More example outputs: ![MacRuby Image color effects](http://img.skitch.com/20100712-jr4jfhbaw2x9nmhy7bscapgbd4.png) -![MacRuby Image Iterate](http://img.skitch.com/20100713-1132mmahgum65tpgj9d9mag939.png) \ No newline at end of file +![MacRuby Image Iterate](http://img.skitch.com/20100713-1132mmahgum65tpgj9d9mag939.png) +![MacRuby particles examples](http://img.skitch.com/20100713-gb3ps8psw3ppyedx1t1x426rwa.png) \ No newline at end of file diff --git a/examples/canvas_example.rb b/examples/canvas_example.rb index ed3c41e..c468284 100644 --- a/examples/canvas_example.rb +++ b/examples/canvas_example.rb @@ -29,9 +29,6 @@ def drawRect(rect) end -# wrapper class to keep the examples as clean/simple as possible app = AppWrapper.new -# assign an instance of our custiom NSView to the window's content view app.window.contentView = CustomView.alloc.initWithFrame(app.frame) -# start the app app.start \ No newline at end of file diff --git a/examples/particle_example.rb b/examples/particle_example.rb new file mode 100644 index 0000000..8737e62 --- /dev/null +++ b/examples/particle_example.rb @@ -0,0 +1,79 @@ +framework 'Cocoa' +HERE = File.expand_path(File.dirname(__FILE__)) +require File.join(HERE, '..', 'graphics') +require File.join(HERE, 'app_wrapper') + +class CustomView < NSView + include MRGraphics + + def drawRect(rect) + dimensions = [CGRectGetWidth(rect), CGRectGetHeight(rect)] + Canvas.for_current_context(:size => dimensions) do |c| + c.background(Color.black) + + # load images and grab colors + img = Image.new(File.join(HERE, 'images', 'italy.jpg')).saturation(1.9) + red_colors = img.colors(100) + img = Image.new(File.join(HERE, 'images', 'v2.jpg')).saturation(1.9) + blue_colors = img.colors(100) + + # create flower head shape + head = Path.new.oval(0,0,10,10,:center) + petals = 3 + petals.times do + head.rotate(360/petals) + head.oval(0,10,5,5,:center) + head.oval(0,17,2,2,:center) + end + # randomize head attributes + head.randomize(:fill, red_colors) + head.randomize(:stroke, blue_colors) + head.randomize(:scale, 0.2..2.0) + head.randomize(:rotation, 0..360) + + # create particles + numparticles = 200 + numframes = 200 + particles = [] + numparticles.times do |i| + # start particle at random point at bottom of canvas + x = MRGraphics.random(c.width/2 - 50, c.width/2 + 50) + p = Particle.new(x,0) + p.velocity_x = MRGraphics.random(-0.5,0.5) # set initial x velocity + p.velocity_y = MRGraphics.random(1.0,3.0) # set initial y velocity + p.acceleration = 0.1 # set drag or acceleration + particles[i] = p # add particle to array + end + + # animate particles + numframes.times do |frame| + numparticles.times do |i| + particles[i].move + end + end + + # draw particle trails and heads + numparticles.times do |i| + + c.push + # choose a stem color + color = MRGraphics.choose(blue_colors).a(0.7).analog(20,0.7) + c.stroke(color) + c.stroke_width(MRGraphics.random(0.5,2.0)) + + # draw the particle + particles[i].draw(c) # raising an error + + # go to the last particle position and draw the flower head + c.translate(particles[i].points[-1][0],particles[i].points[-1][1]) + c.draw(head) + c.pop + end + end + end + +end + +app = AppWrapper.new(800,600) +app.window.contentView = CustomView.alloc.initWithFrame(app.frame) +app.start \ No newline at end of file diff --git a/lib/canvas.rb b/lib/canvas.rb index d76836f..2bcbd93 100755 --- a/lib/canvas.rb +++ b/lib/canvas.rb @@ -96,7 +96,7 @@ def initialize(options={}, &block) @output = options[:filename] || 'test' @stacksize = 0 @colorspace = CGColorSpaceCreateDeviceRGB() # => CGColorSpaceRef - @autoclosepath = false + @autoclose_path = false case options[:type] when :pdf @@ -391,7 +391,7 @@ def draw(object, *args) # automatically close the path after it is ended def autoclose_path! - @autoclosepath = true + @autoclose_path = true end def autoclose_path=(bool) @@ -416,7 +416,8 @@ def begin_path(x, y) # end the current path and draw it def end_path - CGContextClosePath(@ctx) if @autoclosepath + return if CGContextIsPathEmpty(@ctx) + CGContextClosePath(@ctx) if @autoclose_path mode = KCGPathFillStroke CGContextDrawPath(@ctx, mode) # apply fill and stroke end @@ -787,14 +788,12 @@ def draw_path(p, tx=0, ty=0, iterations=1) CGContextAddPath(@ctx, p.path) if p.class == Path CGContextDrawPath(@ctx, KCGPathFillStroke) # apply fill and stroke - # if there's an image, draw it clipped by the path if (p.image) begin_clip(p) image(p.image) end_clip end - end end end diff --git a/lib/elements/particle.rb b/lib/elements/particle.rb index da61de0..a071abb 100755 --- a/lib/elements/particle.rb +++ b/lib/elements/particle.rb @@ -51,8 +51,8 @@ def move @y += @velocity_y # randomly increase/decrease direction - @velocity_x += random(-1.0, 1.0) * @acceleration - @velocity_y += random(-1.0, 1.0) * @acceleration + @velocity_x += MRGraphics.random(-1.0, 1.0) * @acceleration + @velocity_y += MRGraphics.random(-1.0, 1.0) * @acceleration # draw a line from the old position to the new #CANVAS.line(@previous_x,@previous_y,@x,@y); @@ -67,9 +67,9 @@ def move end def draw(canvas) - canvas.nofill - canvas.lines(@points) + canvas.no_fill + canvas.lines(@points) end end -end +end \ No newline at end of file diff --git a/lib/elements/rope.rb b/lib/elements/rope.rb index 67bca7c..d1e9c42 100755 --- a/lib/elements/rope.rb +++ b/lib/elements/rope.rb @@ -29,9 +29,9 @@ def initialize(canvas, options={}) def hair(hair_x0=@x0, hair_y0=@y0, hair_x1=@x1, hair_y1=@y1, hair_width=@width, hair_fibers=@fibers) @canvas.push - @canvas.strokewidth(@strokewidth) - @canvas.autoclosepath(false) - @canvas.nofill + @canvas.stroke_width(@strokewidth) + @canvas.autoclose_path = false + @canvas.no_fill hair_x0 = MRGraphics.choose(hair_x0) hair_y0 = MRGraphics.choose(hair_y0) hair_x1 = MRGraphics.choose(hair_x1) @@ -56,8 +56,8 @@ def hair(hair_x0=@x0, hair_y0=@y0, hair_x1=@x1, hair_y1=@y1, hair_width=@width, def ribbon(ribbon_x0=@x0, ribbon_y0=@y0, ribbon_x1=@x1, ribbon_y1=@y1, ribbon_width=@width, ribbon_fibers=@fibers) @canvas.push @canvas.strokewidth(@strokewidth) - @canvas.autoclosepath(false) - @canvas.nofill + @canvas.autoclose_path = false + @canvas.no_fill black = Color.black white = Color.white ribbon_x0 = MRGraphics.choose(ribbon_x0) @@ -83,7 +83,7 @@ def ribbon(ribbon_x0=@x0, ribbon_y0=@y0, ribbon_x1=@x1, ribbon_y1=@y1, ribbon_wi # @canvas.oval(cpx0,cpy0,5,5,:center) # @canvas.fill(white) # @canvas.oval(cpx1,cpy1,5,5,:center) - # @canvas.nofill + # @canvas.no_fill @canvas.beginpath(x0, y0) @canvas.curveto(