langs a-z
This commit is contained in:
parent
db842d013d
commit
d066446780
11389 changed files with 98361 additions and 1020 deletions
81
Task/Animate-a-pendulum/Oz/animate-a-pendulum.oz
Normal file
81
Task/Animate-a-pendulum/Oz/animate-a-pendulum.oz
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
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}
|
||||
107
Task/Animate-a-pendulum/PureBasic/animate-a-pendulum.purebasic
Normal file
107
Task/Animate-a-pendulum/PureBasic/animate-a-pendulum.purebasic
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
Procedure handleError(x, msg.s)
|
||||
If Not x
|
||||
MessageRequester("Error", msg)
|
||||
End
|
||||
EndIf
|
||||
EndProcedure
|
||||
|
||||
#ScreenW = 320
|
||||
#ScreenH = 210
|
||||
handleError(OpenWindow(0, 0, 0, #ScreenW, #ScreenH, "Animated Pendulum", #PB_Window_SystemMenu), "Can't open window.")
|
||||
handleError(InitSprite(), "Can't setup sprite display.")
|
||||
handleError(OpenWindowedScreen(WindowID(0), 0, 0, #ScreenW, #ScreenH, 0, 0, 0), "Can't open screen.")
|
||||
|
||||
Enumeration ;sprites
|
||||
#bob_spr
|
||||
#ceiling_spr
|
||||
#pivot_spr
|
||||
EndEnumeration
|
||||
|
||||
TransparentSpriteColor(#PB_Default, RGB(255, 0, 255))
|
||||
CreateSprite(#bob_spr, 32, 32)
|
||||
StartDrawing(SpriteOutput(#bob_spr))
|
||||
Box(0, 0, 32, 32, RGB(255, 0, 255))
|
||||
Circle(16, 16, 15, RGB(253, 252, 3))
|
||||
DrawingMode(#PB_2DDrawing_Outlined)
|
||||
Circle(16, 16, 15, RGB(0, 0, 0))
|
||||
StopDrawing()
|
||||
|
||||
CreateSprite(#pivot_spr, 10, 10)
|
||||
StartDrawing(SpriteOutput(#pivot_spr))
|
||||
Box(0, 0, 10, 10, RGB(255, 0, 255))
|
||||
Circle(5, 5, 4, RGB(125, 125, 125))
|
||||
DrawingMode(#PB_2DDrawing_Outlined)
|
||||
Circle(5, 5, 4, RGB(0,0 , 0))
|
||||
StopDrawing()
|
||||
|
||||
CreateSprite(#ceiling_spr,#ScreenW,2)
|
||||
StartDrawing(SpriteOutput(#ceiling_spr))
|
||||
Box(0,0,SpriteWidth(#ceiling_spr), SpriteHeight(#ceiling_spr), RGB(126, 126, 126))
|
||||
StopDrawing()
|
||||
|
||||
Structure pendulum
|
||||
length.d ; meters
|
||||
constant.d ; -g/l
|
||||
gravity.d ; m/s²
|
||||
angle.d ; radians
|
||||
velocity.d ; m/s
|
||||
EndStructure
|
||||
|
||||
Procedure initPendulum(*pendulum.pendulum, length.d = 1.0, gravity.d = 9.81, initialAngle.d = #PI / 2)
|
||||
With *pendulum
|
||||
\length = length
|
||||
\gravity = gravity
|
||||
\angle = initialAngle
|
||||
\constant = -gravity / length
|
||||
\velocity = 0.0
|
||||
EndWith
|
||||
EndProcedure
|
||||
|
||||
|
||||
Procedure updatePendulum(*pendulum.pendulum, deltaTime.d)
|
||||
deltaTime = deltaTime / 1000.0 ;ms
|
||||
Protected acceleration.d = *pendulum\constant * Sin(*pendulum\angle)
|
||||
*pendulum\velocity + acceleration * deltaTime
|
||||
*pendulum\angle + *pendulum\velocity * deltaTime
|
||||
EndProcedure
|
||||
|
||||
Procedure drawBackground()
|
||||
ClearScreen(RGB(190,190,190))
|
||||
;draw ceiling
|
||||
DisplaySprite(#ceiling_spr, 0, 47)
|
||||
;draw pivot
|
||||
DisplayTransparentSprite(#pivot_spr, 154,43) ;origin in upper-left
|
||||
EndProcedure
|
||||
|
||||
Procedure drawPendulum(*pendulum.pendulum)
|
||||
;draw rod
|
||||
Protected x = *pendulum\length * 140 * Sin(*pendulum\angle) ;scale = 1 m/140 pixels
|
||||
Protected y = *pendulum\length * 140 * Cos(*pendulum\angle)
|
||||
StartDrawing(ScreenOutput())
|
||||
LineXY(154 + 5,43 + 5, 154 + 5 + x, 43 + 5 + y) ;draw from pivot-center to bob-center, adjusting for origins
|
||||
StopDrawing()
|
||||
|
||||
;draw bob
|
||||
DisplayTransparentSprite(#bob_spr, 154 + 5 - 16 + x, 43 + 5 - 16 + y) ;adj for origin in upper-left
|
||||
EndProcedure
|
||||
|
||||
Define pendulum.pendulum, event
|
||||
initPendulum(pendulum)
|
||||
drawPendulum(pendulum)
|
||||
|
||||
AddWindowTimer(0, 1, 50)
|
||||
Repeat
|
||||
event = WindowEvent()
|
||||
Select event
|
||||
Case #pb_event_timer
|
||||
drawBackground()
|
||||
Select EventTimer()
|
||||
Case 1
|
||||
updatePendulum(pendulum, 50)
|
||||
drawPendulum(pendulum)
|
||||
EndSelect
|
||||
FlipBuffers()
|
||||
Case #PB_Event_CloseWindow
|
||||
Break
|
||||
EndSelect
|
||||
ForEver
|
||||
59
Task/Animate-a-pendulum/RLaB/animate-a-pendulum.rlab
Normal file
59
Task/Animate-a-pendulum/RLaB/animate-a-pendulum.rlab
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
//
|
||||
// example: solve ODE for pendulum
|
||||
//
|
||||
|
||||
// we first define the first derivative function for the solver
|
||||
dudt = function(t, u, p)
|
||||
{
|
||||
// t-> time
|
||||
// u->[theta, dtheta/dt ]
|
||||
// p-> g/L, parameter
|
||||
rval = zeros(2,1);
|
||||
rval[1] = u[2];
|
||||
rval[2] = -p[1] * sin(u[1]);
|
||||
return rval;
|
||||
};
|
||||
|
||||
// now we solve the problem
|
||||
// physical parameters
|
||||
L = 5; // (m), the length of the arm of the pendulum
|
||||
p = mks.g / L; // RLaB has a built-in list 'mks' which contains large number of physical constants and conversion factors
|
||||
T0 = 2*const.pi*sqrt(L/mks.g); // approximate period of the pendulum
|
||||
|
||||
// initial conditions
|
||||
theta0 = 30; // degrees, initial angle of deflection of pendulum
|
||||
u0 = [theta0*const.pi/180, 0]; // RLaB has a built-in list 'const' of mathematical constants.
|
||||
|
||||
// times at which we want solution
|
||||
t = [0:4:1/64] * T0; // solve for 4 approximate periods with at time points spaced at T0/64
|
||||
|
||||
// prepare ODEIV solver
|
||||
optsode = <<>>;
|
||||
optsode.eabs = 1e-6; // relative error for step size
|
||||
optsode.erel = 1e-6; // absolute error for step size
|
||||
optsode.delta_t = 1e-6; // maximum dt that code is allowed
|
||||
optsode.stdout = stderr(); // open the text console and in it print the results of each step of calculation
|
||||
optsode.imethod = 5; // use method No. 5 from the odeiv toolkit, Runge-Kutta 8th order Prince-Dormand method
|
||||
//optsode.phase_space = 0; // the solver returns [t, u1(t), u2(t)] which is default behavior
|
||||
optsode.phase_space = 1; // the solver returns [t, u1(t), u2(t), d(u1)/dt(t), d(u2)/dt]
|
||||
|
||||
// solver do my bidding
|
||||
y = odeiv(dudt, p, t, u0, optsode);
|
||||
|
||||
// Make an animation. We choose to use 'pgplot' rather then 'gnuplot' interface because the former is
|
||||
// faster and thus less cache-demanding, while the latter can be very cache-demanding (it may slow your
|
||||
// linux system quite down if one sends lots of plots for gnuplot to plot).
|
||||
plwins (1); // we will use one pgplot-window
|
||||
|
||||
plwin(1); // plot to pgplot-window No. 1; necessary if using more than one pgplot window
|
||||
plimits (-L,L, -1.25*L, 0.25*L);
|
||||
xlabel ("x-coordinate");
|
||||
ylabel ("z-coordinate");
|
||||
plegend ("Arm");
|
||||
for (i in 1:y.nr)
|
||||
{
|
||||
// plot a line between the pivot point at (0,0) and the current position of the pendulum
|
||||
arm_line = [0,0; L*sin(y[i;2]), -L*cos(y[i;2])]; // this is because theta is between the arm and the z-coordinate
|
||||
plot (arm_line);
|
||||
sleep (0.1); // sleep 0.1 seconds between plots
|
||||
}
|
||||
36
Task/Animate-a-pendulum/XPL0/animate-a-pendulum.xpl0
Normal file
36
Task/Animate-a-pendulum/XPL0/animate-a-pendulum.xpl0
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
include c:\cxpl\codes; \intrinsic 'code' declarations
|
||||
|
||||
proc Ball(X0, Y0, R, C); \Draw a filled circle
|
||||
int X0, Y0, R, C; \center coordinates, radius, color
|
||||
int X, Y;
|
||||
for Y:= -R to R do
|
||||
for X:= -R to R do
|
||||
if X*X + Y*Y <= R*R then Point(X+X0, Y+Y0, C);
|
||||
|
||||
|
||||
def L = 2.0, \pendulum arm length (meters)
|
||||
G = 9.81, \acceleration due to gravity (meters/second^2)
|
||||
Pi = 3.14,
|
||||
DT = 1.0/72.0; \delta time = screen refresh rate (seconds)
|
||||
def X0=640/2, Y0=480/2; \anchor point = center coordinate
|
||||
real S, V, A, T; \arc length, velocity, acceleration, theta angle
|
||||
int X, Y; \ball coordinates
|
||||
|
||||
[SetVid($101); \set 640x480x8 graphic display mode
|
||||
T:= Pi*0.75; V:= 0.0; \starting angle and velocity
|
||||
S:= T*L;
|
||||
repeat A:= -G*Sin(T);
|
||||
V:= V + A*DT;
|
||||
S:= S + V*DT;
|
||||
T:= S/L;
|
||||
X:= X0 + fix(L*100.0*Sin(T)); \100 scales to fit screen
|
||||
Y:= Y0 + fix(L*100.0*Cos(T));
|
||||
Move(X0, Y0); Line(X, Y, 7); \draw pendulum
|
||||
Ball(X, Y, 10, $E\yellow\);
|
||||
while port($3DA) & $08 do []; \wait for vertical retrace to go away
|
||||
repeat until port($3DA) & $08; \wait for vertical retrace signal
|
||||
Move(X0, Y0); Line(X, Y, 0); \erase pendulum
|
||||
Ball(X, Y, 10, 0\black\);
|
||||
until KeyHit; \keystroke terminates program
|
||||
SetVid(3); \restore normal text screen
|
||||
]
|
||||
Loading…
Add table
Add a link
Reference in a new issue