#!/usr/bin/perl # time_passes.pl - explore a fractal landscape # Tyler MacDonald April 25th, 2004 use strict; use warnings; use vars qw(@ARGV); use Math::Gradient qw(multi_array_gradient); sub make_fractal($$$$$$$$$$$$$$); sub framespec($); our $num = qr{[\+\-0-9e\.]+}; our @frames; my $frames; my $p; our @ARGS = @ARGV; if($ARGV[0] && $ARGV[0] eq "-p") { shift(@ARGV); $p = ""; } else { $p = "-disk"; } if(!@ARGV) { @ARGV = ("/usr/share/xfractint/volcano.map", "-0.4898911524/0.6239721190/0.00/0.00/8.287671/100000", 3600, "-0.4898914567/0.6239718811/0.0000003600/0.00/8.287671/100000"); } my $map = shift(@ARGV); if((@ARGV < 3) || ((@ARGV - 1) % 2)) { die "Usage: $0 map x/y/z/w/zoom/iter frames x/y/z/w/zoom/iter [frames x/y/z/w/zoom/iter ...]\n"; } my $frame1 = [ framespec(shift(@ARGV)) ]; if(!$frame1 || !@$frame1) { die "Invalid starting framespec!\n"; } my $framen = 1; my $pframe; my $cframe; my $nnframes; $pframe = $frame1; @frames = (); while($nnframes = shift(@ARGV)) { $framen++; my $fs = shift(@ARGV); $cframe = [ framespec($fs) ]; if(!$cframe || !@$cframe) { die "Framespec #$framen ($fs) is bad.\n"; } my(@xframes) = multi_array_gradient($nnframes, $pframe, $cframe); push(@frames, @xframes); $pframe = $cframe; } $frames = @frames; $|=1; my $genX = "720"; my $genY = "480"; my $saveX = $genX; my $saveY = $genY; #my $saveX = $genX / 2; #my $saveY = $genY / 2; my $startT = time(); my $factor = 2 ** 10; my $nframes = 0; my $n = 0; my $ndone = 0; my $xframes = 0; my $i; while($factor > 1) { my $factorT = time(); $factor = $factor / 2; $nframes += $frames / $factor; $xframes = $frames / $factor; my $fn = 0; for ($i = 1; $i <= $frames; $i += $factor) { my $frameT = time(); my $file = sprintf("ani%04d.png", $i); my $tmpfile = sprintf("ani%04db.gif", $i); my $args = $frames[$i - 1]; if(-e($file)) { print "$file already exists.\n"; $nframes--; $xframes--; $ndone++; } else { print "$file\n ", join("/", @$args), "\n "; if(make_fractal($i, !$p, $file, $map, $genX, $genY, $saveX, $saveY, $args->[0], $args->[1], $args->[2], $args->[3], $args->[4], $args->[5])) { $fn ++; $n ++; $ndone ++; my $fps = $ndone / (time() - $startT); # ($n + ($frames / ($factor * 2))) / (time() - $factorT); my $eta = ((time() - $startT) / $ndone) * $frames; # my $eta = ((time() - $factorT) / $fn) * ($nframes - $fn); my $k = (-s($file)) / 1024; printf("%dk, %ds, %.03ffps frames %d/%d/f%d %d/%d, eta %ds\n", $k, time() - $frameT, $fps, $fn, $xframes, $factor, $frames - $ndone, $frames, $eta); } else { print "\n"; } } } } sub framespec($) { my $framespec = shift; if($framespec =~ qr{^($num)/($num)/($num)/($num)/($num)/($num)$}) { return($1 + 0, $2 + 0 , $3 + 0 , $4 + 0, $5 + 0, $6 + 0); } else { return; } } sub make_fractal($$$$$$$$$$$$$$) { my($frame, $verbose, $filename, $map, $genX, $genY, $saveX, $saveY, $x, $y, $z, $w, $zoom, $iter) = @_; if(!defined($x) || !defined($y) || !defined($z) || !defined($w) || !defined($zoom)) { return; } my $tmpfile = "temp.$filename"; #$tmpfile =~ s/\.png$/.gif/i; my $p; my $fct_file = gnofract4d_fct($tmpfile, @_); my $fct_cmd = gnofract4d_cmdline($tmpfile, @_); if($verbose) { $p = ""; } else { $p = "-disk"; } # open(ANI, ">ani.par"); # my $ani = sprintf # ( # " # ani { # reset=2003 type=mandel passes=1 # center-mag=%1.10f/%1.10f/%lu # params=%1.10f/%1.10f float=y maxiter=%lu # } # ", # $x, $y, $zoom, $z, $w, $iter # ); # print ANI $ani; # close(ANI); open(FCT, ">$filename.fct"); print FCT $fct_file; close(FCT); # my $cmd = "xfractint \@ani.par/ani -geometry \"${genX}x${genY}\" \"map=$map\" batch=y \"savename=$tmpfile\" \"$p\" > /dev/null"; # print $cmd, "\n"; print "$fct_cmd\n "; system($fct_cmd); print "gen "; if(-e($tmpfile)) { my $time = sprintf("X: %1.10f Y: %1.10f Z: %1.10f W: %1.10f Zoom: %1.10f", $x, $y, $z, $w, $zoom); my $convcmd = sprintf("convert \"%s\" -fill white -box black -draw \"text 10,20 \\\"%s\\\"\" \"%s\"", $tmpfile, $time, $filename); print "\n $convcmd\n "; system($convcmd); unlink($tmpfile); if(-e($filename)) { print "scale "; return $filename; } else { print "failed on scale! "; return; } } else { print "failed on render! "; return; } if(!-e($filename)) { print "Failed on render!\n"; return; } } sub gnofract4d_cmdline { my($tmpfile, $frame, $verbose, $filename, $map, $genX, $genY, $saveX, $saveY, $x, $y, $z, $w, $zoom, $iter) = @_; my $cmd = sprintf("gnofract4d --display=:1 -p \"%s.fct\" -i \"%lu\" -j \"%lu\" -s \"%s\" -q 2> /dev/null", $filename, $genX, $genY, $tmpfile); } sub gnofract4d_fct { my($tmpfile, $frame, $verbose, $filename, $map, $genX, $genY, $saveX, $saveY, $x, $y, $z, $w, $zoom, $iter) = @_; my $file = sprintf ( " # %s # %s # Frame: %s # Image File: %s # Generated Resolution: %lux%lu # Destined Resolution: %lux%lu gnofract4d parameter file version=1.9 bailout=4 x=%1.20f y=%1.20f z=%1.20f w=%1.20f size=%1.20f maxiter=%lu xy=0 xz=0 yz=0 yw=0 zw=0 antialias=1 bailfunc=4 inner=5 outer=1 [function] function=Mandelbrot [endsection] [colorizer]=0 colorizer=1 file=%s [endsection] [colorizer]=1 colorizer=0 red=1 green=0 blue=0 [endsection] [colorizer]=2 colorizer=0 red=1 green=0 blue=0 [endsection] [colorizer]=3 colorizer=0 red=1 green=0 blue=0 [endsection] ", $0, join(" ", @ARGS), $frame, $filename, $genX, $genY, $saveX, $saveY, $x, $y, $z, $w, $zoom, $iter, $map ); return $file; }