Superformula with Perl?

G

guba

Hello,

I am wondering how parametric formulas like the Superformula
http://en.wikipedia.org/wiki/Superformula
can be drawn with Perl. GD or ImageMagick has only some graphic
primitives and I can not see how this could be done which such
programs. Or can Perl API to a mathe library be used to
draw such graphs? Thank you for hints!

Günter
 
Z

zentara

Hello,

I am wondering how parametric formulas like the Superformula
http://en.wikipedia.org/wiki/Superformula
can be drawn with Perl. GD or ImageMagick has only some graphic
primitives and I can not see how this could be done which such
programs. Or can Perl API to a mathe library be used to
draw such graphs? Thank you for hints!

Günter

If you have gnuplot going, put these 2 scripts into a dir,
and run "gnuplot super", it will give an animation of sorts.
Play with the values m n1 n2 n3.

######## snip super ####################
# Show some of the new polar capabilities.
#
unset border
set clip
set polar
set xtics axis nomirror
set ytics axis nomirror
set zeroaxis
set trange [0:12*pi]

a=1
b=1

m=4
n1=1
n2=1
n3=8

butterfly(x) = ( ( abs(( (cos(m*x)/4))/a) )**n2
+ ( abs(( (sin(m*x)/4))/b) )**n3 )**(-1/n1)

set samples 800
set title "SuperFormula hold control-c to exit"
unset key
plot butterfly(t)
pause .1 #-1 "Hit return to continue"

count=0
load 'looper'

##### END ####################################

##### snip looper ##########################3

m= m + .1
n1= n1 + .1
n2= n2 + .1
n3= n3 + .1

print m; print n1; print n2; print n3;

replot
pause .1
count = count +1
if(count < 1000) reread
##########################################


zentara
 
G

guba

Hello,
thank you for the hint to gnuplot; I need the 2D version of the
superformula.
So I took a look at the Perl API at
http://search.cpan.org/~ilyaz/Term-Gnuplot-0.5704/Gnuplot.pm
I hope there is somewhere a tutorial about this because with my
knowledge about Perl based on PerlMagick this API is difficult to
understand. But perhaps there are other options like turtle graphics
where the turtle is controlled by a formula.

Thank you
Günter


Hello,

I am wondering how parametric formulas like the Superformula
http://en.wikipedia.org/wiki/Superformula
can be drawn with Perl. GD or ImageMagick has only some graphic
primitives and I can not see how this could be done which such
programs. Or can Perl API to a mathe library be used to
draw such graphs? Thank you for hints!

Günter

These are cool, thanks for pointing them out.

If you just want the 2d , gnuplot will do polar coordinates.

But the general solution for 3d, would be to use PDL.
The TriD graphics will do parametric equations.
See http://www.johnlapeyre.com/pdl/pdldoc/newbook/index.html!
for a guide.

Here is a chopped down version from the PDL demo, which is close,
and you could probably modify it for your SuperFormula parametric
equations.

#!/usr/bin/perl
use warnings;
use strict;
use Tk;
use PDL;
use PDL::Graphics::TriD;
use PDL::Graphics::TriD::Contours;
use PDL::Graphics::TriD::GL;
use PDL::Graphics::TriD::Tk;

my $TriDW; # declare the graph object in main, defined in initialize
my $MW = MainWindow->new();
my $bframe = $MW->Frame()->pack( -side => 'top', -fill => 'x' );

# This is the TriD Tk widget it is a Tk Frame widget and has all of the
# attributes of a Frame
$TriDW = $MW->Tk()->pack( -expand => 1, -fill => 'both');

# The exit button
my $e_button = $bframe->Button(
-text => "Exit",
-command => sub { exit }
)->pack( -side => 'right', -anchor => 'nw', -fill => 'y' );

# Sets a default focus style for viewport
#setfocusstyle( 'Pointer' );

# a trick needed to display
# set the graphic when the window is first opened
$e_button->bind( "<Configure>", [
sub {
my $but = shift;
Torusdemos();
$e_button->bind( "<Configure>", '' );
} ]
);

$TriDW->MainLoop;

sub Torusdemos {
my ( $bh ) = @_;

return unless defined $TriDW->{ GLwin };
my $graph;

$graph = $TriDW->{ GLwin }->current_viewport->graph();

# define the graph object
$graph = new PDL::Graphics::TriD::Graph();
$graph->default_axes();

my $data;
my $s = 40;
my $a = zeroes 2 * $s, $s / 2;
my $t = $a->xlinvals( 0, 6.284 );
my $u = $a->ylinvals( 0, 6.284 );
my $o = 0.5;
my $i = 0.1;
my $v = $o + $i * sin $u;

my $x = $v * sin $t;
my $y = $v * cos $t;
my $z = $i * cos( $u ) + $o * sin( 3 * $t );

# color
$data = new PDL::Graphics::TriD::SLattice(
[ $x, $y, $z ],
[
0.5 * ( 1 + sin $t ),
0.5 * ( 1 + cos $t ),
0.25 * ( 2 + cos( $u ) + sin( 3 * $t ) )
]
);

# black and white
# $data = new PDL::Graphics::TriD::SLattice_S( [ $x, $y, $z ] );

$graph->add_dataseries( $data, 'Torus-demo' );
$graph->scalethings();
$TriDW->current_viewport()->delete_graph( $graph );
$TriDW->current_viewport()->graph( $graph );
$TriDW->refresh();
}
__END__
 
Z

zentara

thank you for the hint to gnuplot; I need the 2D version of the
superformula.
So I took a look at the Perl API at
http://search.cpan.org/~ilyaz/Term-Gnuplot-0.5704/Gnuplot.pm
I hope there is somewhere a tutorial about this because with my
knowledge about Perl based on PerlMagick this API is difficult to
understand. But perhaps there are other options like turtle graphics
where the turtle is controlled by a formula.
Thank you
Günter

There are many tutorials for gnuplot, just google for them.

http://t16web.lanl.gov/Kawano/gnuplot/intro/index-e.html

is one of the better ones. But the best thing to do is run all
the demos that comes with the gnuplot c package.

I had trouble getting the Perl module Term::Gnuplot to
compile on my system, but the latest Gnuplot 4.1 compiles,
and can be run from Perl. You can output to X11 or to a Tk
canvas. Here is a Tk app which will let you adjust the settings
to see the output. For the Tk version, it was easiest for me to
redraw every second, but if you output to X11, you can increase
the efficiency (lower cpu) by using the normal X11 display with the
replot command.

This is fun to play with, and there are some serious "sweet spots"
where unpredictable shapes occur. (Watch for word wrap problems).

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

$|++;

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 start1{
#for('a1','b1','m1','n1','n2','n3'){
# $scale{$_}->configure( -command => sub{ \&start} );
# }
#&start;
#}


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'}
# equation below is all one line, watch word wrap)
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');
}
__END__
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,202
Messages
2,571,057
Members
47,661
Latest member
FloridaHan

Latest Threads

Top