Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

SuperFormula with gnuplot and Tk

by zentara (Archbishop)
on Dec 30, 2006 at 12:25 UTC ( #592338=snippet: print w/ replies, xml ) Need Help??

Description: A newsgroup post got me going on this. It is a way to quickly visualize the SuperFormula using PerlTk and IPC. I had trouble getting Term::GnuPlot to compile, but the latest gnuplot has Tk output built in (although not as efficient as the X11 driver, see commented out line).

The output for Tkcanvas requires evaling a string and generating subs, so it dosn't run with strict, and I've commented out warnings, to eliminate some harmless warnings. It prints '0 0 0 0' upon finishing a graph cycle.

This has 1 guarantee.... it will become addicting and waste alot of your time. :-) There are some very interesting "sweetspots" in the adjustments.

#!/usr/bin/perl
#use warnings;
#use strict;
use Tk;
use Tk::ROText;
use IPC::Open3;

# see http://en.wikipedia.org/wiki/Superformula
# for the formula

$|++;

my %var =(
  'a1'=> 1, 
  'b1'=> 1,        
  'm1'=> 8,
  'n1'=> 1,
  'n2'=> 1,
  'n3'=> 1,
);

my $stop = 0;
my $repeater;
my $running = 0;

my $mw = MainWindow->new;

my $tframe = $mw->Frame()->pack();
my $canvas = $tframe->Canvas(
                  -bg => 'white',
          -height =>500,
          -width =>500,
          )->pack(-side=>'left',-expand=>1,-fill=>'both');
my $tframe1 = $tframe->Frame()->pack(-side=>'right',-padx=>0);

my %scale;

for ('a1','b1','m1','n1','n2','n3'){
 
    my $tframea = $tframe1->Frame()->pack(-side=>'left',-padx=>0);

   $tframea->Label(-text => " $_   ")->pack(-side=>'top');
    
     $scale{$_} = $tframea->Scale(
      -from    => -100,
      -to    => 100,
      -length => 500,
      -orient    => 'vertical',
      -variable    => \$var{$_},
      -resolution => .01,
      -borderwidth =>0,
      -foreground => 'white',
      -background => 'lightslategrey',
      -troughcolor => 'powderblue',
     )->pack(-side => 'left', -padx=>0);
 }

my $text = $mw->Scrolled('ROText',
            -bg=>'white',
        -height =>5,
        -width => 45)
     ->pack( -fill => 'both', -expand => 1 );

tie(*STDOUT, 'Tk::Text', $text);

$text->tagConfigure( 'red', -foreground => 'red' );

my $pid = open3( \*gIN, \*gOUT, \*gERR, "/usr/bin/gnuplot" ) || die;
$mw->fileevent( \*gOUT, readable => \&read_out );
$mw->fileevent( \*gERR, readable => \&read_err );

#comment out the below line to get gnuplot's X11 display
#which is more efficient than the canvas plot
print gIN "set term tkcanvas perltk interactive\n";

my $bframe = $mw->Frame->pack();
my $startbut = $bframe->Button(
                    -text=>'Start',
                    -command=> \&start)->pack(-side=>'left');

my $stopbut = $bframe->Button(
                    -text=>'Stop',
                    -command=> sub{ $auto = 0;
              $repeater->cancel;
                  $running = 0;        
             })->pack(-side=>'left');

#must be last or get broken pipe error
tie(*STDERR, 'Tk::Text', $text);

$mw->update; 

MainLoop;

sub start{

my $string =<<"EOF";
reset
unset border
set clip
set polar
set xtics axis nomirror
set ytics axis nomirror
set zeroaxis
set trange [0:2*pi]
a=$var{'a1'}
b=$var{'b1'}
m=$var{'m1'}
n1=$var{'n1'}
n2=$var{'n2'}
n3=$var{'n3'}
butterfly(x) =  ( ( abs(( (cos(m*x)/4))/a)  )**n2 + ( abs(( (sin(m*x)/
+4))/b)  )**n3  )**(-1/n1)
set samples 800
set title "SuperFormula"
unset key
plot butterfly(t)
EOF
print gIN  "$string\n";


if( $running == 0){
 $repeater=$mw->repeat(1000,sub{ 
                     $running = 1;
                     &start;
        });
   }
}

sub read_out {
  my $buffer = <gOUT>;
  #  print $buffer,"\n";
  my $can = $canvas;
  eval($buffer);

}

sub read_err {
#    print "read_err()\n";
    my $num = sysread(gERR, my $buffer, 1024 );
#    print "sysread() got $num bytes:\n[$buffer]\n";
    $text->insert( 'end', $buffer, 'red' );
    $text->see('end');
}



Comment on SuperFormula with gnuplot and Tk
Download Code
Re: SuperFormula with gnuplot and Tk
by zentara (Archbishop) on Dec 30, 2006 at 16:28 UTC
    Hi, this is just a followup. Th Tkcanvas code for gnuplot uses quite a bit of extra cpu, all for the drawing the plot on a real Tk canvas. I use almost 40% cpu for the above script. You can get much improved performance by using the default gnuplot driver. See below. It uses less than 2% cpu, has no flicker due to contstant redrawing, and it can be dynamically resized. It is much superior, so I post it below. The tkcanvas method above would be useful only if you have a 1-shot plot, or if you want to save the canvas to postscript. So here is a better version.


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

Back to Snippets Section

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: snippet [id://592338]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others meditating upon the Monastery: (11)
As of 2014-10-23 21:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    For retirement, I am banking on:










    Results (129 votes), past polls