Animate a pendulum

Animate a pendulum
You are encouraged to solve this task according to the task description, using any language you may know.

One good way of making an animation is by simulating a physical system and illustrating the variables in that system using a dynamically changing graphical display.
The classic such physical system is a simple gravity pendulum.

For this task, create a simple physical model of a pendulum and animate it.

The angle θ {\displaystyle \theta } of a pendulum with length L{\displaystyle L} and acceleration due to gravity g{\displaystyle g} with all its mass at the end and no friction/air resistance has an acceleration at any given moment of

This simulation uses this formula directly, updating the velocity from the acceleration and the position from the velocity; inaccuracy results from the finite timestep.

The event flow works like this:
The clock object created by the simulation steps the simulation on the specified in the interval.
The simulation writes its output to angle, which is a Lamport slot which can notify of updates.
The whenever set up by makeDisplayComponent listens for updates and triggers redrawing as long as interest has been expressed, which is done whenever the component actually redraws, which happens only if the component's window is still on screen.
When the window is closed, additionally, the simulation itself is stopped and the application allowed to exit.
(This logic is more general than necessary; it is designed to be suitable for a larger application as well.)

// defines an operator "-?" that calculates the time from t2 to t1 // where t2 is optionallet(-?)(t1: DateTime)(t2: DateTime option) : float<s>=match t2 with | None ->0.0<s>// only one timepoint given -> difference is 0 | Some t ->(t1 - t).TotalSeconds*1.0<s>

DIFFEQ and the callback procedure pendulum numerically integrate the pendulum equation.
The display window can be resized during the run, but for window width not equal to 2*height the pendulum rod becomes a rubber band instead:

# set up the windowmethod component_setup ()# some cosmetic settings for the window attrib("size="||WIDTH||","||HEIGHT,"bg=light gray","label=Pendulum")# make sure we respond to window close event connect (self,"dispose", CLOSE_BUTTON_EVENT)# start the ticker, to update the display periodically self.set_ticker(20)endend

The plane pendulum motion is an interesting and easy problem
in which the facilities of RLaB for numerical computation and simulation
are easily accessible.
The parameters of the problem are L{\displaystyle L}, the length of the arm,
and g{\displaystyle g} the magnitude of the gravity.

We start with the mathematical transliteration of the problem.
We solve it in plane (2-D) in terms of θ{\displaystyle \theta } describing
the angle between the z{\displaystyle z}-axis and the arm of the pendulum,
where the downwards direction is taken as positive.
The Newton equation of motion, which is a second-order non-linear
ordinary differential equation (ODE) reads

In our example, we will solve the problem as, so called,
initial value problem (IVP).
That is, we will specify that at the time t=0 the pendulum was at rest θ˙(0)=0{\displaystyle {\dot {\theta }}(0)=0}, extended at an angle θ(0)=0.523598776{\displaystyle \theta (0)=0.523598776}
radians (equivalent to 30 degrees).

RLaB has the facilities to solve ODE IVP which are accessible through odeiv solver. This solver requires that the ODE be written as the first order differential equation,

u˙=f(u){\displaystyle {\dot {u}}=f(u)}

Here, we introduced a vector u=[θ,θ˙]=[u1,u2]{\displaystyle u=[\theta ,{\dot {\theta }}]=[u_{1},u_{2}]},
for which the original ODE reads

// now we solve the problem// physical parametersL = 5; // (m), the length of the arm of the pendulump = mks.g / L; // RLaB has a built-in list 'mks' which contains large number of physical constants and conversion factorsT0 = 2*const.pi*sqrt(L/mks.g); // approximate period of the pendulum

// 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 windowplimits (-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}

This does not have the window resizing handling that Tcl does --
I did not spend enough time in the docs to figure out
how to get the new window size out of the configuration event.
Of interest when running this pendulum side-by-side with the Tcl one:
the Tcl pendulum swings noticibly faster.