1. Phix / pGui Rosetta example : animate_pendulum2.exw

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 
new topic     » topic index » view message » categorize

2. Re: Phix / pGui Rosetta example : animate_pendulum2.exw

lesterb said...

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.

lesterb said...

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.

lesterb said...

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?

lesterb said...

How important do you think this issue is?

I honestly cannot think of anything less important blink

Pete

new topic     » goto parent     » topic index » view message » categorize

3. Re: Phix / pGui Rosetta example : animate_pendulum2.exw

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

new topic     » goto parent     » topic index » view message » categorize

4. Re: Phix / pGui Rosetta example : animate_pendulum2.exw

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.

new topic     » goto parent     » topic index » view message » categorize

5. Re: Phix / pGui Rosetta example : animate_pendulum2.exw

Oh, that's much better - and with screen res and pretty (?) colours. :)

Les

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu