Animate a pendulum: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (→‎{{header|Phix}}: added full swing option and online link)
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(43 intermediate revisions by 14 users not shown)
Line 1:
[[Category:Animation]]
{{task|Temporal media}}
{{requires|Graphics}}
Line 18 ⟶ 19:
 
pendulums.ads:
<langsyntaxhighlight Adalang="ada">generic
type Float_Type is digits <>;
Gravitation : Float_Type;
Line 36 ⟶ 37:
Velocity : Float_Type;
end record;
end Pendulums;</langsyntaxhighlight>
 
pendulums.adb:
<langsyntaxhighlight Adalang="ada">with Ada.Numerics.Generic_Elementary_Functions;
package body Pendulums is
package Math is new Ada.Numerics.Generic_Elementary_Functions (Float_Type);
Line 76 ⟶ 77:
Item.Velocity * Float_Type (Time);
end Update_Pendulum;
end Pendulums;</langsyntaxhighlight>
 
example main.adb:
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
with Ada.Calendar;
with Pendulums;
Line 102 ⟶ 103:
" Y: " & Float'Image (Get_Y (My_Pendulum)));
end loop;
end Main;</langsyntaxhighlight>
 
{{out}}
Line 139 ⟶ 140:
X: -5.00352E+00 Y: 8.65822E+00
...</pre>
 
=={{header|Amazing Hopper}}==
{{Trans|FreeBASIC}}
<syntaxhighlight lang="text">
#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
</syntaxhighlight>
{{out}}
<pre>
 
PENDULUM
Press any key to quit
 
 
 
 
██
██
██
██
██
██
██
██ ███
██ █
███ █
█ O █
█ █
█ █
███
 
</pre>
<pre>
FALSE MODE GRAPHICS.
You can simulate a pseudo graphical mode in an Ubuntu Linux terminal by adding the following lines:
</pre>
<syntaxhighlight lang="amazing hopper">
SYS("gsettings set org.gnome.Terminal.Legacy.Profile:/org/gnome/terminal/legacy/profiles:/:.../ font 'Ubuntu Mono 1'")
 
CLR-SCR
HIDE-CURSOR
GOSUB( Animate a Pendulum )
 
SYS("gsettings set org.gnome.Terminal.Legacy.Profile:/org/gnome/terminal/legacy/profiles:/:.../ font 'Ubuntu Mono 12'")
SHOW-CURSOR
</syntaxhighlight>
<pre>
And substituting the holding coordinates of the pendulum:
</pre>
<syntaxhighlight lang="amazing hopper">
 
// in "Animate a Pendulum"
 
SET( px, 640 )//65 )
SET( py, 30 ) //7 )
 
// long of the line:
 
LET( bx := ADD( px, MUL( MUL( l, 180 ), SIN(theta) ) ) )
LET( by := SUB( py, MUL( MUL( l, 180 ), COS(theta) ) ) )
 
// and circle ratio:
{bx, by, 10} GOSUB( CIRCLE )
 
</syntaxhighlight>
 
=={{header|AutoHotkey}}==
This version doesn't use an complex physics calculation - I found a faster way.
{{libheader|GDIP}}
<langsyntaxhighlight AutoHotkeylang="autohotkey">SetBatchlines,-1
;settings
SizeGUI:={w:650,h:400} ;Guisize
Line 181 ⟶ 338:
 
GuiClose:
ExitApp</langsyntaxhighlight>
 
=={{header|BASIC}}==
==={{header|Applesoft BASIC}}===
{{trans|Commodore BASIC}}
Two shapes are used to draw and undraw the pendulum. Undrawing and drawing is done on the page that is not being displayed to make the animation flicker free. Animation code is compacted and hoisted to the beginning of the program. Variables are defined for all non-zero values.
<syntaxhighlight lang="gwbasic"> 0 ON NOT T GOTO 9: FOR Q = 0 TO T STEP 0:BX = PX + L * S * SIN (F):BY = PY - L * S * COS (F): HCOLOR= 0: FOR I = 0 TO N(P): DRAW T + (I = N(P)) AT X(P,I),Y(P,I): NEXT I:N(P) = 0: HCOLOR= C
1 FOR X = PX TO BX STEP (BX - PX) / Z:Y = PY + (X - PX) * (BY - PY) / (BX - PX): DRAW T AT X,Y:X(P,N(P)) = X:Y(P,N(P)) = Y:N(P) = N(P) + 1: NEXT X
2 HCOLOR= T: DRAW B AT BX,BY:X(P,N(P)) = BX:Y(P,N(P)) = BY:A = PEEK (R + P):P = NOT P: POKE U,W + W * P:A = G * SIN (F) / L / H:V = V + A / Z:F = F + V: NEXT Q
9 DIM N(1),X(1,11),Y(1,11): FOR P = 32 TO 64 STEP 32: POKE 230,P: HCOLOR= 0: HPLOT 0,0: CALL 62454: NEXT :R = 49236:P = ( PEEK (R) + PEEK (49234) + PEEK (49239) + PEEK (49232)) * 0 + 1
10 S$ = CHR$ (2) + CHR$ (0) + CHR$ (6) + CHR$ (0) + CHR$ (8) + CHR$ (0) + "-" + CHR$ (0) + ".%'?>..%" + CHR$ (0): PRINT MID$ ( STR$ ( FRE (0)) + S$,1,0);: POKE 236, PEEK (131): POKE 237, PEEK (132)
15 S = PEEK (236) + PEEK (237) * 256: POKE 232, PEEK (S + 1): POKE 233, PEEK (S + 2): SCALE= 1: ROT= 0
20 T = 1
25 F = 3.1415926535 / 2: REM THETA
30 G = 9.81
35 L = 0.5
40 V = 0: REM SPEED
45 PX = 140
50 PY = 80
55 S = 20
60 Z = 10
65 C = 3
70 B = 2
75 U = 230
80 W = 32
85 H = 50
90 GOTO</syntaxhighlight>
==={{header|BBC BASIC}}===
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> MODE 8
*FLOAT 64
VDU 23,23,4;0;0;0; : REM Set line thickness
Line 214 ⟶ 395:
GCOL 3,11
CIRCLE FILL bobX + 24 * SIN(a), bobY - 24 * COS(a), 24
ENDPROC</langsyntaxhighlight>
 
==={{header|Commodore BASIC}}===
<langsyntaxhighlight lang="commodorebasic">10 GOSUB 1000
20 THETA = π/2
30 G = 9.81
Line 240 ⟶ 421:
1000 FOR I=0 TO 39: X$ = X$+CHR$(29): NEXT
1010 FOR I=0 TO 24: Y$ = Y$+CHR$(17): NEXT
1020 RETURN</langsyntaxhighlight>
 
==={{header|FreeBASIC}}===
<langsyntaxhighlight lang="freebasic">Const PI = 3.141592920
Dim As Double theta, g, l, accel, speed, px, py, bx, by
theta = PI/2
Line 264 ⟶ 445:
Draw String (0,385), "Press any key to quit"
Sleep 10
Loop Until Inkey()<>""</langsyntaxhighlight>
 
==={{header|IS-BASIC}}===
<langsyntaxhighlight ISlang="is-BASICbasic">100 PROGRAM "Pendulum.bas"
110 LET THETA=RAD(50):LET G=9.81:LET L=.5
120 CALL INIC
Line 321 ⟶ 502:
620 CLOSE #I
630 NEXT
640 END DEF</langsyntaxhighlight>
 
=={{header|C}}==
{{libheader|GLUT}}
<langsyntaxhighlight lang="c">#include <stdlib.h>
#include <math.h>
#include <GL/glut.h>
Line 401 ⟶ 582:
glutMainLoop();
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
{{libheader|Windows Forms}}
 
{{libheader|GDI (System.Drawing)}}
 
<langsyntaxhighlight lang="csharp">
using System;
using System.Drawing;
Line 463 ⟶ 644:
}
}
</syntaxhighlight>
</lang>
 
=={{header|C++}}==
{{libheader|wxWidgets}}
File wxPendulumDlg.hpp
<langsyntaxhighlight lang="cpp">
#ifndef __wxPendulumDlg_h__
#define __wxPendulumDlg_h__
Line 535 ⟶ 716:
 
#endif // __wxPendulumDlg_h__
</syntaxhighlight>
</lang>
File wxPendulumDlg.cpp
<langsyntaxhighlight lang="cpp">
// ---------------------
/// @author Martin Ettl
Line 650 ⟶ 831:
Refresh();
}
</syntaxhighlight>
</lang>
This program is tested with wxWidgets version 2.8 and 2.9.
The whole project, including makefile for compiling on Linux
Line 660 ⟶ 841:
 
{{libheader|Swing}} {{libheader|AWT}}
<langsyntaxhighlight lang="clojure">
(ns pendulum
(:import
Line 724 ⟶ 905:
(-main)
</syntaxhighlight>
</lang>
 
=={{header|Common Lisp}}==
Line 734 ⟶ 915:
Pressing the spacebar adds a pendulum.
 
<langsyntaxhighlight lang="lisp">(defvar *frame-rate* 30)
(defvar *damping* 0.99 "Deceleration factor.")
 
Line 778 ⟶ 959:
(random 90)
(round w 2))
pendulums))))))))</langsyntaxhighlight>
=={{header|Delphi}}==
{{libheader| Vcl.Forms}}
Line 784 ⟶ 965:
{{libheader| Vcl.ExtCtrls}}
{{Trans|C#}}
<syntaxhighlight lang="delphi">
<lang Delphi>
unit main;
 
Line 872 ⟶ 1,053:
end;
 
end.</langsyntaxhighlight>
 
=={{header|E}}==
Line 888 ⟶ 1,069:
(This logic is more general than necessary; it is designed to be suitable for a larger application as well.)
 
<langsyntaxhighlight lang="e">#!/usr/bin/env rune
pragma.syntax("0.9")
 
Line 975 ⟶ 1,156:
}
 
interp.blockAtTop()</langsyntaxhighlight>
 
=={{header|EasyLang}}==
Line 981 ⟶ 1,162:
[https://easylang.online/apps/pendulum.html Run it]
 
<syntaxhighlight lang="text">ang = 45
<lang>on animate
on animate
clear_screen
clear
move_pen 50 50
move 50 50
draw_circle 1
circle 1
x = 50 + 40 * sin ang
y = 50 -+ 40 * cos ang
draw_lineline x y
circle 6
draw_circle 5
vel += sin ang / 5
ang += vel
.
</syntaxhighlight>
ang = 10</lang>
 
=={{header|Elm}}==
<langsyntaxhighlight lang="elm">import Color exposing (..)
import Collage exposing (..)
import Element exposing (..)
Line 1,067 ⟶ 1,249:
, update = update
, subscriptions = subscriptions
}</langsyntaxhighlight>
 
Link to live demo: http://dc25.github.io/animatedPendulumElm
 
=={{header|ERRE}}==
<syntaxhighlight lang="erre">
<lang ERRE>
PROGRAM PENDULUM
 
Line 1,108 ⟶ 1,290:
END LOOP
END PROGRAM
</syntaxhighlight>
</lang>
PC version: Ctrl+Break to stop.
 
Line 1,144 ⟶ 1,326:
===DOS32 version===
{{works with|Euphoria|3.1.1}}
<langsyntaxhighlight lang="euphoria">include graphics.e
include misc.e
 
Line 1,200 ⟶ 1,382:
end procedure
 
animation()</langsyntaxhighlight>
 
=={{header|F_Sharp|F#}}==
A nice application of F#'s support for units of measure.
<langsyntaxhighlight lang="fsharp">open System
open System.Drawing
open System.Windows.Forms
Line 1,285 ⟶ 1,467:
 
[<STAThread>]
Application.Run( new PendulumForm( Visible=true ) )</langsyntaxhighlight>
 
=={{header|Factor}}==
Approximation of the pendulum for small swings : theta = theta0 * cos(omega0 * t)
<langsyntaxhighlight lang="factor">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 ;
Line 1,329 ⟶ 1,511:
[ <pendulum-gadget> "pendulum" open-window ] with-ui ;
MAIN: pendulum-main
</syntaxhighlight>
</lang>
 
=={{header|FBSL}}==
<langsyntaxhighlight lang="qbasic">#INCLUDE <Include\Windows.inc>
 
FBSLSETTEXT(ME, "Pendulum")
Line 1,388 ⟶ 1,570:
DeleteObject(SelectObject(CreateCompatibleDC, SelectObject))
DeleteDC(CreateCompatibleDC)
END SUB</langsyntaxhighlight>
'''Screenshot:'''
[[File:FBSLPendulum.png]]
Line 1,394 ⟶ 1,576:
=={{header|Fortran}}==
Uses system commands (gfortran) to clear the screen. An initial starting angle is allowed between 90 (to the right) and -90 degrees (to the left). It checks for incorrect inputs.
<langsyntaxhighlight lang="fortran">
!Implemented by Anant Dixit (October, 2014)
program animated_pendulum
Line 1,469 ⟶ 1,651:
end do
end subroutine
</syntaxhighlight>
</lang>
 
A small preview (truncated to a few steps of the pendulum changing direction). Initial angle provided = 80 degrees.
Line 1,755 ⟶ 1,937:
=={{header|Groovy}}==
Straight translation of Java solution groovified by removing explicit definitions and converting casts to Groovy as style where needed.
<langsyntaxhighlight lang="groovy">
import java.awt.*;
import javax.swing.*;
Line 1,808 ⟶ 1,990:
}
}
</syntaxhighlight>
</lang>
 
=={{header|FutureBasic}}==
<syntaxhighlight lang="futurebasic">
void local fn BuildWindow
window 1, @"Animated Pendulum in FutureBasic", ( 0, 0, 640, 400 )
WindowSetBackgroundColor( 1, fn ColorBlack )
WindowSetMinSize( 1, fn CGSizeMake( 640, 400 ) )
WindowSetMaxSize( 1, fn CGSizeMake( 640, 400 ) )
end fn
 
local fn AnimatedPendulum
block double theta, gravity, length, accel, speed, weight, tempo, px, py, bx, by
block ColorRef color = fn ColorWithRGB( 0.164, 0.793, 0.075, 1.0 )
theta = pi/2.0 // Denominator of 2.0 = 180-degree swing, < 2.0 narrows inscribed arc, > 2.0 widens it.
gravity = 9.90 // Adjusts effect of gravity on swing. Smaller values slow arc swing.
length = 0.95 // Tweak for length of pendulum arm
speed = 0 // Zero this or you get a propellor!
px = 320 // Pivot horizontal center x point (half window width)
py = 30 // Pivot y center y point from top
weight = 42 // Diameter of pendulum weight
tempo = 75 // Smaller value increases pendulum tempo, larger value slows it.
timerbegin, 0.02, YES
bx = px + length * 300 * sin(theta) // Pendulum bottom x point
by = py - length * 300 * cos(theta) // Pendulum bottom y point
cls
pen 6.0, color
line px, py to bx, by
oval fill bx -weight/2, by -weight/2, weight, weight, color // Traveling weight
pen 4.0
oval fill 313, 20, 16, 16, fn ColorGray // Top center point
accel = gravity * sin(theta) / length / tempo
speed += accel / tempo
theta += speed
timerEnd
end fn
 
void local fn DoDialog( ev as long, tag as long, wnd as long )
select ( ev )
case _windowWillClose : end
end select
end fn
 
on dialog fn DoDialog
 
fn BuildWindow
fn AnimatedPendulum
 
HandleEvents
</syntaxhighlight>
[[File:Animated_Pendulum_FutureBasic2.gif]]
 
=={{header|Go}}==
Using {{libheader|GXUI}} from [https://github.com/google/gxui Github]
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,927 ⟶ 2,160:
func main() {
gl.StartDriver(appMain)
}</langsyntaxhighlight>
 
=={{header|Haskell}}==
{{libheader|HGL}}
<langsyntaxhighlight lang="haskell">import Graphics.HGL.Draw.Monad (Graphic, )
import Graphics.HGL.Draw.Picture
import Graphics.HGL.Utils
Line 1,958 ⟶ 2,191:
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)</langsyntaxhighlight>
 
Usage with <code>ghci</code>:
Line 1,966 ⟶ 2,199:
=== Alternative solution ===
{{libheader|Gloss}}
<langsyntaxhighlight lang="haskell">import Graphics.Gloss
 
-- Initial conditions
Line 2,016 ⟶ 2,249:
fps = round (1/dt)
render xs = pictures $ renderPendulum xs
update _ = movePendulum</langsyntaxhighlight>
 
=={{header|HicEst}}==
[http://www.HicEst.com/DIFFEQ.htm DIFFEQ] and the callback procedure pendulum numerically integrate the pendulum equation.
The display window can be resized during the run, but for window width not equal to 2*height the pendulum rod becomes a rubber band instead:
<langsyntaxhighlight HicEstlang="hicest">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
 
Line 2,053 ⟶ 2,286:
dTheta(1) = Theta(2) ! Theta' = Theta(2) substitution
dTheta(2) = -g/Lrod*SIN(Theta(1)) ! Theta" = Theta(2)' = -g/Lrod*SIN(Theta(1))
END</langsyntaxhighlight>
 
== Icon and {{header|Unicon}} ==
Line 2,061 ⟶ 2,294:
{{trans|Scheme}}
 
<syntaxhighlight lang="unicon">
<lang Unicon>
import gui
$include "guih.icn"
Line 2,155 ⟶ 2,388:
w.show_modal ()
end
</syntaxhighlight>
</lang>
 
=={{header|J}}==
Works for '''J6'''
<langsyntaxhighlight lang="j">require 'gl2 trig'
coinsert 'jgl2'
 
Line 2,201 ⟶ 2,434:
)
 
pend_run'' NB. run animation</langsyntaxhighlight>
Updated for changes in '''J8'''
<langsyntaxhighlight lang="j">require 'gl2 trig'
coinsert 'jgl2'
Line 2,254 ⟶ 2,487:
)
 
pend_run''</langsyntaxhighlight>
 
[[File:J_pendulum.gif|320px|pretend the ball is yellow - gifgrabber grabbed a monochrome image for some reason...]]
Line 2,260 ⟶ 2,493:
=={{header|Java}}==
{{libheader|Swing}} {{libheader|AWT}}
<langsyntaxhighlight lang="java">import java.awt.*;
import javax.swing.*;
 
Line 2,311 ⟶ 2,544:
new Thread(p).start();
}
}</langsyntaxhighlight>
 
=={{header|JavaScript}}==
Line 2,317 ⟶ 2,550:
{{trans|E}} (plus gratuitous motion blur)
 
<langsyntaxhighlight lang="javascript"><html><head>
<title>Pendulum</title>
</head><body style="background: gray;">
Line 2,374 ⟶ 2,607:
</script>
 
</body></html></langsyntaxhighlight>
 
===WithWithin &lt;SVG&gt;===
If we use SVG we don't even have to make a HTML document. We can put the script inside SVG.
With some control elements to ease the usage.
 
<lang javascript><html>
To do things a bit differently, we'll use a [[wp:stereographic projection|stereographic projection]] of the circle, in order to get algebraic [[wp:Euler-Lagrange equations|Euler-Lagrange equations]] which we'll integrate with the [[Runge-Kutta method]].
<head>
 
<title>Swinging Pendulum Simulation</title>
Also we'll use a dimensionless formulation of the problem (taking unit value for the mass, the length and so on).
</head>
 
<body><center>
<svgsyntaxhighlight idlang="scenejavascript"><svg height="200100%" width="300100%" viewBox="-2 0 4 4" xmlns="http://www.w3.org/2000/svg">
<line id="string" x1="1500" y1="500" x2="2501" y2="500" stroke="browngrey" stroke-width="40.05" />
<circle id="ball" cx="2500" cy="500" r="200.1" fill="black" />
<script>
</svg>
/*jshint esnext: true */
<br>
 
Initial angle:<input id="in_angle" type="number" min="0" max="180" onchange="condReset()"/>(degrees)
function rk4(dt, x, f) {
<br>
"use strict";
<button type="button" onclick="startAnimation()">Start</button>
let from = Array.from,
<button type="button" onclick="stopAnimation()">Stop</button>
a = from(f(from(x, $ => $ )), $ => $*dt),
<button type="button" onclick="reset()">Reset</button>
b = from(f(from(x, ($,i) => $ + a[i]/2)), $ => $*dt),
<script>
c = from(f(from(x, ($,i) => $ + b[i]/2)), $ => $*dt),
in_angle.value = 0;
d = from(f(from(x, ($,i) => $ + c[i] )), $ => $*dt);
var cx = 150, cy = 50;
return from(x, (_,i) => (a[i] + 2*b[i] + 2*c[i] + d[i])/6);
var radius = 100; // cm
}
var g = 9.81; // m/s^2
 
var angle = 0; // radians
function setPendulumPos($) {
var vel = 0; // m/s
const string = document.getElementById("string"),
var dx = 0.02; // s
ball = document.getElementById("ball");
var acc, vel, penx, peny;
let $2 = $*$,
var timerFunction = null;
x = 2*$/(1+$2),
function stopAnimation() {
y = (1-$2)/(1+$2);
if(timerFunction != null){
string.setAttribute("x2", x);
clearInterval(timerFunction);
string.setAttribute("y2", y);
timerFunction = null;
ball.setAttribute("cx", x);
}
ball.setAttribute("cy", y);
}
}
function startAnimation() {
 
if(!timerFunction) timerFunction = setInterval(swing, dx * 1000);
var q = [1, 0];
}
var previousTimestamp;
function swing(){
(function animate(timestamp) {
acc = g * Math.cos(angle);
if ( previousTimestamp !== undefined) {
vel += acc * dx;//Convert m/s/s to m/s
let dq = rk4((timestamp - previousTimestamp)/1000, q, $ => [$[1], 2*$[1]*$[1]*$[0]/(1+$[0]*$[0]) - $[0]]);
angle += vel/(radius/100) * dx; //convert m/s into rad/s and then into rad
q = [q[0] + dq[0], q[1] + dq[1]];
setPenPos();
setPendulumPos(q[0]);
}
}
function setPenPos(){
previousTimestamp = timestamp;
penx = cx + radius * Math.cos(angle);
window.requestAnimationFrame(animate);
peny = cy + radius * Math.sin(angle);
})()
scene.getElementById("string").setAttribute("x2", penx);
</script>
scene.getElementById("string").setAttribute("y2", peny);
</svg>
scene.getElementById("ball").setAttribute("cx", penx);
</syntaxhighlight>
scene.getElementById("ball").setAttribute("cy", peny);
}
function reset(){
var val = parseInt(in_angle.value)*0.0174532925199;
if (val) angle = val;
else angle = 0;
acc = 0;
vel = 0;
setPenPos();
}
function condReset(){
if (!timerFunction) reset();
}
</script>
</body>
</html></lang>
 
=={{header|Julia}}==
Differential equation based solution using the Luxor graphics library.<langsyntaxhighlight lang="julia">using Luxor
using Colors
using BoundaryValueDiffEq
Line 2,487 ⟶ 2,705:
animate(muv, [Scene(muv, backdrop),
Scene(muv, frame, easingfunction=easeinoutcubic)],
creategif=true, pathname=giffilename)</syntaxhighlight>
{{out}}
</lang>
[[File:Pendulum animation.gif|320px]]
<pre>
</pre>
 
=={{header|Kotlin}}==
Conversion of Java snippet.
<langsyntaxhighlight lang="scala">import java.awt.*
import java.util.concurrent.*
import javax.swing.*
Line 2,537 ⟶ 2,758:
val executor = Executors.newSingleThreadScheduledExecutor()
executor.scheduleAtFixedRate(Pendulum(200), 0, 15, TimeUnit.MILLISECONDS)
}</langsyntaxhighlight>
 
=={{header|Liberty BASIC}}==
<langsyntaxhighlight lang="lb">nomainwin
WindowWidth = 400
WindowHeight = 300
Line 2,581 ⟶ 2,802:
[quit.main]
close #main
end</langsyntaxhighlight>
 
=={{header|Lingo}}==
<langsyntaxhighlight Lingolang="lingo">global RODLEN, GRAVITY, DT
global velocity, acceleration, angle, posX, posY
Line 2,626 ⟶ 2,847:
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</langsyntaxhighlight>
 
=={{header|Logo}}==
{{works with|UCB Logo}}
<langsyntaxhighlight lang="logo">make "angle 45
make "L 1
make "bob 10
Line 2,658 ⟶ 2,879:
 
hideturtle
until [key?] [step.pendulum]</langsyntaxhighlight>
 
=={{header|Lua}}==
Needs L&Ouml;VE 2D Engine
<langsyntaxhighlight lang="lua">
function degToRad( d )
return d * 0.01745329251
Line 2,691 ⟶ 2,912:
g.circle( "fill", posX, posY, 20 )
end
</syntaxhighlight>
</lang>
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
<lang M2000 Interpreter>
Module Pendulum {
back()
Line 2,742 ⟶ 2,963:
}
Pendulum
</syntaxhighlight>
</lang>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">tmax = 10;
<lang Mathematica>freq = 8; length = freq^(-1/2);
g = 9.8;
Animate[Graphics[
l = 1;
List[{Line[{{0, 0}, length {Sin[T], -Cos[T]}} /. {T -> (Pi/6) Cos[2 Pi freq t]}], PointSize[Large],
pendulum = Module[
Point[{length {Sin[T], -Cos[T]}} /. {T -> (Pi/6) Cos[2 Pi freq t]}]}],
{g, l},
PlotRange -> {{-0.3, 0.3}, {-0.5, 0}}], {t, 0, 1}, AnimationRate -> 0.07]</lang>
ParametricNDSolve[
[[File:mmapendulum.gif]]
{
y''[t] + g/l Sin[y[t]] == 0,
y[0] == 0, y'[0] == 1
},
{y},
{t, 0, tmax},
{g, l}
]
];
Animate[
Graphics[
Rotate[
{Line[{{0, 0}, {0, -1}}], Disk[{0, -1}, .1]},
Evaluate[y[g, l] /. pendulum][t],
{0, 0}
],
PlotRange -> {{-l, l}, {-l - .5, 0}}
],
{t, 0, tmax},
AnimationRate -> 1
]</syntaxhighlight>
 
=={{header|MATLAB}}==
pendulum.m
<langsyntaxhighlight MATLABlang="matlab">%This is a numerical simulation of a pendulum with a massless pivot arm.
 
%% User Defined Parameters
Line 2,821 ⟶ 3,063:
[rodPivotPoint(2) position(2)]);
 
end</langsyntaxhighlight>
 
=={{header|Nim}}==
Line 2,831 ⟶ 3,073:
 
Conversion from C with some modifications: changing some variable names, adding a display function to make the program work with "freeGlut", choosing another initial angle, etc.
<langsyntaxhighlight Nimlang="nim"># Pendulum simulation.
 
import math
Line 2,937 ⟶ 3,179:
var argc: cint = 0
initGfx(addr(argc), nil)
glutMainLoop()</langsyntaxhighlight>
 
===Gtk3 version===
Line 2,944 ⟶ 3,186:
 
This version uses the same equations but replace OpenGL by Gtk3 with the “gintro” bindings.
<langsyntaxhighlight Nimlang="nim"># Pendulum simulation.
 
import math
Line 3,068 ⟶ 3,310:
let app = newApplication(Application, "Rosetta.pendulum")
discard app.connect("activate", activate)
discard app.run()</langsyntaxhighlight>
 
=={{header|ooRexx}}==
ooRexx does not have a portable GUI, but this version is similar to the Ada version and just prints out the coordinates of the end of the pendulum.
<syntaxhighlight lang="oorexx">
<lang ooRexx>
pendulum = .pendulum~new(10, 30)
 
Line 3,109 ⟶ 3,351:
::requires rxmath library
 
</syntaxhighlight>
</lang>
 
=={{header|Oz}}==
Inspired by the E and Ruby versions.
 
<langsyntaxhighlight lang="oz">declare
[QTk] = {Link ['x-oz://system/wp/QTk.ozf']}
 
Line 3,195 ⟶ 3,437:
{Window show}
{Animation go}
</syntaxhighlight>
</lang>
 
=={{header|Perl}}==
Line 3,205 ⟶ 3,447:
This does not have the window resizing handling that Tcl does.
 
<langsyntaxhighlight lang="perl">
use strict;
use warnings;
Line 3,271 ⟶ 3,513:
$canvas->bind('<Destroy>' => sub {$after_id->cancel});
MainLoop;</langsyntaxhighlight>
 
=={{header|Phix}}==
{{libheader|Phix/pGUI}}
{{libheader|Phix/online}}
You can run this online [http://phix.x10.mx/p2js/animate_pendulum2.htm here].
<!--<langsyntaxhighlight Phixlang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\animate_pendulum2animate_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,
Line 3,383 ⟶ 3,627:
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</langsyntaxhighlight>-->
 
=={{header|PicoLisp}}==
A minimalist solution. The pendulum consists of the center point '+', and the swinging xterm cursor.
<langsyntaxhighlight PicoLisplang="picolisp">(load "@lib/math.l")
 
(de pendulum (X Y Len)
Line 3,401 ⟶ 3,645:
(call 'tput "cup"
(+ Y (*/ Len (cos Angle) 2.2)) # Compensate for aspect ratio
(+ X (*/ Len (sin Angle) 1.0)) ) ) ) )</langsyntaxhighlight>
Test (hit any key to stop):
<syntaxhighlight lang PicoLisp="picolisp">(pendulum 40 1 36)</langsyntaxhighlight>
 
=={{header|Portugol}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="portugol">
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)
}
}
}
 
</syntaxhighlight>
 
=={{header|Prolog}}==
SWI-Prolog has a graphic interface XPCE.
<langsyntaxhighlight Prologlang="prolog">:- use_module(library(pce)).
 
pendulum :-
Line 3,487 ⟶ 3,782:
ND = - D;
ND = D).
</syntaxhighlight>
</lang>
 
=={{header|PureBasic}}==
If the code was part of a larger application it could be improved by specifying constants for the locations of image elements.
<langsyntaxhighlight PureBasiclang="purebasic">Procedure handleError(x, msg.s)
If Not x
MessageRequester("Error", msg)
Line 3,597 ⟶ 3,892:
Break
EndSelect
ForEver</langsyntaxhighlight>
 
=={{header|Python}}==
Line 3,603 ⟶ 3,898:
 
{{trans|C}}
<langsyntaxhighlight lang="python">import pygame, sys
from pygame.locals import *
from math import sin, cos, radians
Line 3,684 ⟶ 3,979:
while True:
input(pygame.event.get())
pygame.display.flip()</langsyntaxhighlight>
 
===Python: using tkinter===
<langsyntaxhighlight lang="python">
''' Python 3.6.5 code using Tkinter graphical user interface.'''
 
Line 3,776 ⟶ 4,071:
a = Animation(root)
root.mainloop()
</syntaxhighlight>
</lang>
 
=={{header|QB64}}==
<syntaxhighlight lang="qbasic">'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</syntaxhighlight>
 
 
=={{header|R}}==
<langsyntaxhighlight Rlang="r">library(DescTools)
 
pendulum<-function(length=5,radius=1,circle.color="white",bg.color="white"){
Line 3,801 ⟶ 4,195:
}
 
pendulum(5,1,"gold","lightblue")</langsyntaxhighlight>
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
 
Line 3,824 ⟶ 4,218:
 
(animate (pendulum))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
Line 3,831 ⟶ 4,225:
Handles window resizing, modifies pendulum length and period as window height changes. May need to tweek $ppi scaling to get good looking animation.
 
<syntaxhighlight lang="raku" perl6line>use SDL2::Raw;
use Cairo;
 
Line 3,920 ⟶ 4,314:
}
 
SDL_Quit();</langsyntaxhighlight>
 
=={{header|REXX}}==
Line 3,928 ⟶ 4,322:
this version is similar to the '''Ada''' version and just
<br>displays the coordinates of the end of the pendulum.
<langsyntaxhighlight lang="rexx">/*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.*/
Line 3,958 ⟶ 4,352:
/*──────────────────────────────────────────────────────────────────────────────────────*/
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</langsyntaxhighlight>
Programming note: &nbsp; the &nbsp; '''SIN''' &nbsp; and &nbsp; '''COS''' &nbsp; functions above are abridged versions.
 
Line 4,029 ⟶ 4,423:
 
=={{header|Ring}}==
<langsyntaxhighlight lang="ring">
# Project : Animate a pendulum
 
Line 4,109 ⟶ 4,503:
paint.drawline(pivotx, pivoty, bobx, boby)
paint.drawellipse(bobx + 24 * sin(a), boby - 24 * cos(a), 24, 24)
</syntaxhighlight>
</lang>
 
Output video:
Line 4,141 ⟶ 4,535:
The RLaB script that solves the problem is
 
<syntaxhighlight lang="rlab">
<lang RLaB>
//
// example: solve ODE for pendulum
Line 4,202 ⟶ 4,596:
}
 
</syntaxhighlight>
</lang>
 
=={{header|Ruby}}==
Line 4,215 ⟶ 4,609:
the Tcl pendulum swings noticibly faster.
 
<langsyntaxhighlight lang="ruby">require 'tk'
 
$root = TkRoot.new("title" => "Pendulum Animation")
Line 4,277 ⟶ 4,671:
$canvas.bind('<Destroy>') {$root.after_cancel($after_id)}
 
Tk.mainloop</langsyntaxhighlight>
 
==={{libheader|Shoes}}===
<langsyntaxhighlight lang="ruby">Shoes.app(:width => 320, :height => 200) do
@centerX = 160
@centerY = 25
Line 4,336 ⟶ 4,730:
@Theta = lastTheta
end
end</langsyntaxhighlight>
 
==={{libheader|Ruby/Gosu}}===
<langsyntaxhighlight lang="ruby">#!/bin/ruby
 
begin; require 'rubygems'; rescue; end
Line 4,442 ⟶ 4,836:
puts e.message, e.backtrace
gets
end</langsyntaxhighlight>
 
=={{header|Rust}}==
Line 4,451 ⟶ 4,845:
 
{{libheader|piston_window}}
<syntaxhighlight lang="rust">
<lang Rust>
// using version 0.107.0 of piston_window
use piston_window::{clear, ellipse, line_from_to, PistonWindow, WindowSettings};
Line 4,509 ⟶ 4,903:
}
}
</syntaxhighlight>
</lang>
 
=={{header|Scala}}==
{{libheader|Scala}}
<langsyntaxhighlight Scalalang="scala">import java.awt.Color
import java.util.concurrent.{Executors, TimeUnit}
 
Line 4,567 ⟶ 4,961:
scheduleAtFixedRate(ui.animate, 0, 15, TimeUnit.MILLISECONDS)
}
}</langsyntaxhighlight>
 
=={{header|Scheme}}==
Line 4,576 ⟶ 4,970:
This is a direct translation of the Ruby/Tk example into Scheme + PS/Tk.
 
<langsyntaxhighlight lang="scheme">#!r6rs
 
;;; R6RS implementation of Pendulum Animation
Line 4,647 ⟶ 5,041:
(tk/after 500 animate)
(tk-event-loop tk)))
</syntaxhighlight>
</lang>
 
Another version using gauche scheme:
 
<syntaxhighlight lang="scheme">
#!/usr/bin/env gosh
#| -*- mode: scheme; coding: utf-8; -*- |#
(use gl)
(use gl.glut)
(use gl.simple.viewer)
(use math.const)
(define (deg->rad degree) (* (/ degree 180) pi))
(define (rad->deg radians) (* (/ radians pi) 180))
(define (main args)
(glut-init args)
(let* ((φ (deg->rad 179)) (l 0.5) (bob 0.02) (q (make <glu-quadric>))
(draw-pendulum (lambda()
(gl-push-matrix*
(gl-scale 4 4 4)
(gl-translate 0 l 0)
(gl-rotate (rad->deg φ) 0 0 1)
(gl-begin GL_LINES)
(gl-vertex 0 0)
(gl-vertex 0 (- l))
(gl-end)
(gl-translate 0 (- l) 0)
(glu-sphere q bob 10 10))))
(g 9.81)
(φ̇ 0)
(euler-step (lambda(h)
(inc! φ̇ (* (- (* (/ g l) (sin φ))) h))
(inc! φ (* φ̇ h)))))
(simple-viewer-display
(lambda ()
;; I hope sync to VBLANK aka VSYNC works and the display has ~60Hz
(euler-step 1/60)
(draw-pendulum)
(glut-post-redisplay))))
(simple-viewer-window 'pendulum)
(glut-full-screen)
(simple-viewer-run :rescue-errors #f))
 
</syntaxhighlight>
 
=={{header|Scilab}}==
The animation is displayed on a graphic window, and won't stop until it shows all positions calculated unless the user abort the execution on Scilab console.
<syntaxhighlight lang="text">//Input variables (Assumptions: massless pivot, no energy loss)
bob_mass=10;
g=-9.81;
Line 4,735 ⟶ 5,171:
sleep(deltaT*1000)
end
clear i</langsyntaxhighlight>
 
=={{header|SequenceL}}==
{{libheader|EaselSL}}
Using the [https://github.com/bethune-bryant/Easel Easel Engine for SequenceL] <br>
<langsyntaxhighlight lang="sequencel">import <Utilities/Sequence.sl>;
import <Utilities/Conversion.sl>;
import <Utilities/Math.sl>;
Line 4,807 ⟶ 5,243:
point(x, y);
 
//=============End=Easel=Functions=============================================</langsyntaxhighlight>
 
{{out}}
Line 4,814 ⟶ 5,250:
=={{header|Sidef}}==
{{trans|Perl}}
<langsyntaxhighlight lang="ruby">require('Tk')
 
var root = %s<MainWindow>.new('-title' => 'Pendulum Animation')
Line 4,874 ⟶ 5,310:
 
canvas.bind('<Destroy>' => { after_id.cancel })
%S<Tk>.MainLoop()</langsyntaxhighlight>
 
=={{header|smart BASIC}}==
<langsyntaxhighlight lang="smart BASICbasic">'Pendulum
'By Dutchman
' --- constants
Line 4,912 ⟶ 5,348:
REFRESH ON
RETURN
</syntaxhighlight>
</lang>
<pre>
We hope that the webmaster will soon have image uploads enabled again so that we can show a screen shot.
Line 4,920 ⟶ 5,356:
{{works with|Tcl|8.5}}
==={{libheader|Tk}}===
<langsyntaxhighlight lang="tcl">package require Tcl 8.5
package require Tk
 
Line 4,999 ⟶ 5,435:
bind .c <Configure> {resized %w}
# Callback to stop the animation cleanly when the GUI goes away
bind .c <Destroy> {after cancel $animation}</langsyntaxhighlight>
 
=={{header|VBScript}}==
Well, VbScript does'nt have a graphics mode so this is a wobbly textmode pandulum. It should be called from cscript.
<syntaxhighlight lang="vb">
option explicit
 
const dt = 0.15
const length=23
dim ans0:ans0=chr(27)&"["
dim Veloc,Accel,angle,olr,olc,r,c
const r0=1
const c0=40
cls
angle=0.7
while 1
wscript.sleep(50)
Accel = -.9 * sin(Angle)
Veloc = Veloc + Accel * dt
Angle = Angle + Veloc * dt
r = r0 + int(cos(Angle) * Length)
c = c0+ int(2*sin(Angle) * Length)
cls
draw_line r,c,r0,c0
toxy r,c,"O"
 
olr=r :olc=c
wend
 
sub cls() wscript.StdOut.Write ans0 &"2J"&ans0 &"?25l":end sub
sub toxy(r,c,s) wscript.StdOut.Write ans0 & r & ";" & c & "f" & s :end sub
 
Sub draw_line(r1,c1, r2,c2) 'Bresenham's line drawing
Dim x,y,xf,yf,dx,dy,sx,sy,err,err2
x =r1 : y =c1
xf=r2 : yf=c2
dx=Abs(xf-x) : dy=Abs(yf-y)
If x<xf Then sx=+1: Else sx=-1
If y<yf Then sy=+1: Else sy=-1
err=dx-dy
Do
toxy x,y,"."
If x=xf And y=yf Then Exit Do
err2=err+err
If err2>-dy Then err=err-dy: x=x+sx
If err2< dx Then err=err+dx: y=y+sy
Loop
End Sub 'draw_line
</syntaxhighlight>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|DOME}}
{{libheader|Wren-dynamic}}
<syntaxhighlight lang="wren">import "graphics" for Canvas, Color
import "dome" for Window
import "math" for Math
import "./dynamic" for Tuple
 
var Element = Tuple.create("Element", ["x", "y"])
var Dt = 0.1
var Angle = Num.pi / 2
var AngleVelocity = 0
 
class Pendulum {
construct new(length) {
Window.title = "Pendulum"
_w = 2 * length + 50
_h = length / 2 * 3
Window.resize(_w, _h)
Canvas.resize(_w, _h)
_length = length
_anchor = Element.new((_w/2).floor, (_h/4).floor)
_fore = Color.black
}
 
init() {
drawPendulum()
}
 
drawPendulum() {
Canvas.cls(Color.white)
var ball = Element.new((_anchor.x + Math.sin(Angle) * _length).truncate,
(_anchor.y + Math.cos(Angle) * _length).truncate)
Canvas.line(_anchor.x, _anchor.y, ball.x, ball.y, _fore, 2)
Canvas.circlefill(_anchor.x - 3, _anchor.y - 4, 7, Color.lightgray)
Canvas.circle(_anchor.x - 3, _anchor.y - 4, 7, _fore)
Canvas.circlefill(ball.x - 7, ball.y - 7, 14, Color.yellow)
Canvas.circle(ball.x - 7, ball.y - 7, 14, _fore)
}
 
update() {
AngleVelocity = AngleVelocity - 9.81 / _length * Math.sin(Angle) * Dt
Angle = Angle + AngleVelocity * Dt
}
 
draw(alpha) {
drawPendulum()
}
}
 
var Game = Pendulum.new(200)</syntaxhighlight>
 
=={{header|XPL0}}==
<langsyntaxhighlight XPL0lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
 
proc Ball(X0, Y0, R, C); \Draw a filled circle
Line 5,037 ⟶ 5,575:
until KeyHit; \keystroke terminates program
SetVid(3); \restore normal text screen
]</langsyntaxhighlight>
 
=={{header|Yabasic}}==
<langsyntaxhighlight Yabasiclang="yabasic">clear screen
open window 400, 300
window origin "cc"
Line 5,066 ⟶ 5,604:
until(lower$(inkey$(0.02)) = "q")
 
exit</langsyntaxhighlight>
 
=={{header|Zig}}==
{{libheader|Raylib}}
{{works with|Zig|0.11.0dev}} {{works with|Raylib|4.6dev}}
{{trans|Nim}}
<syntaxhighlight lang="zig">const math = @import("std").math;
const c = @cImport({
@cInclude("raylib.h");
});</syntaxhighlight>
<syntaxhighlight lang="zig">pub fn main() void {
c.SetConfigFlags(c.FLAG_VSYNC_HINT);
c.InitWindow(640, 320, "Pendulum");
defer c.CloseWindow();
 
// Simulation constants.
const g = 9.81; // Gravity (should be positive).
const length = 5.0; // Pendulum length.
const theta0 = math.pi / 3.0; // Initial angle for which omega = 0.
 
const e = g * length * (1 - @cos(theta0)); // Total energy = potential energy when starting.
 
// Simulation variables.
var theta: f32 = theta0; // Current angle.
var omega: f32 = 0; // Angular velocity = derivative of theta.
var accel: f32 = -g / length * @sin(theta0); // Angular acceleration = derivative of omega.
 
c.SetTargetFPS(60);
 
while (!c.WindowShouldClose()) // Detect window close button or ESC key
{
const half_width = @as(f32, @floatFromInt(c.GetScreenWidth())) / 2;
const pivot = c.Vector2{ .x = half_width, .y = 0 };
 
// Compute the position of the mass.
const mass = c.Vector2{
.x = 300 * @sin(theta) + pivot.x,
.y = 300 * @cos(theta),
};
 
{
c.BeginDrawing();
defer c.EndDrawing();
 
c.ClearBackground(c.RAYWHITE);
 
c.DrawLineV(pivot, mass, c.GRAY);
c.DrawCircleV(mass, 20, c.GRAY);
}
 
// Update theta and omega.
const dt = c.GetFrameTime();
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 (length * g * (1 - @cos(theta)) >= e) {
theta = math.sign(theta) * theta0;
omega = 0;
}
accel = -g / length * @sin(theta);
}
}</syntaxhighlight>
 
=={{header|ZX Spectrum Basic}}==
{{trans|ERRE}}
In a real Spectrum it is too slow. Use the BasinC emulator/editor at maximum speed for realistic animation.
<langsyntaxhighlight lang="zxbasic">10 OVER 1: CLS
20 LET theta=1
30 LET g=9.81
Line 5,087 ⟶ 5,688:
1000 PLOT pivotx,pivoty: DRAW bobx-pivotx,boby-pivoty
1010 CIRCLE bobx,boby,3
1020 RETURN</langsyntaxhighlight>
 
 
{{omit from|LFE}}
Line 5,094 ⟶ 5,696:
{{omit from|PHP}}
{{omit from|SQL PL|It does not handle GUI}}
 
[[Category:Animation]]
9,476

edits