Skip to content

Instantly share code, notes, and snippets.

@duckinator
Created September 18, 2010 04:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save duckinator/585365 to your computer and use it in GitHub Desktop.
Save duckinator/585365 to your computer and use it in GitHub Desktop.
require 'tk'
class Pendulum
def initialize
setup
show
@after_id = @root.after(500) {animate}
@canvas.bind('<Destroy>') do
@root.after_cancel(@after_id)
end
Tk.mainloop
end
def setup
@root = TkRoot.new("title" => "Pendulum Animation")
@canvas = TkCanvas.new($root) do
width 320
height 200
create TkcLine, 0, 25, 320, 25, 'tags' => 'plate', 'width' => 2, 'fill' => 'grey50'
create TkcOval, 155, 20, 165, 30, 'tags' => 'pivot', 'outline' => "", 'fill' => 'grey50'
create TkcLine, 1, 1, 1, 1, 'tags' => 'rod', 'width' => 3, 'fill' => 'black'
create TkcOval, 1, 1, 2, 2, 'tags' => 'bob', 'outline' => 'black', 'fill' => 'yellow'
end
@canvas.raise('pivot')
@canvas.pack('fill' => 'both', 'expand' => true)
@Theta = 45.0
@dTheta = 0.0
@length = 150
@home = {
:x => 160,
:y => 25
}
end
def show
angle = @Theta * Math::PI / 180
x = @home[:x] + @length * Math.sin(angle)
y = @home[:y] + @length * Math.cos(angle)
@canvas.coords('rod', @home[:x], @home[:y], x, y)
@canvas.coords('bob', x-15, y-15, x+15, y+15)
end
def recompute_angle
scaling = 3000.0 / (@length ** 2)
# first estimate
firstDDTheta = -Math.sin(@Theta * Math::PI / 180) * scaling
midDTheta = @dTheta + firstDDTheta
midTheta = @Theta + (@dTheta + midDTheta)/2
# second estimate
midDDTheta = -Math.sin(midTheta * Math::PI / 180) * scaling
midDTheta = @dTheta + (firstDDTheta + midDDTheta)/2
midTheta = @Theta + (@dTheta + midDTheta)/2
# again, first
midDDTheta = -Math.sin(midTheta * Math::PI / 180) * scaling
lastDTheta = midDTheta + midDDTheta
lastTheta = midTheta + (midDTheta + lastDTheta)/2
# again, second
lastDDTheta = -Math.sin(lastTheta * Math::PI/180) * scaling
lastDTheta = midDTheta + (midDDTheta + lastDDTheta)/2
lastTheta = midTheta + (midDTheta + lastDTheta)/2
# Now put the values back in our globals
@dTheta = lastDTheta
@Theta = lastTheta
end
def animate
recompute_angle
show
@after_id = @root.after(15) {animate}
end
end
Pendulum.new
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment