81 lines
2.1 KiB
Text
81 lines
2.1 KiB
Text
declare
|
|
[QTk] = {Link ['x-oz://system/wp/QTk.ozf']}
|
|
|
|
Pi = 3.14159265
|
|
|
|
class PendulumModel
|
|
feat
|
|
K
|
|
attr
|
|
angle
|
|
velocity
|
|
|
|
meth init(length:L <= 1.0 %% meters
|
|
gravity:G <= 9.81 %% m/s²
|
|
initialAngle:A <= Pi/2.) %% radians
|
|
self.K = ~G / L
|
|
angle := A
|
|
velocity := 0.0
|
|
end
|
|
|
|
meth nextAngle(deltaT:DeltaTMS %% milliseconds
|
|
?Angle) %% radians
|
|
DeltaT = {Int.toFloat DeltaTMS} / 1000.0 %% seconds
|
|
Acceleration = self.K * {Sin @angle}
|
|
in
|
|
velocity := @velocity + Acceleration * DeltaT
|
|
angle := @angle + @velocity * DeltaT
|
|
Angle = @angle
|
|
end
|
|
end
|
|
|
|
%% Animates a pendulum on a given canvas.
|
|
class PendulumAnimation from Time.repeat
|
|
feat
|
|
Pend
|
|
Rod
|
|
Bob
|
|
home:pos(x:160 y:50)
|
|
length:140.0
|
|
delay
|
|
|
|
meth init(Pendulum Canvas delay:Delay <= 25) %% milliseconds
|
|
self.Pend = Pendulum
|
|
self.delay = Delay
|
|
%% plate and pivot
|
|
{Canvas create(line 0 self.home.y 320 self.home.y width:2 fill:grey50)}
|
|
{Canvas create(oval 155 self.home.y-5 165 self.home.y+5 fill:grey50 outline:black)}
|
|
%% the pendulum itself
|
|
self.Rod = {Canvas create(line 1 1 1 1 width:3 fill:black handle:$)}
|
|
self.Bob = {Canvas create(oval 1 1 2 2 fill:yellow outline:black handle:$)}
|
|
%%
|
|
{self setRepAll(action:Animate delay:Delay)}
|
|
end
|
|
|
|
meth Animate
|
|
Theta = {self.Pend nextAngle(deltaT:self.delay $)}
|
|
%% calculate x and y from angle
|
|
X = self.home.x + {Float.toInt self.length * {Sin Theta}}
|
|
Y = self.home.y + {Float.toInt self.length * {Cos Theta}}
|
|
in
|
|
%% update canvas
|
|
try
|
|
{self.Rod setCoords(self.home.x self.home.y X Y)}
|
|
{self.Bob setCoords(X-15 Y-15 X+15 Y+15)}
|
|
catch system(tk(alreadyClosed ...) ...) then skip end
|
|
end
|
|
end
|
|
|
|
Pendulum = {New PendulumModel init}
|
|
|
|
Canvas
|
|
GUI = td(title:"Pendulum"
|
|
canvas(width:320 height:210 handle:?Canvas)
|
|
action:proc {$} {Animation stop} {Window close} end
|
|
)
|
|
Window = {QTk.build GUI}
|
|
|
|
Animation = {New PendulumAnimation init(Pendulum Canvas)}
|
|
in
|
|
{Window show}
|
|
{Animation go}
|