RosettaCodeData/Task/Animate-a-pendulum/Phix/animate-a-pendulum.phix
2019-09-12 10:33:56 -07:00

89 lines
2.5 KiB
Text

-- demo\rosetta\animate_pendulum2.exw
include pGUI.e
Ihandle dlg, canvas, timer
cdCanvas cdcanvas
constant g = 50
atom angle = PI/2,
velocity = 0
integer w, h, len = 0
function redraw_cb(Ihandle /*ih*/, integer /*posx*/, integer /*posy*/)
{w, h} = IupGetIntInt(canvas, "DRAWSIZE")
cdCanvasActivate(cdcanvas)
cdCanvasClear(cdcanvas)
-- new suspension point:
integer sX = floor(w/2)
integer sY = floor(h/16)
-- 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*/)
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 delta = -len*sin(angle)*g
velocity += dt*delta
angle += dt*velocity
IupUpdate(canvas)
return IUP_IGNORE
end function
function map_cb(Ihandle ih)
atom res = IupGetDouble(NULL, "SCREENDPI")/25.4
IupGLMakeCurrent(canvas)
cdcanvas = cdCreateCanvas(CD_GL, "10x10 %g", {res})
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
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 = IupGLCanvas()
IupSetAttribute(canvas, "RASTERSIZE", "640x380")
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")
IupSetCallback(dlg, "K_ANY", Icallback("esc_close"))
IupShow(dlg)
IupSetAttribute(canvas, "RASTERSIZE", NULL)
IupMainLoop()
IupClose()
end procedure
main()