1. Phix / pGui Rosetta example : animate_pendulum2.exw
- Posted by lesterb Jul 05, 2018
- 1449 views
I had a look at this demo because there's a comment in the code about the pendulum going a bit mad when the window is being resized. I have indeed observed the madness and I believe I know why.
The pendulum position update and resize is done in the redraw callback (redraw_cb()) and this is activated by a canvas update requested by a call to IupDate() in the timer tick callback (timer_cb()).
Unfortunately, when the window is resized, redraw_cb() is also called by the system to repaint the screen. This means that while window resizing, the pendulum position update is called too often and the mad behaviour ensues. I measured up to 20 screen updates during resize rather than 1 or 2 normally.
So we need to repaint every update (to support resize/repaint) but only move the pendulum according to how many timer ticks there have been since last pendulum move.
I added a global variable 'tick' (to count timer ticks) and made small changes to redraw_cb() and timer_cb(). See code below.
The madness is much improved but there's another issue - by resizing the window up and down many times, it's possible to get the pendulum hurtling round the pivot point in one direction. The original code using both Arwen and pGui also displays this problem. Although amusing, it's probably not what's wanted.
My thought so far is that it's caused by the pendulum velocity being unrealistic for the new length but I haven't tried to fix it yet.
How important do you think this issue is?
-- Add after omega declaration atom ticks=0 -- Replace these 2 functions 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 if ticks > 0 then -- only move if the timer has ticked (seems to be 0, 1 or 2) atom dt = 1/w/ticks -- divide 'dt' by number of ticks -- move: atom epsilon = -len*sin(alpha)*g omega += dt*epsilon alpha += dt*omega ticks=0 -- this tick count dealt with end if -- 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 function timer_cb(Ihandle /*ih*/) ticks += 1 IupUpdate(canvas) return IUP_IGNORE end function
2. Re: Phix / pGui Rosetta example : animate_pendulum2.exw
- Posted by petelomax Jul 05, 2018
- 1374 views
while window resizing, the pendulum position update is called too often and the mad behaviour ensues.
That's true, I guess, but I was never that concerned with a bit of speed-up during the resize itself. Still, I'll take it, thanks.
It's possible to get the pendulum hurtling round the pivot point in one direction.
Yeah, that's what I meant by the madness, that persists after the resizing has stopped.
My thought so far is that it's caused by the pendulum velocity being unrealistic for the new length but I haven't tried to fix it yet.
Just before I opened your post, from the subject line, I stabbed a guess that you were resetting things. Anyway, I tried that:
integer waslen = 0 -- (file-level) ... if len!=waslen then waslen = len alpha = PI/2 omega = 0 end if
That certainly stopped the madness, but I don't really like that effect much though.
If it could instead be done as omega=some_func(alpha,len), and alpha left alone, perhaps?
Another thing that struck me is that alpha, omega, and epsilon are simply awful names.
They probably made more sense in some lecture or book with a nice diagram we don't have.
I guess alpha is an angle, epsilon is [eek!] a delta, and is omega a velocity?
How important do you think this issue is?
I honestly cannot think of anything less important
Pete
3. Re: Phix / pGui Rosetta example : animate_pendulum2.exw
- Posted by lesterb Jul 08, 2018
- 1316 views
Hi,
Sorry for the delay (damned clients!)
alpha, epsilon, omega == angle, delta, velocity is my understanding too.
The rotating pendulum is nasty and I have some thoughts about how to control it but it may be getting away from the spirit of Rosetta (kiss). Nevertheless, I may have a go at my leisure (if I should be fortunate enough to get some :).
Les
4. Re: Phix / pGui Rosetta example : animate_pendulum2.exw
- Posted by petelomax Jul 11, 2018
- 1239 views
Beat you to it. (Got a little bit frustrated with my current project saying you have $7, so spend $124 of that...)
Sourced a recalc of the velocity[1]:
if newlen!=len then len = newlen atom tmp = 2*g*len*(cos(angle)) velocity = iff(tmp<0?0:sqrt(tmp)*sign(velocity)) end if
and moved
velocity += dt*delta angle += dt*velocity
from redraw_cb into timer_cb, where it should have been all along.
Grab a fresh copy from https://bitbucket.org/petelomax/phix/src/default/demo/rosetta/animate_pendulum2.exw
Pete
[1]: Internally I have also made sqrt(-1) now report an error rather than yield -nan.
EDIT: also made it use openGL and changed the colours.
5. Re: Phix / pGui Rosetta example : animate_pendulum2.exw
- Posted by lesterb Jul 11, 2018
- 1154 views
Oh, that's much better - and with screen res and pretty (?) colours. :)
Les