Tk Mandelbrot - click on image to center and zoom in... highly inefficient...

Takes a numeric parameter, which sets the width and height, in pixels, of the canvas. Defaults to 100 if no valid argument - personally, I wouldn't try going higher than, say, 500...

<update>Now you can zoom out by right-clicking, and I've changed the colour-scheme...</update>

use strict; use Tk; my $debug = 0; my $c_size = ($ARGV[0] =~ /^\d+$/ && $ARGV[0]>0) ? $ARGV[0] : 100; my $scale = my $oldscale = 1; my ($lasti, $lastr)=(0,-0.5); my $first = 1; my $mw = MainWindow -> new; my $canvas = $mw -> Canvas(-height=>$c_size, -width=>$c_size) -> pack; $canvas -> Tk::bind('all', '<ButtonPress-1>' => \&MakeMan0); $canvas -> Tk::bind('all', '<ButtonPress-3>' => \&MakeMan1); MakeMan(0); MainLoop; sub MakeMan0(){ print "here0\n" if $debug; MakeMan(0); } sub MakeMan1(){ print "here1\n" if $debug; MakeMan(1); } sub MakeMan(){ $canvas -> delete('all'); my ($e, $canv_x, $canv_y)=(0,$c_size/2,$c_size/2); if(!$first){ $e = $canvas -> XEvent; $canv_x = $e->x; $canv_y = $e->y; } print "$_[0] : $scale : $oldscale\n" if $debug; $oldscale = $scale; my $px_old = (4/$oldscale)/$c_size; $scale = $scale * ($_[0] ? 0.5 : 2); $scale = 1 if $first; my $px_new = (4/$scale)/$c_size; print "$_[0] : $scale : $oldscale\n" if $debug; $first = 0; my $i = $lasti = $lasti + ($canv_y - ($c_size/2))*$px_old; # centre $i = $i - (($c_size/2)*$px_new); # left edge my $rconst = $lastr = $lastr + ($canv_x - ($c_size/2))*$px_old; # ce +ntre $rconst = $rconst - (($c_size/2)*$px_new); # top edge my $icount = 1; while($icount <= $c_size){ my $r = $rconst; my $rcount = 1; while($rcount <= $c_size){ my $iter = ($c_size/10)*($scale**0.5); my $tr = $r; my $ti = $i; my $rgb_out = '#000000'; my $red = 20; my $green = 20; my $blue = 20; for my $n(1..$iter){ ($tr, $ti) = (($tr ** 2) - ($ti ** 2) + ($r), (2 * $tr * $ti) ++ ($i)); $red += int(130/$iter); $green += int(130/$iter); $blue +=int(235/$iter); if((($tr * $tr) + ($ti * $ti)) > 4){ $rgb_out = '#' . (sprintf("%2.2X",$red)) . sprintf("%2.2X",$ +green) . (sprintf("%2.2X",$blue)); last; } } $canvas -> createLine($rcount, $icount, $rcount+1, $icount, -fil +l => $rgb_out, -width => 1); $rcount ++; $r += ((4/$scale)/$c_size); } $icount ++; $i += ((4/$scale)/$c_size); } }

Replies are listed 'Best First'.
Re: Tk Mandelbrot Fractal
by BrowserUk (Patriarch) on Dec 07, 2006 at 20:03 UTC

    Where is XEvent documented? In particular, what other methods beside ->x and ->y are available?


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      The information does seem a bit sparse - I found most of the XEvent and callback stuff by hunting around on the internet.

      map{$a=1-$_/10;map{$d=$a;$e=$b=$_/20-2;map{($d,$e)=(2*$d*$e+$a,$e**2 -$d**2+$b);$c=$d**2+$e**2>4?$d=8:_}1..50;print$c}0..59;print$/}0..20
      Tom Melly, pm@tomandlu.co.uk
      There are events listed in perldoc Tk::bind under the section Event types. You can get keyboard events, mouse clicks of a few varieties, and various things like Map and Unmap( which are basically iconify and deiconify).

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

        I know. But that is not my question.

        I'm specifically looking for what other information (besides x and y), are available (by default), from the object returned from $canvas->XEvent method in a mouse event callback. As in the OPs use:

        $e = $canvas -> XEvent; $canv_x = $e->x; $canv_y = $e->y;

        This has to be documented somewhere?

        Looking again at the Tk:bind docs at the section entitled "BINDING CALLBACKS AND SUBSTITUTIONS", it appears that you can choose froma wide variety and formats, what information gets passed to the callback by using the Ev() function(?) when forming the bind. But this appears to involve yet more callbacks and and dynamic evaluations, which slows things down horribly--as if it wasn't slow enough anyway.

        I was hoping to find that the default information supplied to a canvas mouse event callback included not just the window relative x/y, but also the canvas relative x/y. Performing the convesion isn't hard, but it involves yet more calls and just slows everything down again.

        I'm not sure why I (or anyone) bother persisting with using this stuff--it's just painful.


        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.