orange has asked for the wisdom of the Perl Monks concerning the following question:

hi
in the following code i am trying to plot the sine function slowly , i am using $mw->update; and a delay loop, we can change how much slow by changing the $counter variable
i wish other ways to slow the plotting.
i hope there is other ways to get rid of the $mw->update;
use warnings; use strict; use Tk; my $mw = MainWindow->new; my $x = 0; my $y = 0; my $pi = 3.1415926; my $counter=0; my $c = $mw->Canvas(-width => 500, -height => 500); $c ->pack; # draw axis $c -> createLine(50, 250, 450, 250); $c -> createText(10, 250, -fill => 'blue', -text => 'X'); $c -> createLine(250, 50, 250, 450); $c -> createText(250, 10, -fill => 'blue', -text => 'Y'); for ( $x = -(3*$pi); $x <= +(3*$pi); $x += 0.05) { $y = sin($x); $c -> createText( $x*30+250, $y*30+250, -fill => 'red', -text => '.'); $counter=0; # delay loop while ($counter <= 100000) { $counter++; } $mw->update; } MainLoop;

Replies are listed 'Best First'.
Re: plotting slowly
by graff (Chancellor) on Apr 23, 2007 at 17:06 UTC
    kyle is right about avoiding the counter loop that you have there. But "sleep()" might be too coarse unless you get into using Time::HiRes.

    Luckily, you already have access to Tk::After, which is probably what you really want in this situation -- e.g. using the "repeat" method described on that man page.

Re: plotting slowly
by kyle (Abbot) on Apr 23, 2007 at 16:57 UTC
    $counter=0; # delay loop while ($counter <= 100000) { $counter++; }

    Ouch! How about sleep? It doesn't eat up the CPU, it delays the same way on every processor, and it's clear in the code how long the delay is.

Re: plotting slowly
by Fletch (Bishop) on Apr 23, 2007 at 17:01 UTC

    Gah. Busy waiting is never the answer (unless you're like on the bare metal writing a device driver in ASM and have no recourse, of course :).

    At any rate, Tk provides an after method which allows you to schedule periodic or one-time events.

Re: plotting slowly
by zentara (Cardinal) on Apr 23, 2007 at 20:06 UTC
    Just to give you some tips ( we all needed them). If you change your increment 0.05 to a variable, you can make a widget to set it in realtime as a textvariable, and you can have adjustable speed control. You can't change the delay of the repeater dynamically, but you can fudge around it by adjusting how far something moves during that period.
    #!/usr/bin/perl use warnings; use strict; use Tk; my $mw = MainWindow->new; my $x = 0; my $y = 0; my $pi = 3.1415926; my $counter=0; my $c = $mw->Canvas(-width => 500, -height => 500); $c ->pack; # draw axis $c -> createLine(50, 250, 450, 250); $c -> createText(10, 250, -fill => 'blue', -text => 'X'); $c -> createLine(250, 50, 250, 450); $c -> createText(250, 10, -fill => 'blue', -text => 'Y'); $x = -(3*$pi); my $repeater; # declare separately so you can # stop it in it's own callback $repeater = $mw->repeat(50,sub{ # 50 millisecond delay $x += 0.05; if( $x >= +(3*$pi) ){ $repeater->cancel } $y = sin($x); $c -> createText( $x*30+250, $y*30+250, -fill => 'red', -text => '.'); }); MainLoop;

    I'm not really a human, but I play one on earth. Cogito ergo sum a bum