# Binary Ring.
# After Jared Tarbell.

class BinaryRing < Processing::App  
  attr_reader :blackout
  
  def setup
    @num = 1000
    @blackout = false
    @kaons = []
    
    # Environmental
    render_mode P3D
    background 0
    
    # Begin with particle sling-shot around ring origin
    @num.times do |i|
      emitx = (30*Math.sin(Math::PI*2*i/@num))
      emity = (30*Math.cos(Math::PI*2*i/@num))
      r = Math::PI * i / @num
      @kaons[i] = Particle.new(self, emitx, emity, r)
    end
  end
  
  def draw
    push_matrix
    translate width/2, height/2
    @kaons.each {|kaon| kaon.move }
    @blackout = !@blackout if rand < 0.005
    pop_matrix
  end
  
  def mouse_pressed
    @blackout = !@blackout
  end
end

class Particle
  def initialize(app, dx, dy, r)
    @app = app
    @width, @height = @app.width, @app.height
    @x, @y = -dx, -dy
    @xx, @yy = 0, 0
    @vx, @vy = 2*Math.cos(r), 2*Math.sin(r)
    @app.blackout ? @i = 0 : @i = 255
    @age = rand(200)
  end
  
  def move
    @xx, @yy = @x, @y
    @x += @vx
    @y += @vy
    @vx += rand - 0.5
    @vy += rand - 0.5
    @app.stroke @i, 24
    @app.line(@xx, @yy, @x, @y)
    @app.line(- @xx, @yy, - @x, @y)
    # And then grow old
    @age += 1
    if @age > 200 || @x.abs > @width || @y.abs > @height # Die and resurrect.
      t = rand * Math::PI*2
      @x, @y = 30*Math.sin(t), 30*Math.cos(t)
      @xx, @yy, @vx, @vy, @age = 0, 0, 0, 0, 0
      @app.blackout ? @i = 0 : @i = 255
    end
  end
end

BinaryRing.new :width => 1000, :height => 500, :title => "Binary Ring", :full_screen => true