def Pi = 3.14159265358979323846, N=12, Tab=9;
func real D2D;  real D;  return Mod(D, 360.);
func real G2G;  real G;  return Mod(G, 400.);
func real M2M;  real M;  return Mod(M, 6400.);
func real R2R;  real R;  return Mod(R, 2.*Pi);
func real D2G;  real D;  return 400. * D2D(D) / 360.;
func real D2M;  real D;  return 6400.* D2D(D) / 360.;
func real D2R;  real D;  return 2.*Pi* D2D(D) / 360.;
func real G2D;  real G;  return 360. * G2G(G) / 400.;
func real G2M;  real G;  return 6400.* G2G(G) / 400.;
func real G2R;  real G;  return 2.*Pi* G2G(G) / 400.;
func real M2D;  real M;  return 360. * M2M(M) / 6400.;
func real M2G;  real M;  return 400. * M2M(M) / 6400.;
func real M2R;  real M;  return 2.*Pi* M2M(M) / 6400.;
func real R2D;  real R;  return 360. * R2R(R) / (2.*Pi);
func real R2G;  real R;  return 400. * R2R(R) / (2.*Pi);
func real R2M;  real R;  return 6400.* R2R(R) / (2.*Pi);

real Angle;  int I;
[Angle:=
[-2., -1., 0., 1., 2., 6.2831853, 16., 57.2957795, 359., 399., 6399., 1000000.];
Format(7, 7);
Text(0, "
     Degrees         Normalized      Gradians        Mils            Radians
");
for I:= 0 to N-1 do
    [RlOut(0, Angle(I));  ChOut(0, Tab);
    RlOut(0, D2D(Angle(I)));  ChOut(0, Tab);
    RlOut(0, D2G(Angle(I)));  ChOut(0, Tab);
    RlOut(0, D2M(Angle(I)));  ChOut(0, Tab);
    RlOut(0, D2R(Angle(I)));  CrLf(0);
    ];
Text(0, "
     Gradians        Normalized      Degrees         Mils            Radians
");
for I:= 0 to N-1 do
    [RlOut(0, Angle(I));  ChOut(0, Tab);
    RlOut(0, G2G(Angle(I)));  ChOut(0, Tab);
    RlOut(0, G2D(Angle(I)));  ChOut(0, Tab);
    RlOut(0, G2M(Angle(I)));  ChOut(0, Tab);
    RlOut(0, G2R(Angle(I)));  CrLf(0);
    ];
Text(0, "
     Mils            Normalized      Degrees         Gradians        Radians
");
for I:= 0 to N-1 do
    [RlOut(0, Angle(I));  ChOut(0, Tab);
    RlOut(0, M2M(Angle(I)));  ChOut(0, Tab);
    RlOut(0, M2D(Angle(I)));  ChOut(0, Tab);
    RlOut(0, M2G(Angle(I)));  ChOut(0, Tab);
    RlOut(0, M2R(Angle(I)));  CrLf(0);
    ];
Text(0, "
     Radians         Normalized      Degrees         Gradians        Mils
");
for I:= 0 to N-1 do
    [RlOut(0, Angle(I));  ChOut(0, Tab);
    RlOut(0, R2R(Angle(I)));  ChOut(0, Tab);
    RlOut(0, R2D(Angle(I)));  ChOut(0, Tab);
    RlOut(0, R2G(Angle(I)));  ChOut(0, Tab);
    RlOut(0, R2M(Angle(I)));  CrLf(0);
    ];
]


var [const]
   tau=(0.0).pi*2,
   units=Dictionary(	// code:(name, units in circle)
      "d", T("degrees", 360.0), "g",T("gradians",400.0),
      "m", T("mills",  6400.0), "r",T("radians", tau) ),
   cvtNm="%s-->%s".fmt,
   cvt=  // "d-->r":fcn(angle){}, "r-->d":fcn(angle){} ...
      Walker.cproduct(units.keys,units.keys).pump(Dictionary(),fcn([(a,b)]){
	 return(cvtNm(a,b),  // "d-->r"
	    'wrap(angle){ angle=angle.toFloat();
	       u:=units[a][1];
	       (angle%u)*units[b][1] / u
	    })
	  })
;


generic
   type Float_Type is digits <>;
   Gravitation : Float_Type;
package Pendulums is
   type Pendulum is private;
   function New_Pendulum (Length : Float_Type;
                          Theta0 : Float_Type) return Pendulum;
   function Get_X (From : Pendulum) return Float_Type;
   function Get_Y (From : Pendulum) return Float_Type;
   procedure Update_Pendulum (Item : in out Pendulum; Time : in Duration);
private
   type Pendulum is record
      Length   : Float_Type;
      Theta    : Float_Type;
      X        : Float_Type;
      Y        : Float_Type;
      Velocity : Float_Type;
   end record;
end Pendulums;


#include <flow.h>
#include <flow-term.h>

DEF-MAIN(argv,argc)

   SET( Pen, 0 )
   LET( Pen := STR-TO-UTF8(CHAR(219)) )

   CLR-SCR
   HIDE-CURSOR

   GOSUB( Animate a Pendulum )

   SHOW-CURSOR
END

RUTINES

DEF-FUN( Animate a Pendulum )
  MSET( accel, speed, bx, by )
  SET( theta, M_PI_2 )  // pi/2 constant --> flow.h
  SET( g, 9.81 )
  SET( l, 1 )
  SET( px, 65 )
  SET( py, 7 )

  LOOP( Animate All )
    LET( bx := ADD( px, MUL( MUL( l, 23 ), SIN(theta) ) ) )
    LET( by := SUB( py, MUL( MUL( l, 23 ), COS(theta) ) ) )

    CLR-SCR
    {px,py,bx,by} GOSUB( LINE )
    {bx, by, 3} GOSUB( CIRCLE )

    LET( accel := MUL(g, SIN(theta) DIV-INTO(l) DIV-INTO(4) ) )
    LET( speed := ADD( speed, DIV(accel, 100) ) )
    LET( theta := ADD( theta, speed ) )
    LOCATE (1, 62) PRNL("PENDULUM")
    LOCATE (2, 55) PRNL("Press any key to quit")
    SLEEP( 0.1 )
  BACK-IF ( NOT( KEY-PRESSED? ), Animate All )

RET

/* DDA Algorithm */
DEF-FUN(LINE, x1, y1, x2, y2)
  MSET( x, y, dx, dy, paso, i, gm )

  STOR( SUB(x2, x1) SUB(y2, y1), dx, dy )
  LET( paso := IF( GE?( ABS(dx) » (DX), ABS(dy)»(DY) ), DX, DY ) )

  // increment:
  STOR( DIV(dx, paso) DIV(dy, paso), dx, dy )

  // print line:
  SET( i, 0 )
  WHILE( LE?(i, paso), ++i )
     LOCATE( y1, x1 ), PRNL( Pen )
     STOR( ADD( x1, dx) ADD( y1, dy ), x1, y1 )
  WEND
RET

DEF-FUN( Plot Points, xc, yc ,x1 ,y1 )
  LOCATE( ADD(xc,x1), ADD( yc, y1) ), PRN( Pen )
  LOCATE( SUB(xc,x1), ADD( yc, y1) ), PRN( Pen )
  LOCATE( ADD(xc,x1), SUB( yc, y1) ), PRN( Pen )
  LOCATE( SUB(xc,x1), SUB( yc, y1) ), PRN( Pen )
  LOCATE( ADD(xc,y1), ADD( yc, x1) ), PRN( Pen )
  LOCATE( SUB(xc,y1), ADD( yc, x1) ), PRN( Pen )
  LOCATE( ADD(xc,y1), SUB( yc, x1) ), PRN( Pen )
  LOCATE( SUB(xc,y1), SUB( yc, x1) ), PRNL( Pen )
RET

DEF-FUN( CIRCLE, xc, yc, ratio )
  MSET( x, p )

  SET( y, ratio )
  LOCATE( yc,xc ), PRNL("O")
  {yc, xc, y, x} GOSUB( Plot Points )
  LET( p := SUB( 1, ratio ) )
  LOOP( Print Circle )
     ++x
     COND( LT?( p, 0 ) )
          LET( p := ADD( p, MUL(2,x) ) PLUS(1) )
     ELS
          --y
          LET( p := ADD( p, MUL(2, SUB(x,y))) PLUS(1) )
     CEND
     {yc, xc, y, x} GOSUB( Plot Points )
  BACK-IF-LT( x, y, Print Circle )
RET


SetBatchlines,-1
;settings
SizeGUI:={w:650,h:400} ;Guisize
pendulum:={length:300,maxangle:90,speed:2,size:30,center:{x:Sizegui.w//2,y:10}} ;pendulum length, size, center, speed and maxangle

pendulum.maxangle:=pendulum.maxangle*0.01745329252
p_Token:=Gdip_Startup()
Gui,+LastFound
Gui,show,% "w" SizeGUI.w  " h" SizeGUI.h
hwnd:=WinActive()
hdc:=GetDC(hwnd)
start:=A_TickCount/1000
G:=Gdip_GraphicsFromHDC(hdc)
pBitmap:=Gdip_CreateBitmap(650, 450)
G2:=Gdip_GraphicsFromImage(pBitmap)
Gdip_SetSmoothingMode(G2, 4)
pBrush := Gdip_BrushCreateSolid(0xff0000FF)
pBrush2 := Gdip_BrushCreateSolid(0xFF777700)
pPen:=Gdip_CreatePenFromBrush(pBrush2, 10)
SetTimer,Update,10

Update:
Gdip_GraphicsClear(G2,0xFFFFFFFF)
time:=start-(A_TickCount/1000*pendulum.speed)
angle:=sin(time)*pendulum.maxangle
x2:=sin(angle)*pendulum.length+pendulum.center.x
y2:=cos(angle)*pendulum.length+pendulum.center.y
Gdip_DrawLine(G2,pPen,pendulum.center.x,pendulum.center.y,x2,y2)
GDIP_DrawCircle(G2,pBrush,pendulum.center.x,pendulum.center.y,15)
GDIP_DrawCircle(G2,pBrush2,x2,y2,pendulum.size)
Gdip_DrawImage(G, pBitmap)
return

GDIP_DrawCircle(g,b,x,y,r){
	Gdip_FillEllipse(g, b, x-r//2,y-r//2 , r, r)
}

GuiClose:
ExitApp


      MODE 8
      *FLOAT 64
      VDU 23,23,4;0;0;0; : REM Set line thickness

      theta = RAD(40) : REM initial displacement
      g = 9.81 : REM acceleration due to gravity
      l = 0.50 : REM length of pendulum in metres

      REPEAT
        PROCpendulum(theta, l)
        WAIT 1
        PROCpendulum(theta, l)
        accel = - g * SIN(theta) / l / 100
        speed += accel / 100
        theta += speed
      UNTIL FALSE
      END

      DEF PROCpendulum(a, l)
      LOCAL pivotX, pivotY, bobX, bobY
      pivotX = 640
      pivotY = 800
      bobX = pivotX + l * 1000 * SIN(a)
      bobY = pivotY - l * 1000 * COS(a)
      GCOL 3,6
      LINE pivotX, pivotY, bobX, bobY
      GCOL 3,11
      CIRCLE FILL bobX + 24 * SIN(a), bobY - 24 * COS(a), 24
      ENDPROC


#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
#include <GL/gl.h>
#include <sys/time.h>

#define length 5
#define g 9.8
double alpha, accl, omega = 0, E;
struct timeval tv;

double elappsed() {
	struct timeval now;
	gettimeofday(&now, 0);
	int ret = (now.tv_sec - tv.tv_sec) * 1000000
		+ now.tv_usec - tv.tv_usec;
	tv = now;
	return ret / 1.e6;
}

void resize(int w, int h)
{
	glViewport(0, 0, w, h);
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	glOrtho(0, w, h, 0, -1, 1);
}

void render()
{
	double x = 320 + 300 * sin(alpha), y = 300 * cos(alpha);
	resize(640, 320);
 	glClear(GL_COLOR_BUFFER_BIT);

	glBegin(GL_LINES);
	glVertex2d(320, 0);
	glVertex2d(x, y);
	glEnd();
	glFlush();

	double us = elappsed();
	alpha += (omega + us * accl / 2) * us;
	omega += accl * us;

	/* don't let precision error go out of hand */
	if (length * g * (1 - cos(alpha)) >= E) {
		alpha = (alpha < 0 ? -1 : 1) * acos(1 - E / length / g);
		omega = 0;
	}
	accl = -g / length * sin(alpha);
}

void init_gfx(int *c, char **v)
{
	glutInit(c, v);
	glutInitDisplayMode(GLUT_RGB);
	glutInitWindowSize(640, 320);
	glutIdleFunc(render);
	glutCreateWindow("Pendulum");
}

int main(int c, char **v)
{
	alpha = 4 * atan2(1, 1) / 2.1;
	E = length * g * (1 - cos(alpha));

	accl = -g / length * sin(alpha);
	omega = 0;

	gettimeofday(&tv, 0);
	init_gfx(&c, v);
	glutMainLoop();
	return 0;
}


using System;
using System.Drawing;
using System.Windows.Forms;

class CSharpPendulum
{
    Form _form;
    Timer _timer;

    double _angle = Math.PI / 2,
           _angleAccel,
           _angleVelocity = 0,
           _dt = 0.1;

    int _length = 50;

    [STAThread]
    static void Main()
    {
        var p = new CSharpPendulum();
    }

    public CSharpPendulum()
    {
        _form = new Form() { Text = "Pendulum", Width = 200, Height = 200 };
        _timer = new Timer() { Interval = 30 };

        _timer.Tick += delegate(object sender, EventArgs e)
        {
            int anchorX = (_form.Width / 2) - 12,
                anchorY = _form.Height / 4,
                ballX = anchorX + (int)(Math.Sin(_angle) * _length),
                ballY = anchorY + (int)(Math.Cos(_angle) * _length);

            _angleAccel = -9.81 / _length * Math.Sin(_angle);
            _angleVelocity += _angleAccel * _dt;
            _angle += _angleVelocity * _dt;

            Bitmap dblBuffer = new Bitmap(_form.Width, _form.Height);
            Graphics g = Graphics.FromImage(dblBuffer);
            Graphics f = Graphics.FromHwnd(_form.Handle);

            g.DrawLine(Pens.Black, new Point(anchorX, anchorY), new Point(ballX, ballY));
            g.FillEllipse(Brushes.Black, anchorX - 3, anchorY - 4, 7, 7);
            g.FillEllipse(Brushes.DarkGoldenrod, ballX - 7, ballY - 7, 14, 14);

            f.Clear(Color.White);
            f.DrawImage(dblBuffer, new Point(0, 0));
        };

        _timer.Start();
        Application.Run(_form);
    }
}


#ifndef __wxPendulumDlg_h__
#define __wxPendulumDlg_h__

// ---------------------
/// @author Martin Ettl
/// @date   2013-02-03
// ---------------------

#ifdef __BORLANDC__
#pragma hdrstop
#endif

#ifndef WX_PRECOMP
#include <wx/wx.h>
#include <wx/dialog.h>
#else
#include <wx/wxprec.h>
#endif
#include <wx/timer.h>
#include <wx/dcbuffer.h>
#include <cmath>

class wxPendulumDlgApp : public wxApp
{
    public:
        bool OnInit();
        int OnExit();
};

class wxPendulumDlg : public wxDialog
{
    public:

        wxPendulumDlg(wxWindow *parent, wxWindowID id = 1, const wxString &title = wxT("wxPendulum"),
				 const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize,
				 long style = wxSUNKEN_BORDER | wxCAPTION | wxRESIZE_BORDER | wxSYSTEM_MENU | wxDIALOG_NO_PARENT | wxMINIMIZE_BOX | wxMAXIMIZE_BOX | wxCLOSE_BOX);

        virtual ~wxPendulumDlg();

		// Event handler
        void wxPendulumDlgPaint(wxPaintEvent& event);
        void wxPendulumDlgSize(wxSizeEvent& event);
        void OnTimer(wxTimerEvent& event);

    private:

		// a pointer to a timer object
        wxTimer *m_timer;

		unsigned int m_uiLength;
		double  	 m_Angle;
		double       m_AngleVelocity;

        enum wxIDs
        {
            ID_WXTIMER1 = 1001,
            ID_DUMMY_VALUE_
        };

        void OnClose(wxCloseEvent& event);
        void CreateGUIControls();

        DECLARE_EVENT_TABLE()
};

#endif // __wxPendulumDlg_h__


(ns pendulum
  (:import
    (javax.swing JFrame)
    (java.awt Canvas Graphics Color)))

(def length 200)
(def width (* 2 (+ 50 length)))
(def height (* 3 (/ length 2)))
(def dt 0.1)
(def g 9.812)
(def k (- (/ g length)))
(def anchor-x (/ width 2))
(def anchor-y (/ height 8))
(def angle (atom (/ (Math/PI) 2)))

(defn draw [#^Canvas canvas angle]
  (let [buffer  (.getBufferStrategy canvas)
        g       (.getDrawGraphics buffer)
        ball-x (+ anchor-x (* (Math/sin angle) length))
        ball-y (+ anchor-y (* (Math/cos angle) length))]
    (try
      (doto g
        (.setColor Color/BLACK)
        (.fillRect 0 0 width height)
        (.setColor Color/RED)
        (.drawLine anchor-x anchor-y ball-x ball-y)
        (.setColor Color/YELLOW)
        (.fillOval (- anchor-x 3) (- anchor-y 4) 7 7)
        (.fillOval (- ball-x 7) (- ball-y 7) 14 14))
      (finally (.dispose g)))
    (if-not (.contentsLost buffer)
      (.show buffer)) ))

(defn start-renderer [canvas]
  (->>
    (fn [] (draw canvas @angle) (recur))
    (new Thread)
    (.start)))

(defn -main [& args]
  (let [frame  (JFrame. "Pendulum")
        canvas (Canvas.)]

    (doto frame
      (.setSize width height)
      (.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
      (.setResizable false)
      (.add canvas)
      (.setVisible true))

    (doto canvas
      (.createBufferStrategy 2)
      (.setVisible true)
      (.requestFocus))

    (start-renderer canvas)

    (loop [v 0]
      (swap! angle #(+ % (* v dt)))
      (Thread/sleep 15)
      (recur (+ v (* k (Math/sin @angle) dt)))) ))

(-main)


(defvar *frame-rate* 30)
(defvar *damping* 0.99 "Deceleration factor.")

(defun make-pendulum (length theta0 x)
  "Returns an anonymous function with enclosed state representing a pendulum."
  (let* ((theta (* (/ theta0 180) pi))
         (acceleration 0))
    (if (< length 40) (setf length 40)) ;;avoid a divide-by-zero
    (lambda ()
      ;;Draws the pendulum, updating its location and speed.
      (sdl:draw-line (sdl:point :x x :y 1)
                     (sdl:point :x (+ (* (sin theta) length) x)
                                :y (* (cos theta) length)))
      (sdl:draw-filled-circle (sdl:point :x (+ (* (sin theta) length) x)
                                         :y (* (cos theta) length))
                              20
                              :color sdl:*yellow*
                              :stroke-color sdl:*white*)
      ;;The magic constant approximates the speed we want for a given frame-rate.
      (incf acceleration (* (sin theta) (* *frame-rate* -0.001)))
      (incf theta acceleration)
      (setf acceleration (* acceleration *damping*)))))

(defun main (&optional (w 640) (h 480))
  (sdl:with-init ()
    (sdl:window w h :title-caption "Pendulums"
                :fps (make-instance 'sdl:fps-fixed))
    (setf (sdl:frame-rate) *frame-rate*)
    (let ((pendulums nil))
      (sdl:with-events ()
        (:quit-event () t)
        (:idle ()
               (sdl:clear-display sdl:*black*)
               (mapcar #'funcall pendulums) ;;Draw all the pendulums

               (sdl:update-display))
        (:key-down-event (:key key)
                         (cond ((sdl:key= key :sdl-key-escape)
                                (sdl:push-quit-event))
                               ((sdl:key= key :sdl-key-space)
                                (push (make-pendulum (random (- h 100))
                                                     (random 90)
                                                     (round w 2))
                                      pendulums))))))))


unit main;

interface

uses
  Vcl.Forms, Vcl.Graphics, Vcl.ExtCtrls;

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
    procedure FormDestroy(Sender: TObject);
  private
    Timer: TTimer;
    angle, angleAccel, angleVelocity, dt: double;
    len: Integer;
    procedure Tick(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
begin
  Width := 200;
  Height := 200;
  DoubleBuffered := True;
  Timer := TTimer.Create(nil);
  Timer.Interval := 30;
  Timer.OnTimer := Tick;
  Caption := 'Pendulum';

  // initialize
  angle := PI / 2;
  angleAccel := 0;
  angleVelocity := 0;
  dt := 0.1;
  len := 50;
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
  Timer.Free;
end;

procedure TForm1.Tick(Sender: TObject);
const
  HalfPivot = 4;
  HalfBall = 7;
var
  anchorX, anchorY, ballX, ballY: Integer;
begin
  anchorX := Width div 2 - 12;
  anchorY := Height div 4;
  ballX := anchorX + Trunc(Sin(angle) * len);
  ballY := anchorY + Trunc(Cos(angle) * len);

  angleAccel := -9.81 / len * Sin(angle);
  angleVelocity := angleVelocity + angleAccel * dt;
  angle := angle + angleVelocity * dt;

  with canvas do
  begin
    Pen.Color := clBlack;

    with Brush do
    begin
      Style := bsSolid;
      Color := clWhite;
    end;

    FillRect(ClientRect);
    MoveTo(anchorX, anchorY);
    LineTo(ballX, ballY);

    Brush.Color := clGray;
    Ellipse(anchorX - HalfPivot, anchorY - HalfPivot, anchorX + HalfPivot,
      anchorY + HalfPivot);

    Brush.Color := clYellow;
    Ellipse(ballX - HalfBall, ballY - HalfBall, ballX + HalfBall, ballY + HalfBall);
  end;
end;

end.


#!/usr/bin/env rune
pragma.syntax("0.9")

def pi := (-1.0).acos()
def makeEPainter := <unsafe:com.zooko.tray.makeEPainter>
def makeLamportSlot := <import:org.erights.e.elib.slot.makeLamportSlot>
def whenever := <import:org.erights.e.elib.slot.whenever>
def colors := <import:java.awt.makeColor>

# --------------------------------------------------------------
# --- Definitions

def makePendulumSim(length_m :float64,
                    gravity_mps2 :float64,
                    initialAngle_rad :float64,
                    timestep_ms :int) {
  var velocity := 0
  def &angle := makeLamportSlot(initialAngle_rad)
  def k := -gravity_mps2/length_m
  def timestep_s := timestep_ms / 1000
  def clock := timer.every(timestep_ms, fn _ {
    def acceleration := k * angle.sin()
    velocity += acceleration * timestep_s
    angle    += velocity     * timestep_s
  })
  return [clock, &angle]
}

def makeDisplayComponent(&angle) {
  def c
  def updater := whenever([&angle], fn { c.repaint() })

  bind c := makeEPainter(def paintCallback {
    to paintComponent(g) {
      try {
        def originX := c.getWidth() // 2
        def originY := c.getHeight() // 2
        def pendRadius := (originX.min(originY) * 0.95).round()
        def ballRadius := (originX.min(originY) * 0.04).round()
        def ballX := (originX + angle.sin() * pendRadius).round()
        def ballY := (originY + angle.cos() * pendRadius).round()

        g.setColor(colors.getWhite())
        g.fillRect(0, 0, c.getWidth(), c.getHeight())
        g.setColor(colors.getBlack())

        g.fillOval(originX - 2, originY - 2, 4, 4)
        g.drawLine(originX, originY, ballX, ballY)
        g.fillOval(ballX - ballRadius, ballY - ballRadius, ballRadius * 2, ballRadius * 2)

        updater[] # provoke interest provided that we did get drawn (window not closed)
      } catch p {
        stderr.println(`In paint callback: $p${p.eStack()}`)
      }
    }
  })

  c.setPreferredSize(<awt:makeDimension>(300, 300))
  return c
}

# --------------------------------------------------------------
# --- Application setup

def [clock, &angle] := makePendulumSim(1, 9.80665, pi*99/100, 10)

# Initialize AWT, move to AWT event thread
when (currentVat.morphInto("awt")) -> {

  # Create the window
  def frame := <unsafe:javax.swing.makeJFrame>("Pendulum")
  frame.setContentPane(def display := makeDisplayComponent(&angle))
  frame.addWindowListener(def mainWindowListener {
    to windowClosing(_) {
      clock.stop()
      interp.continueAtTop()
    }
    match _ {}
  })
  frame.setLocation(50, 50)
  frame.pack()

  # Start and become visible
  frame.show()
  clock.start()
}

interp.blockAtTop()


on animate
  clear
  move 50 50
  circle 1
  x = 50 + 40 * sin ang
  y = 50 - 40 * cos ang
  line x y
  circle 5
  vel += sin ang / 5
  ang += vel
.
ang = 45


import Color exposing (..)
import Collage exposing (..)
import Element exposing (..)
import Html exposing (..)
import Time exposing (..)
import Html.App exposing (program)

dt = 0.01
scale = 100

type alias Model =
  { angle : Float
  , angVel : Float
  , length : Float
  , gravity : Float
  }

type Msg
    = Tick Time

init : (Model,Cmd Msg)
init =
  ( { angle = 3 * pi / 4
    , angVel = 0.0
    , length = 2
    , gravity = -9.81
    }
  , Cmd.none)

update : Msg -> Model -> (Model, Cmd Msg)
update _ model =
  let
    angAcc = -1.0 * (model.gravity / model.length) * sin (model.angle)
    angVel' = model.angVel + angAcc * dt
    angle' = model.angle + angVel' * dt
  in
    ( { model
        | angle = angle'
        , angVel = angVel'
      }
    , Cmd.none )

view : Model -> Html Msg
view model =
  let
    endPoint = ( 0, scale * model.length )
    pendulum =
      group
        [ segment ( 0, 0 ) endPoint
            |> traced { defaultLine | width = 2, color = red }
        , circle 8
            |> filled blue
        , ngon 3 10
            |> filled green
            |> rotate (pi/2)
            |> move endPoint
        ]
  in
    toHtml <|
      collage 700 500
        [ pendulum |> rotate model.angle ]

subscriptions : Model -> Sub Msg
subscriptions _ =
    Time.every (dt * second) Tick

main =
  program
      { init = init
      , view = view
      , update = update
      , subscriptions = subscriptions
      }


PROGRAM PENDULUM

!
! for rosettacode.org
!

!$KEY

!$INCLUDE="PC.LIB"

PROCEDURE PENDULUM(A,L)
      PIVOTX=320
      PIVOTY=0
      BOBX=PIVOTX+L*500*SIN(a)
      BOBY=PIVOTY+L*500*COS(a)
      LINE(PIVOTX,PIVOTY,BOBX,BOBY,6,FALSE)
      CIRCLE(BOBX+24*SIN(A),BOBY+24*COS(A),27,11)
      PAUSE(0.01)
      LINE(PIVOTX,PIVOTY,BOBX,BOBY,0,FALSE)
      CIRCLE(BOBX+24*SIN(A),BOBY+24*COS(A),27,0)
END PROCEDURE

BEGIN
      SCREEN(9)
      THETA=40*p/180     ! initial displacement
      G=9.81             ! acceleration due to gravity
      L=0.5              ! length of pendulum in metres
      LINE(0,0,639,0,5,FALSE)
      LOOP
        PENDULUM(THETA,L)
        ACCEL=-G*SIN(THETA)/L/100
        SPEED=SPEED+ACCEL/100
        THETA=THETA+SPEED
      END LOOP
END PROGRAM


>g=gearth$; l=1m;
>function f(x,y) := [y[2],-g*sin(y[1])/l]
>function h(a) := ode("f",linspace(0,a,100),[0,2])[1,-1]
>period=solve("h",2)
 2.06071780729
>t=linspace(0,period,30); s=ode("f",t,[0,2])[1];
>function anim (t,s) ...
$  setplot(-1,1,-1,1);
$  markerstyle("o#");
$  repeat
$  for i=1 to cols(t)-1;
$    clg;
$    hold on;
$    plot([0,sin(s[i])],[1,1-cos(s[i])]);
$    mark([0,sin(s[i])],[1,1-cos(s[i])]);
$    hold off;
$    wait(t[i+1]-t[i]);
$  end;
$  until testkey();
$  end
$endfunction
>anim(t,s);
>


include graphics.e
include misc.e

constant dt = 1E-3
constant g = 50

sequence vc
sequence suspension
atom len

procedure draw_pendulum(atom color, atom len, atom alfa)
    sequence point
    point = (len*{sin(alfa),cos(alfa)} + suspension)
    draw_line(color, {suspension, point})
    ellipse(color,0,point-{10,10},point+{10,10})
end procedure

function wait()
    atom t0
    t0 = time()
    while time() = t0 do
        if get_key() != -1 then
            return 1
        end if
    end while
    return 0
end function

procedure animation()
    atom alfa, omega, epsilon

    if graphics_mode(18) then
    end if

    vc = video_config()
    suspension = {vc[VC_XPIXELS]/2,vc[VC_YPIXELS]/2}
    len = vc[VC_YPIXELS]/2-20

    alfa = PI/2
    omega = 0

    while 1 do
        draw_pendulum(BRIGHT_WHITE,len,alfa)
        if wait() then
            exit
        end if
        draw_pendulum(BLACK,len,alfa)
        epsilon = -len*sin(alfa)*g
        omega += dt*epsilon
        alfa += dt*omega
    end while

    if graphics_mode(-1) then
    end if
end procedure

animation()


open System
open System.Drawing
open System.Windows.Forms

// define units of measurement
[<Measure>] type m;  // metres
[<Measure>] type s;  // seconds

// a pendulum is represented as a record of physical quantities
type Pendulum =
 { length   : float<m>
   gravity  : float<m/s^2>
   velocity : float<m/s>
   angle    : float
 }

// calculate the next state of a pendulum
let next pendulum deltaT : Pendulum =
  let k = -pendulum.gravity / pendulum.length
  let acceleration = k * Math.Sin pendulum.angle * 1.0<m>
  let newVelocity = pendulum.velocity + acceleration * deltaT
  let newAngle = pendulum.angle + newVelocity * deltaT / 1.0<m>
  { pendulum with velocity = newVelocity; angle = newAngle }

// paint a pendulum (using hard-coded screen coordinates)
let paint pendulum (gr: System.Drawing.Graphics) =
  let homeX = 160
  let homeY = 50
  let length = 140.0
  // draw plate
  gr.DrawLine( new Pen(Brushes.Gray, width=2.0f), 0, homeY, 320, homeY )
  // draw pivot
  gr.FillEllipse( Brushes.Gray,           homeX-5, homeY-5, 10, 10 )
  gr.DrawEllipse( new Pen(Brushes.Black), homeX-5, homeY-5, 10, 10 )
  // draw the pendulum itself
  let x = homeX + int( length * Math.Sin pendulum.angle )
  let y = homeY + int( length * Math.Cos pendulum.angle )
  // draw rod
  gr.DrawLine( new Pen(Brushes.Black, width=3.0f), homeX, homeY, x, y )
  // draw bob
  gr.FillEllipse( Brushes.Yellow,         x-15, y-15, 30, 30 )
  gr.DrawEllipse( new Pen(Brushes.Black), x-15, y-15, 30, 30 )

// defines an operator "-?" that calculates the time from t2 to t1
// where t2 is optional
let (-?) (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>

// our main window is double-buffered form that reacts to paint events
type PendulumForm() as self =
  inherit Form(Width=325, Height=240, Text="Pendulum")
  let mutable pendulum = { length   = 1.0<m>;
                           gravity  = 9.81<m/s^2>
                           velocity = 0.0<m/s>
                           angle    = Math.PI / 2.0
                         }
  let mutable lastPaintedAt = None
  let updateFreq = 0.01<s>

  do self.DoubleBuffered <- true
     self.Paint.Add( fun args ->
       let now = DateTime.Now
       let deltaT = now -? lastPaintedAt |> min 0.01<s>
       lastPaintedAt <- Some now

       pendulum <- next pendulum deltaT

       let gr = args.Graphics
       gr.Clear( Color.LightGray )
       paint pendulum gr

       // initiate a new paint event after a while (non-blocking)
       async { do! Async.Sleep( int( 1000.0 * updateFreq / 1.0<s> ) )
               self.Invalidate()
            }
       |> Async.Start
     )

[<STAThread>]
Application.Run( new PendulumForm( Visible=true ) )


USING: accessors alarms arrays calendar colors.constants kernel
locals math math.constants math.functions math.rectangles
math.vectors opengl sequences system ui ui.gadgets ui.render ;
IN: pendulum

CONSTANT: g 9.81
CONSTANT: l 20
CONSTANT: theta0 0.5

: current-time ( -- time ) nano-count -9 10^ * ;

: T0 ( -- T0 ) 2 pi l g / sqrt * * ;
: omega0 ( -- omega0 ) 2 pi * T0 / ;
: theta ( -- theta ) current-time omega0 * cos theta0 * ;

: relative-xy ( theta l -- xy )
    swap [ sin * ] [ cos * ] 2bi 2array ;
: theta-to-xy ( origin theta l -- xy ) relative-xy v+ ;

TUPLE: pendulum-gadget < gadget alarm ;

: O ( gadget -- origin ) rect-bounds [ drop ] [ first 2 / ] bi* 0 2array ;
: window-l ( gadget -- l ) rect-bounds [ drop ] [ second ] bi* ;
: gadget-xy ( gadget -- xy ) [ O ] [ drop theta ] [ window-l ] tri theta-to-xy ;

M: pendulum-gadget draw-gadget*
    COLOR: black gl-color
    [ O ] [ gadget-xy ] bi gl-line ;

M:: pendulum-gadget graft* ( gadget -- )
    [ gadget relayout-1 ]
    20 milliseconds every gadget (>>alarm) ;
M: pendulum-gadget ungraft* alarm>> cancel-alarm ;

: <pendulum-gadget> ( -- gadget )
    pendulum-gadget new
    { 500 500 } >>pref-dim ;
: pendulum-main ( -- )
    [ <pendulum-gadget> "pendulum" open-window ] with-ui ;
MAIN: pendulum-main


#INCLUDE <Include\Windows.inc>

FBSLSETTEXT(ME, "Pendulum")
FBSL.SETTIMER(ME, 1000, 10)
RESIZE(ME, 0, 0, 300, 200)
CENTER(ME)
SHOW(ME)

BEGIN EVENTS
	SELECT CASE CBMSG
		CASE WM_TIMER
			' Request redraw
			InvalidateRect(ME, NULL, FALSE)
			RETURN 0
		CASE WM_PAINT
			Swing()
		CASE WM_CLOSE
			FBSL.KILLTIMER(ME, 1000)
	END SELECT
END EVENTS

SUB Swing()
	TYPE RECT: %rcLeft, %rcTop, %rcRight, %rcBottom: END TYPE
	STATIC rc AS RECT, !!acceleration, !!velocity, !!angle = M_PI_2, %pendulum = 100

	GetClientRect(ME, @rc)

	' Recalculate
	DIM headX = rc.rcRight / 2, headY = rc.rcBottom / 4
	DIM tailX = headX + SIN(angle) * pendulum
	DIM tailY = headY + COS(angle) * pendulum

	acceleration = -9.81 / pendulum * SIN(angle)
	INCR(velocity, acceleration * 0.1)(angle, velocity * 0.1)

	' Create backbuffer
	CreateCompatibleDC(GetDC(ME))
	SelectObject(CreateCompatibleDC, CreateCompatibleBitmap(GetDC, rc.rcRight, rc.rcBottom))

	' Draw to backbuffer
	FILLSTYLE(FILL_SOLID): FILLCOLOR(RGB(200, 200, 0))
	LINE(CreateCompatibleDC, 0, 0, rc.rcRight, rc.rcBottom, GetSysColor(COLOR_BTNHILIGHT), TRUE, TRUE)
	LINE(CreateCompatibleDC, 0, headY, rc.rcRight, headY, GetSysColor(COLOR_3DSHADOW))
	DRAWWIDTH(3)
	LINE(CreateCompatibleDC, headX, headY, tailX, tailY, RGB(200, 0, 0))
	DRAWWIDTH(1)
	CIRCLE(CreateCompatibleDC, headX, headY, 2, GetSysColor, 0, 360, 1, TRUE)
	CIRCLE(CreateCompatibleDC, tailX, tailY, 10, GetSysColor, 0, 360, 1, FALSE)

	' Blit to window
	BitBlt(GetDC, 0, 0, rc.rcRight, rc.rcBottom, CreateCompatibleDC, 0, 0, SRCCOPY)
	ReleaseDC(ME, GetDC)

	' Delete backbuffer
	DeleteObject(SelectObject(CreateCompatibleDC, SelectObject))
	DeleteDC(CreateCompatibleDC)
END SUB


!Implemented by Anant Dixit (October, 2014)
program animated_pendulum
implicit none
double precision, parameter :: pi = 4.0D0*atan(1.0D0), l = 1.0D-1, dt = 1.0D-2, g = 9.8D0
integer :: io
double precision :: s_ang, c_ang, p_ang, n_ang

write(*,*) 'Enter starting angle (in degrees):'
do
  read(*,*,iostat=io) s_ang
  if(io.ne.0 .or. s_ang.lt.-90.0D0 .or. s_ang.gt.90.0D0) then
    write(*,*) 'Please enter an angle between 90 and -90 degrees:'
  else
    exit
  end if
end do
call execute_command_line('cls')

c_ang = s_ang*pi/180.0D0
p_ang = c_ang

call display(c_ang)
do
  call next_time_step(c_ang,p_ang,g,l,dt,n_ang)
  if(abs(c_ang-p_ang).ge.0.05D0) then
    call execute_command_line('cls')
    call display(c_ang)
  end if
end do
end program

subroutine next_time_step(c_ang,p_ang,g,l,dt,n_ang)
double precision :: c_ang, p_ang, g, l, dt, n_ang
n_ang = (-g*sin(c_ang)/l)*2.0D0*dt**2 + 2.0D0*c_ang - p_ang
p_ang = c_ang
c_ang = n_ang
end subroutine

subroutine display(c_ang)
double precision :: c_ang
character (len=*), parameter :: cfmt = '(A1)'
double precision :: rx, ry
integer :: x, y, i, j
rx = 45.0D0*sin(c_ang)
ry = 22.5D0*cos(c_ang)
x = int(rx)+51
y = int(ry)+2
do i = 1,32
  do j = 1,100
    if(i.eq.y .and. j.eq.x) then
      write(*,cfmt,advance='no') 'O'
    else if(i.eq.y .and. (j.eq.(x-1).or.j.eq.(x+1))) then
      write(*,cfmt,advance='no') 'G'
    else if(j.eq.x .and. (i.eq.(y-1).or.i.eq.(y+1))) then
      write(*,cfmt,advance='no') 'G'
    else if(i.eq.y .and. (j.eq.(x-2).or.j.eq.(x+2))) then
      write(*,cfmt,advance='no') '#'
    else if(j.eq.x .and. (i.eq.(y-2).or.i.eq.(y+2))) then
      write(*,cfmt,advance='no') 'G'
    else if((i.eq.(y+1).and.j.eq.(x+1)) .or. (i.eq.(y-1).and.j.eq.(x-1))) then
      write(*,cfmt,advance='no') '#'
    else if((i.eq.(y+1).and.j.eq.(x-1)) .or. (i.eq.(y-1).and.j.eq.(x+1))) then
      write(*,cfmt,advance='no') '#'
    else if(j.eq.50) then
      write(*,cfmt,advance='no') '|'
    else if(i.eq.2) then
      write(*,cfmt,advance='no') '-'
    else
      write(*,cfmt,advance='no') ' '
    end if
  end do
  write(*,*)
end do
end subroutine


import java.awt.*;
import javax.swing.*;

class Pendulum extends JPanel implements Runnable {

    private angle = Math.PI / 2;
    private length;

    Pendulum(length) {
        this.length = length;
        setDoubleBuffered(true);
    }

    @Override
    void paint(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.BLACK);
        int anchorX = getWidth() / 2, anchorY = getHeight() / 4;
        def ballX = anchorX + (Math.sin(angle) * length) as int;
        def ballY = anchorY + (Math.cos(angle) * length) as int;
        g.drawLine(anchorX, anchorY, ballX, ballY);
        g.fillOval(anchorX - 3, anchorY - 4, 7, 7);
        g.fillOval(ballX - 7, ballY - 7, 14, 14);
    }

    void run() {
        def angleAccel, angleVelocity = 0, dt = 0.1;
        while (true) {
            angleAccel = -9.81 / length * Math.sin(angle);
            angleVelocity += angleAccel * dt;
            angle += angleVelocity * dt;
            repaint();
            try { Thread.sleep(15); } catch (InterruptedException ex) {}
        }
    }

    @Override
    Dimension getPreferredSize() {
        return new Dimension(2 * length + 50, (length / 2 * 3) as int);
    }

    static void main(String[] args) {
        def f = new JFrame("Pendulum");
        def p = new Pendulum(200);
        f.add(p);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
        new Thread(p).start();
    }
}


package main

import (
	"github.com/google/gxui"
	"github.com/google/gxui/drivers/gl"
	"github.com/google/gxui/math"
	"github.com/google/gxui/themes/dark"
	omath "math"
	"time"
)

//Two pendulums animated
//Top: Mathematical pendulum with small-angle approxmiation (not appropiate with PHI_ZERO=pi/2)
//Bottom: Simulated with differential equation phi'' = g/l * sin(phi)

const (
	ANIMATION_WIDTH  int     = 480
	ANIMATION_HEIGHT int     = 320
	BALL_RADIUS      float32 = 25.0
	METER_PER_PIXEL  float64 = 1.0 / 20.0
	PHI_ZERO         float64 = omath.Pi * 0.5
)

var (
	l    float64 = float64(ANIMATION_HEIGHT) * 0.5
	freq float64 = omath.Sqrt(9.81 / (l * METER_PER_PIXEL))
)

type Pendulum interface {
	GetPhi() float64
}

type mathematicalPendulum struct {
	start time.Time
}

func (p *mathematicalPendulum) GetPhi() float64 {
	if (p.start == time.Time{}) {
		p.start = time.Now()
	}
	t := float64(time.Since(p.start).Nanoseconds()) / omath.Pow10(9)
	return PHI_ZERO * omath.Cos(t*freq)
}

type numericalPendulum struct {
	currentPhi float64
	angAcc     float64
	angVel     float64
	lastTime   time.Time
}

func (p *numericalPendulum) GetPhi() float64 {
	dt := 0.0
	if (p.lastTime != time.Time{}) {
		dt = float64(time.Since(p.lastTime).Nanoseconds()) / omath.Pow10(9)
	}
	p.lastTime = time.Now()

	p.angAcc = -9.81 / (float64(l) * METER_PER_PIXEL) * omath.Sin(p.currentPhi)
	p.angVel += p.angAcc * dt
	p.currentPhi += p.angVel * dt

	return p.currentPhi
}

func draw(p Pendulum, canvas gxui.Canvas, x, y int) {
	attachment := math.Point{X: ANIMATION_WIDTH/2 + x, Y: y}

	phi := p.GetPhi()
	ball := math.Point{X: x + ANIMATION_WIDTH/2 + math.Round(float32(l*omath.Sin(phi))), Y: y + math.Round(float32(l*omath.Cos(phi)))}

	line := gxui.Polygon{gxui.PolygonVertex{attachment, 0}, gxui.PolygonVertex{ball, 0}}

	canvas.DrawLines(line, gxui.DefaultPen)

	m := math.Point{int(BALL_RADIUS), int(BALL_RADIUS)}
	rect := math.Rect{ball.Sub(m), ball.Add(m)}
	canvas.DrawRoundedRect(rect, BALL_RADIUS, BALL_RADIUS, BALL_RADIUS, BALL_RADIUS, gxui.TransparentPen, gxui.CreateBrush(gxui.Yellow))
}

func appMain(driver gxui.Driver) {
	theme := dark.CreateTheme(driver)

	window := theme.CreateWindow(ANIMATION_WIDTH, 2*ANIMATION_HEIGHT, "Pendulum")
	window.SetBackgroundBrush(gxui.CreateBrush(gxui.Gray50))

	image := theme.CreateImage()

	ticker := time.NewTicker(time.Millisecond * 15)
	pendulum := &mathematicalPendulum{}
	pendulum2 := &numericalPendulum{PHI_ZERO, 0.0, 0.0, time.Time{}}

	go func() {
		for _ = range ticker.C {
			canvas := driver.CreateCanvas(math.Size{ANIMATION_WIDTH, 2 * ANIMATION_HEIGHT})
			canvas.Clear(gxui.White)

			draw(pendulum, canvas, 0, 0)
			draw(pendulum2, canvas, 0, ANIMATION_HEIGHT)

			canvas.Complete()
			driver.Call(func() {
				image.SetCanvas(canvas)
			})
		}
	}()

	window.AddChild(image)

	window.OnClose(ticker.Stop)
	window.OnClose(driver.Terminate)
}

func main() {
	gl.StartDriver(appMain)
}


import Graphics.HGL.Draw.Monad (Graphic, )
import Graphics.HGL.Draw.Picture
import Graphics.HGL.Utils
import Graphics.HGL.Window
import Graphics.HGL.Run

import Control.Exception (bracket, )
import Control.Arrow

toInt = fromIntegral.round

pendulum = runGraphics $
  bracket
    (openWindowEx "Pendulum animation task" Nothing (600,400) DoubleBuffered (Just 30))
    closeWindow
    (\w -> mapM_ ((\ g -> setGraphic w g >> getWindowTick w).
                    (\ (x, y) -> overGraphic (line (300, 0) (x, y))
                                    (ellipse (x - 12, y + 12) (x + 12, y - 12)) )) pts)
 where
    dt = 1/30
    t = - pi/4
    l = 1
    g = 9.812
    nextAVT (a,v,t) = (a', v', t + v' * dt) where
        a' = - (g / l) * sin t
        v' = v + a' * dt
    pts = map (\(_,t,_) -> (toInt.(300+).(300*).cos &&& toInt. (300*).sin) (pi/2+0.6*t) )
        $ iterate nextAVT (- (g / l) * sin t, t, 0)


REAL :: msec=10, Lrod=1, dBob=0.03, g=9.81, Theta(2), dTheta(2)
BobMargins = ALIAS(ls, rs, ts, bs) ! box margins to draw the bob

Theta = (1, 0)        ! initial angle and velocity
start_t = TIME()

DO i = 1, 1E100       ! "forever"
   end_t = TIME()     ! to integrate in real-time sections:
   DIFFEQ(Callback="pendulum", T=end_t, Y=Theta, DY=dTheta, T0=start_t)
   xBob = (SIN(Theta(1)) + 1) / 2
   yBob = COS(Theta(1)) - dBob

   ! create or clear window and draw pendulum bob at (xBob, yBob):
   WINDOW(WIN=wh, LeftSpace=0, RightSpace=0, TopSpace=0, BottomSpace=0, Up=999)
   BobMargins = (xBob-dBob, 1-xBob-dBob, yBob-dBob, 1-yBob-dBob)
   WINDOW(WIN=wh, LeftSpace=ls, RightSpace=rs, TopSpace=ts, BottomSpace=bs)
   WRITE(WIN=wh, DeCoRation='EL=4, BC=4') ! flooded red ellipse as bob

   ! draw the rod hanging from the center of the window:
   WINDOW(WIN=wh, LeftSpace=0.5, TopSpace=0, RightSpace=rs+dBob)
   WRITE(WIN=wh, DeCoRation='LI=0 0; 1 1, FC=4.02') ! red pendulum rod

   SYSTEM(WAIT=msec)
   start_t = end_t
ENDDO

END

SUBROUTINE pendulum                 ! Theta" = - (g/Lrod) * SIN(Theta)
  dTheta(1) = Theta(2)              ! Theta' = Theta(2)  substitution
  dTheta(2) = -g/Lrod*SIN(Theta(1)) ! Theta" = Theta(2)' = -g/Lrod*SIN(Theta(1))
END


import gui
$include "guih.icn"

# some constants to define the display and pendulum
$define HEIGHT 400
$define WIDTH 500
$define STRING_LENGTH 200
$define HOME_X 250
$define HOME_Y 21
$define SIZE 30
$define START_ANGLE 80

class WindowApp : Dialog ()

  # draw the pendulum on given context_window, at position (x,y)
  method draw_pendulum (x, y)
    # reference to current screen area to draw on
    cw := Clone(self.cwin)

    # clear screen
    WAttrib (cw, "bg=grey")
    EraseRectangle (cw, 0, 0, WIDTH, HEIGHT)

    # draw the display
    WAttrib (cw, "fg=dark gray")
    DrawLine (cw, 10, 20, WIDTH-20, 20)
    WAttrib (cw, "fg=black")
    DrawLine (cw, HOME_X, HOME_Y, x, y)
    FillCircle (cw, x, y, SIZE+2)
    WAttrib (cw, "fg=yellow")
    FillCircle (cw, x, y, SIZE)

    # free reference to screen area
    Uncouple (cw)
  end

  # find the average of given two arguments
  method avg (a, b)
    return (a + b) / 2
  end

  # this method gets called by the ticker
  # it computes the next position of the pendulum and
  # requests a redraw
  method tick ()
    static x, y
    static theta := START_ANGLE
    static d_theta := 0
    # update x,y of pendulum
    scaling := 3000.0 / (STRING_LENGTH * STRING_LENGTH)
    # -- first estimate
    first_dd_theta := -(sin (dtor (theta)) * scaling)
    mid_d_theta := d_theta + first_dd_theta
    mid_theta := theta + avg (d_theta, mid_d_theta)
    # -- second estimate
    mid_dd_theta := - (sin (dtor (mid_theta)) * scaling)
    mid_d_theta_2 := d_theta + avg (first_dd_theta, mid_dd_theta)
    mid_theta_2 := theta + avg (d_theta, mid_d_theta_2)
    # -- again first
    mid_dd_theta_2 := -(sin (dtor (mid_theta_2)) * scaling)
    last_d_theta := mid_d_theta_2 + mid_dd_theta_2
    last_theta := mid_theta_2 + avg (mid_d_theta_2, last_d_theta)
    # -- again second
    last_dd_theta := - (sin (dtor (last_theta)) * scaling)
    last_d_theta_2 := mid_d_theta_2 + avg (mid_dd_theta_2, last_dd_theta)
    last_theta_2 := mid_theta_2 + avg (mid_d_theta_2, last_d_theta_2)
    # -- update stored angles
    d_theta := last_d_theta_2
    theta := last_theta_2
    # -- update x, y
    pendulum_angle := dtor (theta)
    x := HOME_X + STRING_LENGTH * sin (pendulum_angle)
    y := HOME_Y + STRING_LENGTH * cos (pendulum_angle)

    # draw pendulum
    draw_pendulum (x, y)
  end

  # set up the window
  method 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)
  end
end

procedure main ()
  w := WindowApp ()
  w.show_modal ()
end


require 'gl2 trig'
coinsert 'jgl2'

DT   =: %30      NB. seconds
ANGLE=: 0.45p1   NB. radians
L    =: 1        NB. metres
G    =: 9.80665  NB. ms_2
VEL  =: 0        NB. ms_1

PEND=: noun define
pc pend;pn "Pendulum";
xywh 0 0 320 200;cc isi isigraph rightmove bottommove;
pas 0 0;pcenter;
rem form end;
)

pend_run      =: verb def ' wd PEND,'';pshow;timer '',":DT * 1000 '
pend_close    =: verb def ' wd ''timer 0; pclose'' '
pend_isi_paint=: verb def ' drawPendulum ANGLE '

sys_timer_z_=: verb define
  recalcAngle ''
  wd 'psel pend; setinvalid isi'
)

recalcAngle=: verb define
  accel=. - (G % L) * sin ANGLE
  VEL  =: VEL + accel * DT
  ANGLE=: ANGLE + VEL * DT
)

drawPendulum=: verb define
  width=. {. glqwh''
  ps=. (-: width) , 40
  pe=. ps + 280 <[email protected]* (cos , sin) 0.5p1 + y    NB. adjust orientation
  glbrush glrgb 91 91 91
  gllines ps , pe
  glellipse (,~ ps - -:) 40 15
  glellipse (,~ pe - -:) 20 20
  glrect 0 0 ,width, 40
)

pend_run''                                    NB. run animation


import java.awt.*;
import javax.swing.*;

public class Pendulum extends JPanel implements Runnable {

    private double angle = Math.PI / 2;
    private int length;

    public Pendulum(int length) {
        this.length = length;
        setDoubleBuffered(true);
    }

    @Override
    public void paint(Graphics g) {
        g.setColor(Color.WHITE);
        g.fillRect(0, 0, getWidth(), getHeight());
        g.setColor(Color.BLACK);
        int anchorX = getWidth() / 2, anchorY = getHeight() / 4;
        int ballX = anchorX + (int) (Math.sin(angle) * length);
        int ballY = anchorY + (int) (Math.cos(angle) * length);
        g.drawLine(anchorX, anchorY, ballX, ballY);
        g.fillOval(anchorX - 3, anchorY - 4, 7, 7);
        g.fillOval(ballX - 7, ballY - 7, 14, 14);
    }

    public void run() {
        double angleAccel, angleVelocity = 0, dt = 0.1;
        while (true) {
            angleAccel = -9.81 / length * Math.sin(angle);
            angleVelocity += angleAccel * dt;
            angle += angleVelocity * dt;
            repaint();
            try { Thread.sleep(15); } catch (InterruptedException ex) {}
        }
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(2 * length + 50, length / 2 * 3);
    }

    public static void main(String[] args) {
        JFrame f = new JFrame("Pendulum");
        Pendulum p = new Pendulum(200);
        f.add(p);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
        new Thread(p).start();
    }
}


  <title>Pendulum</title>

<canvas id="canvas" width="600" height="600">

Sorry, your browser does not support the <canvas> used to display the pendulum animation.

</canvas>


using Luxor
using Colors
using BoundaryValueDiffEq

# constants for differential equations and movie
const g = 9.81
const L = 1.0                         # pendulum length in meters
const bobd = 0.10                     # pendulum bob diameter in meters
const framerate = 50.0                # intended frame rate/sec
const t0 = 0.0                        # start time (s)
const tf = 2.3                        # end simulation time (s)
const dtframe = 1.0/framerate         # time increment per frame
const tspan = LinRange(t0, tf, Int(floor(tf*framerate)))  # array of time points in animation

const bgcolor = "black"               # gif background
const leaderhue = (0.80, 0.70, 0.20)  # gif swing arm hue light gold
const hslcolors = [HSL(col) for col in (distinguishable_colors(
                   Int(floor(tf*framerate)+3),[RGB(1,1,1)])[2:end])]
const giffilename = "pendulum.gif"    # output file

# differential equations
simplependulum(du, u, p, t) = (θ=u[1]; dθ=u[2]; du[1]=dθ; du[2]=-(g/L)*sin(θ))
bc2(residual, u, p, t) = (residual[1] = u[end÷2][1] + pi/2; residual[2] = u[end][1] - pi/2)
bvp2 = BVProblem(simplependulum, bc2, [pi/2,pi/2], (tspan[1],tspan[end]))
sol2 = solve(bvp2, MIRK4(), dt=dtframe) # use the MIRK4 solver for TwoPointBVProblem

# movie making background
backdrop(scene, framenumber) = background(bgcolor)

function frame(scene, framenumber)
    u1, u2 = sol2.u[framenumber]
    y, x = L*cos(u1), L*sin(u1)
    sethue(leaderhue)
    poly([Point(-4.0, 0.0), Point(4.0, 0.0),
          Point(160.0x,160.0y)], :fill)
    sethue(Colors.HSV(framenumber*4.0, 1, 1))
    circle(Point(160.0x,160.0y), 160bobd, :fill)
    text(string("frame $framenumber of $(scene.framerange.stop)"),
        Point(0.0, -190.0),
        halign=:center)
end

muv = Movie(400, 400, "Pendulum Demo", 1:length(tspan))
animate(muv, [Scene(muv, backdrop),
              Scene(muv, frame, easingfunction=easeinoutcubic)],
              creategif=true, pathname=giffilename)


import java.awt.*
import java.util.concurrent.*
import javax.swing.*

class Pendulum(private val length: Int) : JPanel(), Runnable {
    init {
        val f = JFrame("Pendulum")
        f.add(this)
        f.defaultCloseOperation = JFrame.EXIT_ON_CLOSE
        f.pack()
        f.isVisible = true
        isDoubleBuffered = true
    }

    override fun paint(g: Graphics) {
        with(g) {
            color = Color.WHITE
            fillRect(0, 0, width, height)
            color = Color.BLACK
            val anchor = Element(width / 2, height / 4)
            val ball = Element((anchor.x + Math.sin(angle) * length).toInt(), (anchor.y + Math.cos(angle) * length).toInt())
            drawLine(anchor.x, anchor.y, ball.x, ball.y)
            fillOval(anchor.x - 3, anchor.y - 4, 7, 7)
            fillOval(ball.x - 7, ball.y - 7, 14, 14)
        }
    }

    override fun run() {
        angleVelocity += -9.81 / length * Math.sin(angle) * dt
        angle += angleVelocity * dt
        repaint()
    }

    override fun getPreferredSize() = Dimension(2 * length + 50, length / 2 * 3)

    private data class Element(val x: Int, val y: Int)

    private val dt = 0.1
    private var angle = Math.PI / 2
    private var angleVelocity = 0.0
}

fun main(a: Array<String>) {
    val executor = Executors.newSingleThreadScheduledExecutor()
    executor.scheduleAtFixedRate(Pendulum(200), 0, 15, TimeUnit.MILLISECONDS)
}


nomainwin
    WindowWidth = 400
    WindowHeight = 300

    open "Pendulum" for graphics_nsb_nf as #main
    #main "down;fill white; flush"
    #main "color black"
    #main "trapclose [quit.main]"

    Angle = asn(1)
    DeltaT = 0.1
    PendLength = 150
    FixX = int(WindowWidth / 2)
    FixY = 40

    timer 30, [swing]

    wait

[swing]

    #main "cls"
    #main "discard"

    PlumbobX = FixX + int(sin(Angle) * PendLength)
    PlumbobY = FixY + int(cos(Angle) * PendLength)
    AngAccel = -9.81 / PendLength * sin(Angle)
    AngVelocity = AngVelocity + AngAccel * DeltaT
    Angle = Angle + AngVelocity * DeltaT

    #main "backcolor black"
    #main "place ";FixX;" ";FixY
    #main "circlefilled 3"
    #main "line ";FixX;" ";FixY;" ";PlumbobX;" ";PlumbobY
    #main "backcolor red"
    #main "circlefilled 10"

    wait

[quit.main]
    close #main
    end


global RODLEN, GRAVITY, DT
global velocity, acceleration, angle, posX, posY

on startMovie

    -- window properties
    _movie.stage.title = "Pendulum"
    _movie.stage.titlebarOptions.visible = TRUE
    _movie.stage.rect = rect(0, 0, 400, 400)
    _movie.centerStage = TRUE
    _movie.puppetTempo(30)

    RODLEN = 180
    GRAVITY = -9.8
    DT = 0.03

    velocity = 0.0
    acceleration = 0.0
    angle = PI/3
    posX = 200 - sin(angle) * RODLEN
    posY = 100 + cos(angle) * RODLEN
    paint()

    -- show the window
    _movie.stage.visible = TRUE
end

on enterFrame
    acceleration = GRAVITY * sin(angle)
    velocity = velocity + acceleration * DT
    angle = angle + velocity * DT
    posX = 200 - sin(angle) * rodLen
    posY = 100 + cos(angle) * rodLen
    paint()
end

on paint
    img = _movie.stage.image
    img.fill(img.rect, rgb(255,255,255))
    img.fill(point(200-5, 100-5), point(200+5, 100+5), [#shapeType:#oval,#color:rgb(0,0,0)])
    img.draw(point(200, 100), point(posX, posY), [#color:rgb(0,0,0)])
    img.fill(point(posX-20, posY-20), point(posX+20, posY+20), [#shapeType:#oval,#lineSize:1,#bgColor:rgb(0,0,0),#color:rgb(255,255,0)])
end


make "angle 45
make "L 1
make "bob 10

to draw.pendulum
  clearscreen
  seth :angle+180		; down on screen is 180
  forward :L*100-:bob
  penup
  forward :bob
  pendown
  arc 360 :bob
end

make "G   9.80665
make "dt  1/30
make "acc 0
make "vel 0

to step.pendulum
  make "acc  -:G / :L * sin :angle
  make "vel   :vel   + :acc * :dt
  make "angle :angle + :vel * :dt
  wait :dt*60
  draw.pendulum
end

hideturtle
until [key?] [step.pendulum]


function degToRad( d )
    return d * 0.01745329251
end

function love.load()
    g = love.graphics
    rodLen, gravity, velocity, acceleration = 260, 3, 0, 0
    halfWid, damp = g.getWidth() / 2, .989
    posX, posY, angle = halfWid
    TWO_PI, angle = math.pi * 2, degToRad( 90 )
end

function love.update( dt )
    acceleration = -gravity / rodLen * math.sin( angle )
    angle = angle + velocity; if angle > TWO_PI then angle = 0 end
    velocity = velocity + acceleration
    velocity = velocity * damp
    posX = halfWid + math.sin( angle ) * rodLen
    posY = math.cos( angle ) * rodLen
end

function love.draw()
    g.setColor( 250, 0, 250 )
    g.circle( "fill", halfWid, 0, 8 )
    g.line( halfWid, 4, posX, posY )
    g.setColor( 250, 100, 20 )
    g.circle( "fill", posX, posY, 20 )
end


Module Pendulum {
      back()
      degree=180/pi
      THETA=Pi/2
      SPEED=0
      G=9.81
      L=0.5
      Profiler
      lasttimecount=0
      cc=40  ' 40 ms every draw
      accold=0
      Every cc {
            ACCEL=G*SIN(THETA*degree)/L/50
            SPEED+=ACCEL/cc
            THETA+=SPEED
            Pendulum(THETA)
            if KeyPress(32) Then Exit
      }

      Sub back()
            If not IsWine then Smooth On
            Cls 7,0
            Pen 0
            Move 0, scale.y/4
            Draw scale.x,0
            Step -scale.x/2
            circle fill #AAAAAA, scale.x/50
            Hold  ' hold this as background
      End Sub

      Sub Pendulum(x)
            x+=pi/2
            Release  ' place stored background to screen
            Width scale.x/2000 {
                  Draw Angle x, scale.y/2.5
                  Width 1 {
                        Circle Fill 14, scale.x/25
                  }
                  Step Angle x, -scale.y/2.5
            }
            Print @(1,1), lasttimecount
            if sgn(accold)<>sgn(ACCEL) then lasttimecount=timecount: Profiler
            accold=ACCEL
            Refresh 1000
      End Sub
}
Pendulum


freq = 8; length = freq^(-1/2);
Animate[Graphics[
  List[{Line[{{0, 0}, length {Sin[T], -Cos[T]}} /. {T -> (Pi/6) Cos[2 Pi freq t]}], PointSize[Large],
               Point[{length {Sin[T], -Cos[T]}} /. {T -> (Pi/6) Cos[2 Pi freq t]}]}],
  PlotRange -> {{-0.3, 0.3}, {-0.5, 0}}], {t, 0, 1}, AnimationRate -> 0.07]


%This is a numerical simulation of a pendulum with a massless pivot arm.

%% User Defined Parameters
%Define external parameters
g = -9.8;
deltaTime = 1/50; %Decreasing this will increase simulation accuracy
endTime = 16;

%Define pendulum
rodPivotPoint = [2 2]; %rectangular coordinates
rodLength = 1;
mass = 1; %of the bob
radius = .2; %of the bob
theta = 45; %degrees, defines initial position of the bob
velocity = [0 0]; %cylindrical coordinates; first entry is radial velocity,
                  %second entry is angular velocity

%% Simulation
assert(radius < rodLength,'Pendulum bob radius must be less than the length of the rod.');

position = rodPivotPoint - (rodLength*[-sind(theta) cosd(theta)]); %in rectangular coordinates

%Generate graphics, render pendulum
figure;
axesHandle = gca;
xlim(axesHandle, [(rodPivotPoint(1) - rodLength - radius) (rodPivotPoint(1) + rodLength + radius)] );
ylim(axesHandle, [(rodPivotPoint(2) - rodLength - radius) (rodPivotPoint(2) + rodLength + radius)] );

rectHandle = rectangle('Position',[(position - radius/2) radius radius],...
    'Curvature',[1,1],'FaceColor','g'); %Pendulum bob
hold on
plot(rodPivotPoint(1),rodPivotPoint(2),'^'); %pendulum pivot
lineHandle = line([rodPivotPoint(1) position(1)],...
    [rodPivotPoint(2) position(2)]); %pendulum rod
hold off

%Run simulation, all calculations are performed in cylindrical coordinates
for time = (deltaTime:deltaTime:endTime)

    drawnow; %Forces MATLAB to render the pendulum

    %Find total force
    gravitationalForceCylindrical = [mass*g*cosd(theta) mass*g*sind(theta)];

    %This code is just incase you want to add more forces,e.g friction
    totalForce = gravitationalForceCylindrical;

    %If the rod isn't massless or is a spring, etc., modify this line
    %accordingly
    rodForce = [-totalForce(1) 0]; %cylindrical coordinates

    totalForce = totalForce + rodForce;

    acceleration = totalForce / mass; %F = ma
    velocity = velocity + acceleration * deltaTime;
    rodLength = rodLength + velocity(1) * deltaTime;
    theta = theta + velocity(2) * deltaTime; % Attention!! Mistake here.
    % Velocity needs to be divided by pendulum length and scaled to degrees:
    % theta = theta + velocity(2) * deltaTime/rodLength/pi*180;

    position = rodPivotPoint - (rodLength*[-sind(theta) cosd(theta)]);

    %Update figure with new position info
    set(rectHandle,'Position',[(position - radius/2) radius radius]);
    set(lineHandle,'XData',[rodPivotPoint(1) position(1)],'YData',...
        [rodPivotPoint(2) position(2)]);

end


# Pendulum simulation.

import math
import times

import opengl
import opengl/glut

var
  # Simulation variables.
  lg: float         # Pendulum length.
  g: float          # Gravity (should be positive).
  currTime: Time    # Current time.
  theta0: float     # Initial angle.
  theta: float      # Current angle.
  omega: float      # Angular velocity = derivative of theta.
  accel: float      # Angular acceleration = derivative of omega.
  e: float          # Total energy.

#---------------------------------------------------------------------------------------------------

proc initSimulation(length, gravitation, start: float) =
  ## Initialize the simulation.

  lg = length
  g = gravitation
  currTime = getTime()
  theta0 = start                    # Initial angle for which omega = 0.
  theta = start
  omega = 0
  accel = -g / lg * sin(theta0)
  e = g * lg * (1 - cos(theta0))    # Total energy = potential energy when starting.

#---------------------------------------------------------------------------------------------------

proc elapsed(): float =
  ## Return the elapsed time since previous call, expressed in seconds.

  let nextTime = getTime()
  result = (nextTime - currTime).inMicroseconds.float / 1e6
  currTime = nextTime

#---------------------------------------------------------------------------------------------------

proc resize(w, h: GLsizei) =
  ## Resize the window.

  glViewport(0, 0, w, h)
  glMatrixMode(GL_PROJECTION)
  glLoadIdentity()

  glMatrixMode(GL_MODELVIEW)
  glLoadIdentity()
  glOrtho(0, GLdouble(w), GLdouble(h), 0, -1, 1)

#---------------------------------------------------------------------------------------------------

proc render() {.cdecl.} =
  ## Render the window.

  # Compute the position of the mass.
  var x = 320 + 300 * sin(theta)
  var y = 300 * cos(theta)

  resize(640, 320)
  glClear(GL_COLOR_BUFFER_BIT)

  # Draw the line from pivot to mass.
  glBegin(GL_LINES)
  glVertex2d(320, 0)
  glVertex2d(x, y)
  glEnd()
  glFlush()

  # Update theta and omega.
  let dt = elapsed()
  theta += (omega + dt * accel / 2) * dt
  omega += accel * dt

  # If, due to computation errors, potential energy is greater than total energy,
  # reset theta to ±theta0 and omega to 0.
  if lg * g * (1 - cos(theta)) >= e:
    theta = sgn(theta).toFloat * theta0
    omega = 0

  accel = -g / lg * sin(theta)

#---------------------------------------------------------------------------------------------------

proc initGfx(argc: ptr cint; argv: pointer) =
  ## Initialize OpenGL rendering.

  glutInit(argc, argv)
  glutInitDisplayMode(GLUT_RGB)
  glutInitWindowSize(640, 320)
  glutIdleFunc(render)
  discard glutCreateWindow("Pendulum")
  glutDisplayFunc(render)
  loadExtensions()

#———————————————————————————————————————————————————————————————————————————————————————————————————

initSimulation(length = 5, gravitation = 9.81, start = PI / 3)

var argc: cint = 0
initGfx(addr(argc), nil)
glutMainLoop()


pendulum = .pendulum~new(10, 30)

before = .datetime~new
do 100         -- somewhat arbitrary loop count
  call syssleep .2
  now = .datetime~new
  pendulum~update(now - before)
  before = now
  say " X:" pendulum~x " Y:" pendulum~y
end

::class pendulum
::method init
  expose length theta x y velocity
  use arg length, theta
  x = rxcalcsin(theta) * length
  y = rxcalccos(theta) * length
  velocity = 0

::attribute x GET
::attribute y GET

::constant g -9.81   -- acceleration due to gravity

::method update
  expose length theta x y velocity
  use arg duration
  acceleration = self~g / length * rxcalcsin(theta)
  durationSeconds = duration~microseconds / 1000000
  x = rxcalcsin(theta, length)
  y = rxcalccos(theta, length)
  velocity = velocity + acceleration * durationSeconds
  theta = theta + velocity * durationSeconds

::requires rxmath library


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}


use strict;
use warnings;
use Tk;
use Math::Trig qw/:pi/;

my $root =  new MainWindow( -title => 'Pendulum Animation' );
my $canvas = $root->Canvas(-width => 320, -height => 200);
my $after_id;

for ($canvas) {
	$_->createLine(   0,  25, 320,  25, -tags => [qw/plate/], -width => 2, -fill => 'grey50' );
	$_->createOval( 155,  20, 165,  30, -tags => [qw/pivot outline/], -fill => 'grey50' );
	$_->createLine(   1,   1,    1,  1, -tags => [qw/rod width/], -width => 3, -fill => 'black' );
	$_->createOval(   1,   1,    2,  2, -tags => [qw/bob outline/], -fill => 'yellow' );
}

$canvas->raise('pivot');
$canvas->pack(-fill => 'both', -expand => 1);
my ($Theta, $dTheta, $length, $homeX, $homeY) =
	(45, 0, 150, 160, 25);

sub show_pendulum {
  my $angle = $Theta * pi() / 180;
  my $x = $homeX + $length * sin($angle);
  my $y = $homeY + $length * cos($angle);
  $canvas->coords('rod', $homeX, $homeY, $x, $y);
  $canvas->coords('bob', $x-15, $y-15, $x+15, $y+15);
}

sub recompute_angle {
  my $scaling = 3000.0 / ($length ** 2);
  # first estimate
  my $firstDDTheta = -sin($Theta * pi / 180) * $scaling;
  my $midDTheta = $dTheta + $firstDDTheta;
  my $midTheta = $Theta + ($dTheta + $midDTheta)/2;
  # second estimate
  my $midDDTheta = -sin($midTheta * pi/ 180) * $scaling;
  $midDTheta = $dTheta + ($firstDDTheta + $midDDTheta)/2;
  $midTheta = $Theta + ($dTheta + $midDTheta)/2;
  # again, first
  $midDDTheta = -sin($midTheta * pi/ 180) * $scaling;
  my $lastDTheta = $midDTheta + $midDDTheta;
  my $lastTheta = $midTheta + ($midDTheta + $lastDTheta)/2;
  # again, second
  my $lastDDTheta = -sin($lastTheta * 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;
}

sub animate {
  recompute_angle;
  show_pendulum;
  $after_id = $root->after(15 => sub {animate() });
}

show_pendulum;
$after_id = $root->after(500 => sub {animate});

$canvas->bind('<Destroy>' => sub {$after_id->cancel});
MainLoop;


--
-- demo\rosetta\animate_pendulum.exw
-- =================================
--
-- Author Pete Lomax, March 2017
--
-- Port of animate_pendulum.exw from arwen to pGUI, which is now
--  preserved as a comment below (in the distro version only).
--
-- With help from lesterb, updates now in timer_cb not redraw_cb,
-- variables better named, and velocity problem sorted, July 2018.
--
constant full = false   -- set true for full swing to near-vertical.
                        -- false performs swing to horizontal only.
                        -- (adjusts the starting angle, pivot point,
                        --  and canvas size, only.)

include pGUI.e

Ihandle dlg, canvas, timer
cdCanvas cdcanvas

constant g = 50

atom angle = iff(full?PI-0.01:PI/2),  -- (near_vertical | horiz)
     velocity = 0
integer w = 0, h = 0, len = 0

function redraw_cb(Ihandle /*ih*/, integer /*posx*/, /*posy*/)
    {w, h} = IupGetIntInt(canvas, "DRAWSIZE")
    cdCanvasActivate(cdcanvas)
    cdCanvasClear(cdcanvas)
    -- new suspension point:
    integer sX = floor(w/2)
    integer sY = floor(h/iff(full?2:16))  -- (mid | top)
    -- repaint:
    integer eX = floor(len*sin(angle)+sX)
    integer eY = floor(len*cos(angle)+sY)
    cdCanvasSetForeground(cdcanvas, CD_CYAN)
    cdCanvasLine(cdcanvas, sX, h-sY, eX, h-eY)
    cdCanvasSetForeground(cdcanvas, CD_DARK_GREEN)
    cdCanvasSector(cdcanvas, sX, h-sY, 5, 5, 0, 360)
    cdCanvasSetForeground(cdcanvas, CD_BLUE)
    cdCanvasSector(cdcanvas, eX, h-eY, 35, 35, 0, 360)
    cdCanvasFlush(cdcanvas)
    return IUP_DEFAULT
end function

function timer_cb(Ihandle /*ih*/)
    if w!=0 then
        integer newlen = floor(w/2)-30
        if newlen!=len then
            len = newlen
            atom tmp = 2*g*len*(cos(angle))
            velocity = iff(tmp<0?0:sqrt(tmp)*sign(velocity))
        end if
        atom dt = 0.2/w
        atom acceleration = -len*sin(angle)*g
        velocity += dt*acceleration
        angle += dt*velocity
        IupUpdate(canvas)
    end if
    return IUP_IGNORE
end function

function map_cb(Ihandle ih)
    atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
    IupGLMakeCurrent(canvas)
    if platform()=JS then
        cdcanvas = cdCreateCanvas(CD_IUP, canvas)
    else
        cdcanvas = cdCreateCanvas(CD_GL, "10x10 %g", {res})
    end if
    cdCanvasSetBackground(cdcanvas, CD_PARCHMENT)
    return IUP_DEFAULT
end function

function canvas_resize_cb(Ihandle /*canvas*/)
    integer {canvas_width, canvas_height} = IupGetIntInt(canvas, "DRAWSIZE")
    atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
    cdCanvasSetAttribute(cdcanvas, "SIZE", "%dx%d %g", {canvas_width, canvas_height, res})
    return IUP_DEFAULT
end function

procedure main()
    IupOpen()

    canvas = IupGLCanvas()
    IupSetAttribute(canvas, "RASTERSIZE", iff(full?"640x640":"640x340")) -- (fit 360|180)
    IupSetCallback(canvas, "MAP_CB", Icallback("map_cb"))
    IupSetCallback(canvas, "ACTION", Icallback("redraw_cb"))
    IupSetCallback(canvas, "RESIZE_CB", Icallback("canvas_resize_cb"))

    timer = IupTimer(Icallback("timer_cb"), 20)

    dlg = IupDialog(canvas)
    IupSetAttribute(dlg, "TITLE", "Animated Pendulum")

    IupShow(dlg)
    IupSetAttribute(canvas, "RASTERSIZE", NULL)
    if platform()!=JS then
        IupMainLoop()
        IupClose()
    end if
end procedure

main()


(load "@lib/math.l")

(de pendulum (X Y Len)
   (let (Angle pi/2  V 0)
      (call 'clear)
      (call 'tput "cup" Y X)
      (prin '+)
      (call 'tput "cup" 1 (+ X Len))
      (until (key 25)                        # 25 ms
         (let A (*/ (sin Angle) -9.81 1.0)
            (inc 'V (*/ A 40))               # DT = 25 ms = 1/40 sec
            (inc 'Angle (*/ V 40)) )
         (call 'tput "cup"
            (+ Y (*/ Len (cos Angle) 2.2))   # Compensate for aspect ratio
            (+ X (*/ Len (sin Angle) 1.0)) ) ) ) )


programa {
    inclua biblioteca Matematica --> math // math library
    inclua biblioteca Util --> u // util library
    inclua biblioteca Graficos --> g // graphics library
    inclua biblioteca Teclado --> t // keyboard library

    real accel, bx, by
    real theta	= math.PI * 0.5
    real g	= 9.81
    real l	= 1.0
    real speed	= 0.0
    real px	= 320.0
    real py	= 10.0
    inteiro w	= 10 // circle width and height (radius)

    // main entry
    funcao inicio() {

    g.iniciar_modo_grafico(verdadeiro)
        g.definir_dimensoes_janela(640, 400)

        // while ESC key not pressed
        enquanto (nao t.tecla_pressionada(t.TECLA_ESC)) {
            bx = px + l * 300.0 * math.seno(theta)
            by = py - l * 300.0 * math.cosseno(theta)

            g.definir_cor(g.COR_PRETO)
            g.limpar()

            g.definir_cor(g.COR_BRANCO)
            g.desenhar_linha(px, py, bx, by)
            g.desenhar_elipse(bx - w, by - w, w * 2, w * 2, verdadeiro)

            accel = g * math.seno(theta) / l / 100.0
            speed = speed + accel / 100.0
            theta = theta + speed

            g.desenhar_texto(0, 370, "Pendulum")
            g.desenhar_texto(0, 385, "Press ESC to quit")

            g.renderizar()
            u.aguarde(10)
        }
    }
}


:- use_module(library(pce)).

pendulum :-
	new(D, window('Pendulum')),
	send(D, size, size(560, 300)),
	new(Line, line(80, 50, 480, 50)),
	send(D, display, Line),
	new(Circle, circle(20)),
	send(Circle, fill_pattern,  colour(@default, 0, 0, 0)),
	new(Boule, circle(60)),
	send(Boule, fill_pattern,  colour(@default, 0, 0, 0)),
	send(D, display, Circle, point(270,40)),
	send(Circle, handle, handle(h/2, w/2, in)),
	send(Boule, handle, handle(h/2, w/2, out)),
	send(Circle, connect, Boule, link(in, out, line(0,0,0,0,none))),
	new(Anim, animation(D, 0.0, Boule, 200.0)),
	send(D, done_message, and(message(Anim, free),
				  message(Boule, free),
				  message(Circle, free),
				  message(@receiver,destroy))),
	send(Anim?mytimer, start),
	send(D, open).

:- pce_begin_class(animation(window, angle, boule, len_pendulum), object).
variable(window, object,  both, "Display window").
variable(boule,  object, both,  "bowl of the pendulum").
variable(len_pendulum,    object, both,  "len of the pendulum").
variable(angle,  object, both,  "angle with the horizontal").
variable(delta,    object, both,  "increment of the angle").
variable(mytimer, timer, both, "timer of the animation").

initialise(P, W:object, A:object, B : object, L:object) :->
        "Creation of the object"::
        send(P, window, W),
        send(P, angle, A),
        send(P, boule, B),
        send(P, len_pendulum, L),
        send(P, delta, 0.01),
	send(P, mytimer, new(_, timer(0.01,message(P, anim_message)))).

% method called when the object is destroyed
% first the timer is stopped
% then all the resources are freed
unlink(P) :->
	send(P?mytimer, stop),
	send(P, send_super, unlink).

% message processed by the timer
anim_message(P) :->
	get(P, angle, A),
	get(P, len_pendulum, L),
	calc(A, L, X, Y),
	get(P, window, W),
	get(P, boule, B),
	send(W, display, B, point(X,Y)),
	% computation of the next position
	get(P, delta, D),
	next_Angle(A, D, NA, ND),
	send(P, angle, NA),
	send(P, delta, ND).

:- pce_end_class.

% computation of the position of the bowl.
calc(Ang, Len, X, Y) :-
	X is Len * cos(Ang)+ 250,
	Y is Len * sin(Ang) + 20.

% computation of the next angle
% if we reach 0 or pi, delta change.
next_Angle(A, D, NA, ND) :-
	NA is D + A,
	(((D > 0,   abs(pi-NA) < 0.01); (D < 0, abs(NA) < 0.01))->
	  ND = - D;
	  ND = D).


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


import pygame, sys
from pygame.locals import *
from math import sin, cos, radians

pygame.init()

WINDOWSIZE = 250
TIMETICK = 100
BOBSIZE = 15

window = pygame.display.set_mode((WINDOWSIZE, WINDOWSIZE))
pygame.display.set_caption("Pendulum")

screen = pygame.display.get_surface()
screen.fill((255,255,255))

PIVOT = (WINDOWSIZE/2, WINDOWSIZE/10)
SWINGLENGTH = PIVOT[1]*4

class BobMass(pygame.sprite.Sprite):
    def __init__(self):
        pygame.sprite.Sprite.__init__(self)
        self.theta = 45
        self.dtheta = 0
        self.rect = pygame.Rect(PIVOT[0]-SWINGLENGTH*cos(radians(self.theta)),
                                PIVOT[1]+SWINGLENGTH*sin(radians(self.theta)),
                                1,1)
        self.draw()

    def recomputeAngle(self):
        scaling = 3000.0/(SWINGLENGTH**2)

        firstDDtheta = -sin(radians(self.theta))*scaling
        midDtheta = self.dtheta + firstDDtheta
        midtheta = self.theta + (self.dtheta + midDtheta)/2.0

        midDDtheta = -sin(radians(midtheta))*scaling
        midDtheta = self.dtheta + (firstDDtheta + midDDtheta)/2
        midtheta = self.theta + (self.dtheta + midDtheta)/2

        midDDtheta = -sin(radians(midtheta)) * scaling
        lastDtheta = midDtheta + midDDtheta
        lasttheta = midtheta + (midDtheta + lastDtheta)/2.0

        lastDDtheta = -sin(radians(lasttheta)) * scaling
        lastDtheta = midDtheta + (midDDtheta + lastDDtheta)/2.0
        lasttheta = midtheta + (midDtheta + lastDtheta)/2.0

        self.dtheta = lastDtheta
        self.theta = lasttheta
        self.rect = pygame.Rect(PIVOT[0]-
                                SWINGLENGTH*sin(radians(self.theta)),
                                PIVOT[1]+
                                SWINGLENGTH*cos(radians(self.theta)),1,1)

    def draw(self):
        pygame.draw.circle(screen, (0,0,0), PIVOT, 5, 0)
        pygame.draw.circle(screen, (0,0,0), self.rect.center, BOBSIZE, 0)
        pygame.draw.aaline(screen, (0,0,0), PIVOT, self.rect.center)
        pygame.draw.line(screen, (0,0,0), (0, PIVOT[1]), (WINDOWSIZE, PIVOT[1]))

    def update(self):
        self.recomputeAngle()
        screen.fill((255,255,255))
        self.draw()

bob = BobMass()

TICK = USEREVENT + 2
pygame.time.set_timer(TICK, TIMETICK)

def input(events):
    for event in events:
        if event.type == QUIT:
            sys.exit(0)
        elif event.type == TICK:
            bob.update()

while True:
    input(pygame.event.get())
    pygame.display.flip()


'declare and initialize variables
CONST PI = 3.141592

DIM SHARED Bob_X, Bob_Y, Pivot_X, Pivot_Y, Rod_Length, Rod_Angle, Bob_Angular_Acceleration, Bob_Angular_Velocity, Delta_Time, Drawing_Scale, G AS DOUBLE
DIM SHARED exit_flag AS INTEGER

'set gravity to Earth's by default (in m/s squared)
G = -9.80665

'set the pivot at the screen center near the top. Positions are in meters not pixels, and they translate to 320 and 60 pixels
Pivot_X = 1.6
Pivot_Y = 0.3

'set the rod length, 0.994 meters by default (gives 1 second period in Earth gravity)
Rod_Length = 0.994
'set the initial rod angle to 6 degrees and convert to radians. 6 degrees seems small but it is near to what clocks use so it
'makes the pendulum look like a clock's. More amplitude works perfectly but looks silly.
Rod_Angle = 6 * (PI / 180)
'set delta time, seconds. 5 miliseconds is precise enough.
Delta_Time = 0.05

'because the positions are calculated in meters, the pendulum as drawn would be way too small (1 meter = 1 pixel),
'so a scale factor is introduced (1 meter = 200 pixels by default)
Drawing_Scale = 200

'initialize the screen to 640 x 480, 16 colors
SCREEN 12

'main loop
DO
    'math to figure out what the pendulum is doing based on the initial conditions.

    'first calculate the position of the bob's center based on the rod angle by using the sine and cosine functions for x and y coordinates
    Bob_X = (Pivot_X + SIN(Rod_Angle) * Rod_Length)
    Bob_Y = (Pivot_Y + COS(Rod_Angle) * Rod_Length)
    'then based on the rod's last angle, length, and gravitational acceleration, calculate the angular acceleration
    Bob_Angular_Acceleration = G / Rod_Length * SIN(Rod_Angle)
    'integrate the angular acceleration over time to obtain angular velocity
    Bob_Angular_Velocity = Bob_Angular_Velocity + (Bob_Angular_Acceleration * Delta_Time)
    'integrate the angular velocity over time to obtain a new angle for the rod
    Rod_Angle = Rod_Angle + (Bob_Angular_Velocity * Delta_Time)

    'draw the user interface and pendulum position

    'clear the screen before drawing the next frame of the animation
    CLS

    'print information
    PRINT "   Gravity: " + STR$(ABS(G)) + " m/sý, Rod Length: " + STR$(Rod_Length); " m"
    LOCATE 25, 1
    PRINT "+/- keys control rod length, numbers 1-5 select gravity, (1 Earth, 2 the Moon, 3 Mars, 4 more 5 less), Q to exit"

    'draw the pivot
    CIRCLE (Pivot_X * Drawing_Scale, Pivot_Y * Drawing_Scale), 5, 8
    PAINT STEP(0, 0), 8, 8

    'draw the bob
    CIRCLE (Bob_X * Drawing_Scale, Bob_Y * Drawing_Scale), 20, 14
    PAINT STEP(0, 0), 14, 14

    'draw the rod
    LINE (Pivot_X * Drawing_Scale, Pivot_Y * Drawing_Scale)-(Bob_X * Drawing_Scale, Bob_Y * Drawing_Scale), 14

    'process input
    SELECT CASE UCASE$(INKEY$)
        CASE "+"
            'lengthen rod
            Rod_Length = Rod_Length + 0.01
        CASE "-"
            'shorten rod
            Rod_Length = Rod_Length - 0.01
        CASE "1"
            'Earth G
            G = -9.80665
        CASE "2"
            'Moon G
            G = -1.62
        CASE "3"
            'Mars G
            G = -3.721
        CASE "4"
            'More G
            G = G + 0.1
        CASE "5"
            'Less G
            G = G - 0.1
        CASE "Q"
            'exit on any other key
            exit_flag = 1
    END SELECT

    'wait before drawing the next frame
    _DELAY Delta_Time

    'loop the animation until the user presses any key
LOOP UNTIL exit_flag = 1


library(DescTools)

pendulum<-function(length=5,radius=1,circle.color="white",bg.color="white"){
  tseq = c(seq(0,pi,by=.1),seq(pi,0,by=-.1))
  slow=.27;fast=.07
  sseq = c(seq(slow,fast,length.out = length(tseq)/4),seq(fast,slow,length.out = length(tseq)/4),seq(slow,fast,length.out = length(tseq)/4),seq(fast,slow,length.out = length(tseq)/4))
  plot(0,0,xlim=c((-length-radius)*1.2,(length+radius)*1.2),ylim=c((-length-radius)*1.2,0),xaxt="n",yaxt="n",xlab="",ylab="")
  cat("Press Esc to end animation")

  while(T){
    for(i in 1:length(tseq)){
      rect(par("usr")[1],par("usr")[3],par("usr")[2],par("usr")[4],col = bg.color)
      abline(h=0,col="grey")
      points(0,0)
      DrawCircle((radius+length)*cos(tseq[i]),(radius+length)*-sin(tseq[i]),r.out=radius,col=circle.color)
      lines(c(0,length*cos(tseq[i])),c(0,length*-sin(tseq[i])))
      Sys.sleep(sseq[i])
    }
  }

}

pendulum(5,1,"gold","lightblue")


#lang racket

(require 2htdp/image 2htdp/universe)

(define (pendulum)
  (define (accel θ) (- (sin θ)))
  (define θ (/ pi 2.5))
  (define θ′ 0)
  (define θ′′ (accel (/ pi 2.5)))
  (define (x θ) (+ 200 (* 150 (sin θ))))
  (define (y θ) (* 150 (cos θ)))
  (λ (n)
    (define p-image (underlay/xy (add-line (empty-scene 400 200) 200 0 (x θ) (y θ) "black")
                                 (- (x θ) 5) (- (y θ) 5) (circle 5 "solid" "blue")))
    (set! θ (+ θ (* θ′ 0.04)))
    (set! θ′ (+ θ′ (* (accel θ) 0.04)))
    p-image))

(animate (pendulum))


use SDL2::Raw;
use Cairo;

my $width = 1000;
my $height = 400;

SDL_Init(VIDEO);

my $window = SDL_CreateWindow(
    'Pendulum - Raku',
    SDL_WINDOWPOS_CENTERED_MASK,
    SDL_WINDOWPOS_CENTERED_MASK,
    $width, $height, RESIZABLE
);

my $render = SDL_CreateRenderer($window, -1, ACCELERATED +| PRESENTVSYNC);

my $bob = Cairo::Image.create( Cairo::FORMAT_ARGB32, 32, 32 );
given Cairo::Context.new($bob) {
     my Cairo::Pattern::Gradient::Radial $sphere .=
        create(13.3, 12.8, 3.2, 12.8, 12.8, 32);
     $sphere.add_color_stop_rgba(0, 1, 1, .698, 1);
     $sphere.add_color_stop_rgba(1, .623, .669, .144, 1);
     .pattern($sphere);
     .arc(16, 16, 15, 0, 2 * pi);
     .fill;
     $sphere.destroy;
}

my $bob_texture = SDL_CreateTexture(
    $render, %PIXELFORMAT<ARGB8888>,
    STATIC, 32, 32
);

SDL_UpdateTexture(
    $bob_texture,
    SDL_Rect.new(:x(0), :y(0), :w(32), :h(32)),
    $bob.data, $bob.stride // 32
);

SDL_SetTextureBlendMode($bob_texture, 1);

SDL_SetRenderDrawBlendMode($render, 1);

my $event = SDL_Event.new;

my $now = now;   # time
my $Θ   = -π/3;  # start angle
my $ppi = 500;   # scale
my $g   = -9.81; # accelaration of gravity
my $ax  = $width/2; # anchor x
my $ay  = 25;       # anchor y
my $len = $height - 75; # 'rope' length
my $vel; # velocity
my $dt;  # delta time

main: loop {
    while SDL_PollEvent($event) {
        my $casted_event = SDL_CastEvent($event);
        given $casted_event {
            when *.type == QUIT    { last main }
            when *.type == WINDOWEVENT {
                if .event == 5 {
                    $width  = .data1;
                    $height = .data2;
                    $ax = $width/2;
                    $len = $height - 75;
                }
            }
        }
    }

    $dt = now - $now;
    $now = now;
    $vel += $g / $len * sin($Θ) * $ppi * $dt;
    $Θ   += $vel * $dt;
    my $bx = $ax + sin($Θ) * $len;
    my $by = $ay + cos($Θ) * $len;

    SDL_SetRenderDrawColor($render, 255, 255, 255, 255);
    SDL_RenderDrawLine($render, |($ax, $ay, $bx, $by)».round);
    SDL_RenderCopy( $render, $bob_texture, Nil,
      SDL_Rect.new($bx - 16, $by - 16, 32, 32)
    );
    SDL_RenderPresent($render);
    SDL_SetRenderDrawColor($render, 0, 0, 0, 0);
    SDL_RenderClear($render);
}

SDL_Quit();


/*REXX program displays the   (x, y)  coördinates  (at the end of a swinging pendulum). */
parse arg cycles Plength theta .                 /*obtain optional argument from the CL.*/
if  cycles=='' |  cycles==","  then  cycles=  60 /*Not specified?  Then use the default.*/
if pLength=='' | pLength==","  then pLength=  10 /* "      "         "   "   "     "    */
if   theta=='' |   theta==","  then   theta=  30 /* "      "         "   "   "     "    */
theta= theta / 180 * pi()                        /* 'cause that's the way  Ada  did it. */
was= time('R')                                   /*obtain the current elapsed time (was)*/
g= -9.81                                         /*gravitation constant  (for earth).   */
speed= 0                                         /*velocity of the pendulum, now resting*/
         do cycles;            call delay 1/20   /*swing the pendulum a number of times.*/
         now= time('E')                          /*obtain the current time (in seconds).*/
         duration= now - was                     /*calculate duration since last cycle. */
         acceleration= g / pLength * sin(theta)  /*compute the pendulum acceleration.   */
         x= sin(theta) * pLength                 /*calculate  X  coördinate of pendulum.*/
         y= cos(theta) * pLength                 /*    "      Y       "           "     */
         speed= speed + acceleration * duration  /*calculate "   speed      "     "     */
         theta= theta + speed        * duration  /*    "     "   angle      "     "     */
         was= now                                /*save the elapsed time as it was then.*/
         say right('X: ',20)   fmt(x)      right("Y: ", 10)        fmt(y)
         end   /*cycles*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
fmt:  procedure; parse arg z;  return left('', z>=0)format(z, , digits() - 1)   /*align#*/
pi:   pi= 3.1415926535897932384626433832795028841971693993751058209749445923078; return pi
r2r:  return arg(1)  //  (pi() * 2)              /*normalize radians ──► a unit circle. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
cos:  procedure; parse arg x; x=r2r(x); numeric fuzz min(6,digits()-3);  z=1;  _=1;  x=x*x
      p=z; do k=2  by 2; _=-_*x/(k*(k-1)); z=z+_;  if z=p  then leave; p=z; end;  return z
/*──────────────────────────────────────────────────────────────────────────────────────*/
sin:  procedure; parse arg x; x=r2r(x); _=x; numeric fuzz min(5, max(1,digits()-3)); q=x*x
      z=x;   do k=2  by 2  until p=z;  p= z;  _= -_*q/(k*k+k);   z= z+_;   end;   return z


# Project : Animate a pendulum

load "guilib.ring"
load "stdlib.ring"

CounterMan = 1
paint = null
pi = 22/7
theta = pi/180*40
g = 9.81
l = 0.50
speed = 0

new qapp
        {
        win1 = new qwidget() {
                  setwindowtitle("Animate a pendulum")
                  setgeometry(100,100,800,600)
                  label1 = new qlabel(win1) {
                              setgeometry(10,10,800,600)
                              settext("")
                  }
                  new qpushbutton(win1) {
                          setgeometry(150,500,100,30)
                          settext("draw")
                          setclickevent("draw()")
                  }
                  TimerMan = new qtimer(win1)
                  {
                                    setinterval(1000)
                                    settimeoutevent("draw()")
                                    start()
                  }
                  show()
        }
        exec()
        }

func draw
        p1 = new qpicture()
               color = new qcolor() {
               setrgb(0,0,255,255)
        }
        pen = new qpen() {
                 setcolor(color)
                 setwidth(1)
        }
        paint = new qpainter() {
                  begin(p1)
                  setpen(pen)
        ptime()
        endpaint()
        }
        label1 { setpicture(p1) show() }
        return

 func ptime()
         TimerMan.start()
         pPlaySleep()
         sleep(0.1)
         CounterMan++
         if CounterMan = 20
            TimerMan.stop()
         ok

func pPlaySleep()
       pendulum(theta, l)
       pendulum(theta, l)
       accel = - g * sin(theta) / l / 100
       speed = speed + accel / 100
       theta = theta + speed

func pendulum(a, l)
       pivotx = 640
       pivoty = 800
       bobx = pivotx + l * 1000 * sin(a)
       boby = pivoty - l * 1000 * cos(a)
       paint.drawline(pivotx, pivoty, bobx, boby)
       paint.drawellipse(bobx + 24 * sin(a), boby - 24 * cos(a), 24, 24)


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


require 'tk'

$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
$homeX = 160
$homeY = 25

def show_pendulum
  angle = $Theta * Math::PI / 180
  x = $homeX + $length * Math.sin(angle)
  y = $homeY + $length * Math.cos(angle)
  $canvas.coords('rod', $homeX, $homeY, 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_pendulum
  $after_id = $root.after(15) {animate}
end

show_pendulum
$after_id = $root.after(500) {animate}

$canvas.bind('<Destroy>') {$root.after_cancel($after_id)}

Tk.mainloop


// using version 0.107.0 of piston_window
use piston_window::{clear, ellipse, line_from_to, PistonWindow, WindowSettings};

const PI: f64 = std::f64::consts::PI;
const WIDTH: u32 = 640;
const HEIGHT: u32 = 480;

const ANCHOR_X: f64 = WIDTH as f64 / 2. - 12.;
const ANCHOR_Y: f64 = HEIGHT as f64 / 4.;
const ANCHOR_ELLIPSE: [f64; 4] = [ANCHOR_X - 3., ANCHOR_Y - 3., 6., 6.];

const ROPE_ORIGIN: [f64; 2] = [ANCHOR_X, ANCHOR_Y];
const ROPE_LENGTH: f64 = 200.;
const ROPE_THICKNESS: f64 = 1.;

const DELTA: f64 = 0.05;
const STANDARD_GRAVITY_VALUE: f64 = -9.81;

// RGBA Colors
const BLACK: [f32; 4] = [0., 0., 0., 1.];
const RED: [f32; 4] = [1., 0., 0., 1.];
const GOLD: [f32; 4] = [216. / 255., 204. / 255., 36. / 255., 1.0];
fn main() {
    let mut window: PistonWindow = WindowSettings::new("Pendulum", [WIDTH, HEIGHT])
        .exit_on_esc(true)
        .build()
        .unwrap();

    let mut angle = PI / 2.;
    let mut angular_vel = 0.;

    while let Some(event) = window.next() {
        let (angle_sin, angle_cos) = angle.sin_cos();
        let ball_x = ANCHOR_X + angle_sin * ROPE_LENGTH;
        let ball_y = ANCHOR_Y + angle_cos * ROPE_LENGTH;

        let angle_accel = STANDARD_GRAVITY_VALUE / ROPE_LENGTH * angle_sin;
        angular_vel += angle_accel * DELTA;
        angle += angular_vel * DELTA;
        let rope_end = [ball_x, ball_y];
        let ball_ellipse = [ball_x - 7., ball_y - 7., 14., 14.];

        window.draw_2d(&event, |context, graphics, _device| {
            clear([1.0; 4], graphics);
            line_from_to(
                BLACK,
                ROPE_THICKNESS,
                ROPE_ORIGIN,
                rope_end,
                context.transform,
                graphics,
            );
            ellipse(RED, ANCHOR_ELLIPSE, context.transform, graphics);
            ellipse(GOLD, ball_ellipse, context.transform, graphics);
        });
    }
}


import java.awt.Color
import java.util.concurrent.{Executors, TimeUnit}

import scala.swing.{Graphics2D, MainFrame, Panel, SimpleSwingApplication}
import scala.swing.Swing.pair2Dimension

object Pendulum extends SimpleSwingApplication {
  val length = 100

  lazy val ui = new Panel {
    import scala.math.{cos, Pi, sin}

    background = Color.white
    preferredSize = (2 * length + 50, length / 2 * 3)
    peer.setDoubleBuffered(true)

    var angle: Double = Pi / 2

    override def paintComponent(g: Graphics2D): Unit = {
      super.paintComponent(g)

      val (anchorX, anchorY) = (size.width / 2, size.height / 4)
      val (ballX, ballY) =
        (anchorX + (sin(angle) * length).toInt, anchorY + (cos(angle) * length).toInt)
      g.setColor(Color.lightGray)
      g.drawLine(anchorX - 2 * length, anchorY, anchorX + 2 * length, anchorY)
      g.setColor(Color.black)
      g.drawLine(anchorX, anchorY, ballX, ballY)
      g.fillOval(anchorX - 3, anchorY - 4, 7, 7)
      g.drawOval(ballX - 7, ballY - 7, 14, 14)
      g.setColor(Color.yellow)
      g.fillOval(ballX - 7, ballY - 7, 14, 14)
    }

    val animate: Runnable = new Runnable {
      var angleVelocity = 0.0
      var dt = 0.1

      override def run(): Unit = {
        angleVelocity += -9.81 / length * Math.sin(angle) * dt
        angle += angleVelocity * dt
        repaint()
      }
    }
  }

  override def top = new MainFrame {
    title = "Rosetta Code >>> Task: Animate a pendulum | Language: Scala"
    contents = ui
    centerOnScreen()
    Executors.
      newSingleThreadScheduledExecutor().
      scheduleAtFixedRate(ui.animate, 0, 15, TimeUnit.MILLISECONDS)
  }
}


#!r6rs

;;; R6RS implementation of Pendulum Animation

(import (rnrs)
        (lib pstk main) ; change this for your pstk installation
        )

(define PI 3.14159)
(define *conv-radians* (/ PI 180))
(define *theta* 45.0)
(define *d-theta* 0.0)
(define *length* 150)
(define *home-x* 160)
(define *home-y* 25)

;;; estimates new angle of pendulum
(define (recompute-angle)
  (define (avg a b) (/ (+ a b) 2))
  (let* ((scaling (/ 3000.0 (* *length* *length*)))
         ; first estimate
         (first-dd-theta (- (* (sin (* *theta* *conv-radians*)) scaling)))
         (mid-d-theta (+ *d-theta* first-dd-theta))
         (mid-theta (+ *theta* (avg *d-theta* mid-d-theta)))
         ; second estimate
         (mid-dd-theta (- (* (sin (* mid-theta *conv-radians*)) scaling)))
         (mid-d-theta-2 (+ *d-theta* (avg first-dd-theta mid-dd-theta)))
         (mid-theta-2 (+ *theta* (avg *d-theta* mid-d-theta-2)))
         ; again first
         (mid-dd-theta-2 (- (* (sin (* mid-theta-2 *conv-radians*)) scaling)))
         (last-d-theta (+ mid-d-theta-2 mid-dd-theta-2))
         (last-theta (+ mid-theta-2 (avg mid-d-theta-2 last-d-theta)))
         ; again second
         (last-dd-theta (- (* (sin (* last-theta *conv-radians*)) scaling)))
         (last-d-theta-2 (+ mid-d-theta-2 (avg mid-dd-theta-2 last-dd-theta)))
         (last-theta-2 (+ mid-theta-2 (avg mid-d-theta-2 last-d-theta-2))))
    ; put values back in globals
    (set! *d-theta* last-d-theta-2)
    (set! *theta* last-theta-2)))

;;; The main event loop and graphics context
(let ((tk (tk-start)))
  (tk/wm 'title tk "Pendulum Animation")
  (let ((canvas (tk 'create-widget 'canvas)))

    ;;; redraw the pendulum on canvas
    ;;; - uses angle and length to compute new (x,y) position of bob
    (define (show-pendulum canvas)
      (let* ((pendulum-angle (* *conv-radians* *theta*))
             (x (+ *home-x* (* *length* (sin pendulum-angle))))
             (y (+ *home-y* (* *length* (cos pendulum-angle)))))
        (canvas 'coords 'rod *home-x* *home-y* x y)
        (canvas 'coords 'bob (- x 15) (- y 15) (+ x 15) (+ y 15))))

    ;;; move the pendulum and repeat after 20ms
    (define (animate)
      (recompute-angle)
      (show-pendulum canvas)
      (tk/after 20 animate))

    ;; layout the canvas
    (tk/grid canvas 'column: 0 'row: 0)
    (canvas 'create 'line 0 25 320 25 'tags: 'plate 'width: 2 'fill: 'grey50)
    (canvas 'create 'oval 155 20 165 30 'tags: 'pivot 'outline: "" 'fill: 'grey50)
    (canvas 'create 'line 1 1 1 1 'tags: 'rod 'width: 3 'fill: 'black)
    (canvas 'create 'oval 1 1 2 2 'tags: 'bob 'outline: 'black 'fill: 'yellow)

    ;; get everything started
    (show-pendulum canvas)
    (tk/after 500 animate)
    (tk-event-loop tk)))