I constantly harp here about Tk::Zinc. Well I would just like to give a little demonstration of it's abilities. Just to keep Zinc in everyone's "list of options". :-) I am going to build a rudimentary "Newton's cradle", one in Canvas and one in Zinc. As a matter of fact, I'm going to use RotCanvas, instead of Canvas, otherwise it would be too complex too even mess with in Canvas. The first thing you will notice, is that RotCanvas is limited to only a few items types which can be rotated, and that it will lock up if you try to "push it too fast" with a timer. On my 800 Mhz system, RotCanvas will lock up if I set the repeat interval to less than 20. On Zinc, I can go down to 1. This results in greater resolution and smoother motion. Try setting the repeat interval to 1, in both scripts and see the difference. One other thing, I havn't even incorporated the scaling ability of Zinc , expecially on groups. With that, I could simulate 3D by zooming in and out as the pendulums rotate.
#!/usr/bin/perl use warnings; use strict; use Tk; use Tk::RotCanvas; my $mw = tkinit; my $heightmw = 260; my $width = 600; my $height = $heightmw - 60; $mw->geometry($width.'x'.$heightmw .'+100+100'); my $canvas = $mw->RotCanvas(-width => $width, -height => $height, -bg => 'black')->pack(-fill=>'both',-expand => 1); my $angle = 0; my $px0 = 240; my $py0 = 0; my $px_new = 240; my $py_new = $height; my %pend; for(0..4){ $pend{$_}{'line'} = $canvas->createLine( $px0 ,$py0, $px_new ,$py_new, -smooth => 1, -width => 3, -tags => ['line'.$_], -fill => 'white'); $pend{$_}{'ball'} = $canvas->createOval( $px_new - 15 ,$py_new , $px_new + 15, $py_new + 30, -tags => ['ball'.$_], -fill => 'orange', ); $canvas->move( $pend{$_}{'line'},$_ * 30,0); $canvas->move( $pend{$_}{'ball'},$_ * 30,0); $pend{$_}{'centerx'} = $px0 + $_ * 30; } my $motion = 0; my $bframe = $mw->Frame()->pack(-fill =>'both'); my $startbut; my $timer; my $toggle = -1; $startbut = $bframe->Button(-text=>'Start', -command =>sub{ if($motion == 0){ $startbut->configure(-text=>'Stop'); $motion = 1; &start; }else{ $startbut->configure(-text=>'Start'); $motion = 0; $timer->cancel; } } )->pack(-side => 'left'); $bframe->Button(-text=>'Quit', -command =>sub{exit})->pack(-side => 'right'); MainLoop; sub start{ #cannot set the timer too low or #the rotate's below don't have enough #time to complete, so lockups occur #so set swing degree higher for more speed $timer = $canvas->repeat(50,sub{ &swing(4); }); } ########################################################## sub swing{ my $degree = shift; $degree = $toggle*$degree; $angle = $angle + $degree; if( $angle > 90 ){$toggle *= -1} if( $angle < -90 ){$toggle *= -1} for(0..4){ # can only specify one tag at a time in RotCanvas, # and it will not do a group $canvas->rotate('line'.$_, $degree, $pend{$_}{'centerx'},$py0); $canvas->rotate('ball'.$_, $degree, $pend{$_}{'centerx'},$py0); } } __END__ ########################################################### ########################################################## #and now with Zinc ########################################################## ######################################################### #!/usr/bin/perl use warnings; use strict; use Tk; use Tk::Zinc; my $mw = tkinit; my $heightmw = 260; my $width = 600; my $height = $heightmw - 60; $mw->geometry($width.'x'.$heightmw .'+100+100'); my $canvas = $mw->Zinc(-width => $width, -height => $height, -backcolor => 'black')->pack(-fill=>'both',-expand => 1 +); my $angle = 0; my $px0 = 0; my $py0 = 0; my $px_new = 240; my $py_new = $height; my %pends; #make a prototype pendulum easily at (0,0) coords $pends{0}{'pendulum'} = $canvas->add('group',1,-visible=> 1); # all lines are curves....of course!! it's relativity :-) my $line = $canvas->add('curve',$pends{0}{'pendulum'}, [0 ,0, 0 ,$py_new], -linewidth => 3, -tags => ['line'], -fillcolor => 'white', -linecolor => 'white', ); my $ball = $canvas->add('arc',$pends{0}{'pendulum'}, [-15,$py_new,15,$py_new+30], -tags => ['ball'], -filled=> 1, -fillcolor => 'orange', ); $canvas->translate($pends{0}{'pendulum'},240,0); $pends{0}{'center_rot'} = [240,0]; ########end of first prototype #now clone and position the other pendulums for(1..4){ $pends{$_}{'pendulum'} = $canvas->clone( $pends{0}{'pendulum'} ); $canvas->translate($pends{$_}{'pendulum'}, $_*30, 0); $pends{$_}{'center_rot'} = [240 + $_ * 30 ,0]; } my $motion = 0; my $bframe = $mw->Frame()->pack(-fill =>'both'); my $startbut; my $timer; my $toggle = -1; $startbut = $bframe->Button(-text=>'Start', -command =>sub{ if($motion == 0){ $startbut->configure(-text=>'Stop'); $motion = 1; &start; }else{ $startbut->configure(-text=>'Start'); $motion = 0; $timer->cancel; } } )->pack(-side => 'left'); $bframe->Button(-text=>'Quit', -command =>sub{exit})->pack(-side => 'right'); MainLoop; ###################################################### sub start{ $timer = $canvas->repeat(10,sub{ &swing(.0175); # 1 degree in radians }); } ###################################################### sub swing{ my $degree = shift; $degree = $toggle*$degree; $angle = $angle + $degree; if( $angle > 1.57 ){$toggle *= -1} if( $angle < -1.57 ){$toggle *= -1} for(0..5){ # rotate( item, rads, [center of rotation ]) $canvas->rotate($pends{$_}{'pendulum'}, $degree, @{$pends{$_}{'center_rot'}}); } } __END__

Replies are listed 'Best First'.
Re: Advantages of Tk::Zinc over plain Canvas
by webfiend (Vicar) on Dec 17, 2004 at 00:39 UTC

    For those of us who are not among the swiftest of the swift, here is some information about what a Newton's cradle is.

    Finally I know what to call them besides "that cool clicky ball thingy you saw on Ed's desk."

      And there is a nice java animation at Newton's Cradle I will post a Tk version of it later.

      I'm not really a human, but I play one on earth. flash japh