September 2017 Update
This commit is contained in:
parent
bba7bfd280
commit
ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions
|
|
@ -14,15 +14,15 @@ pendulum = runGraphics $
|
|||
(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)
|
||||
(\ (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
|
||||
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)
|
||||
$ iterate nextAVT (- (g / l) * sin t, t, 0)
|
||||
51
Task/Animate-a-pendulum/Haskell/animate-a-pendulum-2.hs
Normal file
51
Task/Animate-a-pendulum/Haskell/animate-a-pendulum-2.hs
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import Graphics.Gloss
|
||||
|
||||
-- Initial conditions
|
||||
g_ = (-9.8) :: Float --Gravity acceleration
|
||||
v_0 = 0 :: Float --Initial tangential speed
|
||||
a_0 = 0 / 180 * pi :: Float --Initial angle
|
||||
dt = 0.01 :: Float --Time step
|
||||
t_f = 15 :: Float --Final time for data logging
|
||||
l_ = 200 :: Float --Rod length
|
||||
|
||||
-- Define a type to represent the pendulum:
|
||||
type Pendulum = (Float, Float, Float) -- (rod length, tangential speed, angle)
|
||||
|
||||
-- Pendulum's initial state
|
||||
initialstate :: Pendulum
|
||||
initialstate = (l_, v_0, a_0)
|
||||
|
||||
-- Step funtion: update pendulum to new position
|
||||
movePendulum :: Float -> Pendulum -> Pendulum
|
||||
movePendulum dt (l,v,a) = ( l , v_2 , a + v_2 / l * dt*10 )
|
||||
where v_2 = v + g_ * (cos a) * dt
|
||||
|
||||
-- Convert from Pendulum to [Picture] for display
|
||||
renderPendulum :: Pendulum -> [Picture]
|
||||
renderPendulum (l,v,a) = map (uncurry Translate newOrigin)
|
||||
[ Line [ ( 0 , 0 ) , ( l * (cos a), l * (sin a) ) ]
|
||||
, polygon [ ( 0 , 0 ) , ( -5 , 8.66 ) , ( 5 , 8.66 ) ]
|
||||
, Translate ( l * (cos a)) (l * (sin a)) (circleSolid (0.04*l_))
|
||||
, Translate (-1.1*l) (-1.3*l) (Scale 0.1 0.1 (Text currSpeed))
|
||||
, Translate (-1.1*l) (-1.3*l + 20) (Scale 0.1 0.1 (Text currAngle))
|
||||
]
|
||||
where currSpeed = "Speed (pixels/s) = " ++ (show v)
|
||||
currAngle = "Angle (deg) = " ++ (show ( 90 + a / pi * 180 ) )
|
||||
|
||||
-- New origin to beter display the animation
|
||||
newOrigin = (0, l_ / 2)
|
||||
|
||||
-- Calcule a proper window size (for angles between 0 and -pi)
|
||||
windowSize :: (Int, Int)
|
||||
windowSize = ( 300 + 2 * round (snd newOrigin)
|
||||
, 200 + 2 * round (snd newOrigin) )
|
||||
|
||||
-- Run simulation
|
||||
main :: IO ()
|
||||
main = do --plotOnGNU
|
||||
simulate window background fps initialstate render update
|
||||
where window = InWindow "Animate a pendulum" windowSize (40, 40)
|
||||
background = white
|
||||
fps = round (1/dt)
|
||||
render xs = pictures $ renderPendulum xs
|
||||
update _ = movePendulum
|
||||
28
Task/Animate-a-pendulum/Lua/animate-a-pendulum.lua
Normal file
28
Task/Animate-a-pendulum/Lua/animate-a-pendulum.lua
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
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
|
||||
35
Task/Animate-a-pendulum/OoRexx/animate-a-pendulum.rexx
Normal file
35
Task/Animate-a-pendulum/OoRexx/animate-a-pendulum.rexx
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
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
|
||||
|
|
@ -1,68 +1,76 @@
|
|||
include ..\arwen\arwen.ew
|
||||
include ..\arwen\axtra.ew
|
||||
--
|
||||
-- demo\rosetta\animate_pendulum2.exw
|
||||
-- ==================================
|
||||
--
|
||||
include pGUI.e
|
||||
|
||||
constant main = create(Window, "Animated Pendulum", 0, 0, 20, 20, 625, 690, 0),
|
||||
mainDC = getPrivateDC(main),
|
||||
backDC = c_func(xCreateCompatibleDC, {NULL}), -- the background
|
||||
viewDC = c_func(xCreateCompatibleDC, {NULL}), -- with animation
|
||||
grey = #909090
|
||||
Ihandle dlg, canvas, timer
|
||||
cdCanvas cddbuffer, cdcanvas
|
||||
|
||||
constant MainTimer = createTimer()
|
||||
|
||||
integer dw = 0, dh = 0 -- client area width and height
|
||||
atom bmBack, bmView
|
||||
integer bmX = 0, bmY = 0 -- actual size of the bitmaps
|
||||
|
||||
constant dt = 1E-3
|
||||
constant g = 50
|
||||
|
||||
integer sX = 0, sY = 0 -- suspension point of pendulum
|
||||
integer len
|
||||
atom alpha = PI/2,
|
||||
omega = 0,
|
||||
epsilon
|
||||
omega = 0
|
||||
|
||||
function mainHandler(integer id, integer msg, atom wParam, object lParam)
|
||||
integer eX, eY -- moving end of pendulum
|
||||
if msg=WM_SIZE then
|
||||
{{},{},dw,dh} = getClientRect(main)
|
||||
if dw>bmX or dh>bmY then
|
||||
-- we need bigger bitmaps
|
||||
bmBack = c_func(xCreateCompatibleBitmap, {mainDC, dw, dh})
|
||||
{} = deleteObject(selectObject(backDC,bmBack))
|
||||
-- clear the background
|
||||
setPenColor(grey)
|
||||
drawRectangleh(backDC, True, 0, 0, dw, dh)
|
||||
bmView = c_func(xCreateCompatibleBitmap, {mainDC, dw, dh})
|
||||
{} = deleteObject(selectObject(viewDC,bmView))
|
||||
{bmX,bmY} = {dw,dh}
|
||||
end if
|
||||
-- new suspension point and length
|
||||
sX = floor(dw/2)
|
||||
sY = floor(dh/8)
|
||||
len = sX-20
|
||||
elsif msg=WM_PAINT then
|
||||
-- start with a fresh copy of the background
|
||||
void = c_func(xBitBlt,{viewDC,0,0,dw,dh,backDC,0,0,SRCCOPY})
|
||||
eX = floor(len*sin(alpha)+sX)
|
||||
eY = floor(len*cos(alpha)+sY)
|
||||
drawLinesh(viewDC,{Red,{sX,sY,eX,eY},Yellow})
|
||||
drawEllipseh(viewDC,eX-5,eY-5,eX+5,eY+5)
|
||||
void = c_func(xBitBlt,{mainDC,0,0,dw,dh,viewDC,0,0,SRCCOPY})
|
||||
elsif msg=WM_TIMER then
|
||||
epsilon = -len*sin(alpha)*g
|
||||
omega += dt*epsilon
|
||||
alpha += dt*omega
|
||||
repaintWindow(main)
|
||||
elsif msg=WM_SHOWWINDOW then
|
||||
startTimer(MainTimer,main,33)
|
||||
elsif msg=WM_CHAR
|
||||
and wParam=VK_ESCAPE then
|
||||
closeWindow(main)
|
||||
if id or object(lParam) then end if -- suppress warnings
|
||||
end if
|
||||
return 0
|
||||
function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/)
|
||||
integer {w, h} = IupGetIntInt(canvas, "DRAWSIZE")
|
||||
cdCanvasActivate(cddbuffer)
|
||||
cdCanvasClear(cddbuffer)
|
||||
-- new suspension point and length
|
||||
integer sX = floor(w/2)
|
||||
integer sY = floor(h/8)
|
||||
integer len = sX-30
|
||||
atom dt = 1/w
|
||||
-- move:
|
||||
atom epsilon = -len*sin(alpha)*g
|
||||
omega += dt*epsilon
|
||||
alpha += dt*omega
|
||||
-- repaint:
|
||||
integer eX = floor(len*sin(alpha)+sX)
|
||||
integer eY = floor(len*cos(alpha)+sY)
|
||||
cdCanvasSetForeground(cddbuffer, CD_DARK_GREY)
|
||||
cdCanvasLine(cddbuffer, sX, h-sY, eX, h-eY)
|
||||
cdCanvasSetForeground(cddbuffer, CD_BLACK)
|
||||
cdCanvasSector(cddbuffer, eX, h-eY, 35, 35, 0, 360)
|
||||
cdCanvasFlush(cddbuffer)
|
||||
return IUP_DEFAULT
|
||||
end function
|
||||
setHandler({main},routine_id("mainHandler"))
|
||||
|
||||
WinMain(main, SW_NORMAL)
|
||||
function timer_cb(Ihandle /*ih*/)
|
||||
IupUpdate(canvas)
|
||||
return IUP_IGNORE
|
||||
end function
|
||||
|
||||
function map_cb(Ihandle ih)
|
||||
cdcanvas = cdCreateCanvas(CD_IUP, ih)
|
||||
cddbuffer = cdCreateCanvas(CD_DBUFFER, cdcanvas)
|
||||
cdCanvasSetBackground(cddbuffer, CD_GREY)
|
||||
return IUP_DEFAULT
|
||||
end function
|
||||
|
||||
function esc_close(Ihandle /*ih*/, atom c)
|
||||
if c=K_ESC then return IUP_CLOSE end if
|
||||
return IUP_CONTINUE
|
||||
end function
|
||||
|
||||
procedure main()
|
||||
IupOpen()
|
||||
|
||||
canvas = IupCanvas(NULL)
|
||||
IupSetAttribute(canvas, "RASTERSIZE", "640x380")
|
||||
IupSetCallback(canvas, "MAP_CB", Icallback("map_cb"))
|
||||
IupSetCallback(canvas, "ACTION", Icallback("redraw_cb"))
|
||||
|
||||
timer = IupTimer(Icallback("timer_cb"), 20)
|
||||
|
||||
dlg = IupDialog(canvas)
|
||||
IupSetAttribute(dlg, "TITLE", "Animated Pendulum")
|
||||
IupSetCallback(dlg, "K_ANY", Icallback("esc_close"))
|
||||
|
||||
IupShow(dlg)
|
||||
IupSetAttribute(canvas, "RASTERSIZE", NULL)
|
||||
IupMainLoop()
|
||||
IupClose()
|
||||
end procedure
|
||||
|
||||
main()
|
||||
|
|
|
|||
85
Task/Animate-a-pendulum/Scilab/animate-a-pendulum.scilab
Normal file
85
Task/Animate-a-pendulum/Scilab/animate-a-pendulum.scilab
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
//Input variables (Assumptions: massless pivot, no energy loss)
|
||||
bob_mass=10;
|
||||
g=-9.81;
|
||||
L=2;
|
||||
theta0=-%pi/6;
|
||||
v0=0;
|
||||
t0=0;
|
||||
|
||||
//No. of steps
|
||||
steps=300;
|
||||
|
||||
//Setting deltaT or duration (comment either of the lines below)
|
||||
//deltaT=0.1; t_max=t0+deltaT*steps;
|
||||
t_max=5; deltaT=(t_max-t0)/steps;
|
||||
|
||||
if t_max<=t0 then
|
||||
error("Check duration (t0 and t_f), number of steps and deltaT.");
|
||||
end
|
||||
|
||||
//Initial position
|
||||
not_a_pendulum=%F;
|
||||
t=zeros(1,steps); t(1)=t0; //time
|
||||
theta=zeros(1,steps); theta(1)=theta0; //angle
|
||||
F=zeros(1,steps); F(1)=bob_mass*g*sin(theta0); //force
|
||||
A=zeros(1,steps); A(1)=F(1)/bob_mass; //acceleration
|
||||
V=zeros(1,steps); V(1)=v0; //linear speed
|
||||
W=zeros(1,steps); W(1)=v0/L; //angular speed
|
||||
|
||||
for i=2:steps
|
||||
t(i)=t(i-1)+deltaT;
|
||||
V(i)=A(i-1)*deltaT+V(i-1);
|
||||
W(i)=V(i)/L;
|
||||
theta(i)=theta(i-1)+W(i)*deltaT;
|
||||
F(i)=bob_mass*g*sin(theta(i));
|
||||
A(i)=F(i)/bob_mass;
|
||||
if (abs(theta(i))>=%pi | (abs(theta(i))==0 & V(i)==0)) & ~not_a_pendulum then
|
||||
disp("Initial conditions do not describe a pendulum.");
|
||||
not_a_pendulum = %T;
|
||||
end
|
||||
end
|
||||
clear i
|
||||
|
||||
//Ploting the pendulum
|
||||
bob_r=0.08*L;
|
||||
bob_shape=bob_r*exp(%i.*linspace(0,360,20)/180*%pi);
|
||||
|
||||
bob_pos=zeros(20,steps);
|
||||
rod_pos=zeros(1,steps);
|
||||
for i=1:steps
|
||||
rod_pos(i)=L*exp(%i*(-%pi/2+theta(i)));
|
||||
bob_pos(:,i)=bob_shape'+rod_pos(i);
|
||||
end
|
||||
clear i
|
||||
|
||||
scf(0); clf(); xname("Simple gravity pendulum");
|
||||
plot2d(real([0 rod_pos(1)]),imag([0 rod_pos(1)]));
|
||||
axes=gca();
|
||||
axes.isoview="on";
|
||||
axes.children(1).children.mark_style=3;
|
||||
axes.children(1).children.mark_size=1;
|
||||
axes.children(1).children.thickness=3;
|
||||
|
||||
plot2d(real(bob_pos(:,1)),imag(bob_pos(:,1)));
|
||||
axes=gca();
|
||||
axes.children(1).children.fill_mode="on";
|
||||
axes.children(1).children.foreground=2;
|
||||
axes.children(1).children.background=2;
|
||||
|
||||
if max(imag(bob_pos))>0 then
|
||||
axes.data_bounds=[-L-bob_r,-L-1.01*bob_r;L+bob_r,max(imag(bob_pos))];
|
||||
else
|
||||
axes.data_bounds=[-L-bob_r,-L-1.01*bob_r;L+bob_r,bob_r];
|
||||
end
|
||||
|
||||
|
||||
|
||||
//Animating the plot
|
||||
disp("Duration: "+string(max(t)+deltaT-t0)+"s.");
|
||||
sleep(850);
|
||||
for i=2:steps
|
||||
axes.children(1).children.data=[real(bob_pos(:,i)), imag(bob_pos(:,i))];
|
||||
axes.children(2).children.data=[0, 0; real(rod_pos(i)), imag(rod_pos(i))];
|
||||
sleep(deltaT*1000)
|
||||
end
|
||||
clear i
|
||||
35
Task/Animate-a-pendulum/Smart-BASIC/animate-a-pendulum.smart
Normal file
35
Task/Animate-a-pendulum/Smart-BASIC/animate-a-pendulum.smart
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
'Pendulum
|
||||
'By Dutchman
|
||||
' --- constants
|
||||
g=9.81 ' accelleration of gravity
|
||||
l=1 ' length of pendulum
|
||||
GET SCREEN SIZE sw,sh
|
||||
pivotx=sw/2
|
||||
pivoty=150
|
||||
' --- initialise graphics
|
||||
GRAPHICS
|
||||
DRAW COLOR 1,0,0
|
||||
FILL COLOR 0,0,1
|
||||
DRAW SIZE 2
|
||||
' --- initialise pendulum
|
||||
theta=1 ' initial displacement in radians
|
||||
speed=0
|
||||
' --- loop
|
||||
DO
|
||||
bobx=pivotx+100*l*SIN(theta)
|
||||
boby=pivoty-100*l*COS(theta)
|
||||
GOSUB Plot
|
||||
PAUSE 0.01
|
||||
accel=g*SIN(theta)/l/100
|
||||
speed=speed+accel
|
||||
theta=theta+speed
|
||||
UNTIL 0
|
||||
END
|
||||
' --- subroutine
|
||||
Plot:
|
||||
REFRESH OFF
|
||||
GRAPHICS CLEAR 1,1,0.5
|
||||
DRAW LINE pivotx,pivoty TO bobx,boby
|
||||
FILL CIRCLE bobx,boby SIZE 10
|
||||
REFRESH ON
|
||||
RETURN
|
||||
Loading…
Add table
Add a link
Reference in a new issue