Animate a pendulum: Difference between revisions

m
→‎{{header|Wren}}: Changed to Wren S/H
m (Automated syntax highlighting fixup (second round - minor fixes))
m (→‎{{header|Wren}}: Changed to Wren S/H)
 
(12 intermediate revisions by 6 users not shown)
Line 1,162:
[https://easylang.online/apps/pendulum.html Run it]
 
<syntaxhighlight lang="text">onang animate= 45
on animate
clear
move 50 50
circle 1
x = 50 + 40 * sin ang
y = 50 -+ 40 * cos ang
line x y
circle 56
vel += sin ang / 5
ang += vel
.
ang = 45</syntaxhighlight>
 
=={{header|Elm}}==
Line 1,990 ⟶ 1,991:
}
</syntaxhighlight>
 
=={{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}}==
Line 2,653 ⟶ 2,705:
animate(muv, [Scene(muv, backdrop),
Scene(muv, frame, easingfunction=easeinoutcubic)],
creategif=true, pathname=giffilename)</syntaxhighlight>
{{out}}
</syntaxhighlight>
[[File:Pendulum animation.gif|320px]]
<pre>
</pre>
 
=={{header|Kotlin}}==
Line 2,911 ⟶ 2,966:
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">freqtmax = 8; length = freq^(-1/2)10;
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]</syntaxhighlight>
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}}==
Line 4,965 ⟶ 5,041:
(tk/after 500 animate)
(tk-event-loop tk)))
</syntaxhighlight>
 
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>
 
Line 5,372 ⟶ 5,490:
{{libheader|DOME}}
{{libheader|Wren-dynamic}}
<syntaxhighlight lang="ecmascriptwren">import "graphics" for Canvas, Color
import "dome" for Window
import "math" for Math
Line 5,487 ⟶ 5,605:
 
exit</syntaxhighlight>
 
=={{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}}==
9,476

edits