#!/usr/bin/perl -w use strict; use warnings; use Goo::Canvas; use Gtk2 '-init'; use Glib qw(TRUE FALSE); my $window = Gtk2::Window->new('toplevel'); $window->signal_connect('delete_event' => sub { Gtk2->main_quit; }); $window->set_size_request(640, 600); my $swin = Gtk2::ScrolledWindow->new; $swin->set_shadow_type('in'); $window->add($swin); my $canvas = Goo::Canvas->new(); $canvas->set_size_request(800, 650); $canvas->set_bounds(0, 0, 1000, 1000); $swin->add($canvas); my $root = $canvas->get_root_item(); # first offset set my $pts_ref = [50,50,180,120,90,100,50,50]; my $line = Goo::Canvas::Polyline->new( $root, TRUE, $pts_ref, 'stroke-color' => 'black', 'line-width' => 3, 'fill-color-rgba' => 0x3cb37180, ); my ($midx, $midy) = _get_CM( @$pts_ref ); my $ellipse = Goo::Canvas::Ellipse->new( $root, $midx-2, $midy-2,$midx+2, $midy+2, 'stroke-color' => 'goldenrod', 'line-width' => 8 ); my $ellipse1 = Goo::Canvas::Ellipse->new( $root, -2, -2, +2, +2, 'stroke-color' => 'black', 'line-width' => 4 ); $ellipse1->translate($midx,$midy); # end first set #if you have equilateral shapes it's #possible to make at origin and translate my $group = Goo::Canvas::Group->new($root); my $pts_ref1 = [-60,0, 60,0, 0, 40, -60, 0]; my $line1 = Goo::Canvas::Polyline->new( $group, TRUE, $pts_ref1, 'stroke-color' => 'black', 'line-width' => 3, 'fill-color-rgba' => 0xffb37180, ); my ($midx1, $midy1) = _get_CM( @$pts_ref1 ); print "$midx1, $midy1\n"; my $ellipse2 = Goo::Canvas::Ellipse->new( $group, -2, -2, +2, +2, 'stroke-color' => 'black', 'line-width' => 4 ); $ellipse2->translate(0,$midy1 + 4); my $ellipse3 = Goo::Canvas::Ellipse->new( $group, ,-60,-60,60,60, 'stroke-color' => 'green', 'line-width' => 4 ); $ellipse3->translate(60,60); #move whole group $group->translate(400,400); my $id = Glib::Timeout->add (10, sub { $line->rotate (10, $midx, $midy); $group->rotate (-1, 0, 0 ); return 1; }); $window->show_all(); Gtk2->main; ################################################################# # This sub finds the center of mass of a polygon. # I grabbed the algorithm somewhere from the web. # I grabbed it from Ala Qumsieh's RotCanvas :-) sub _get_CM { my ($x, $y, $area); my $i = 0; while ($i < $#_) { my $x0 = $_[$i]; my $y0 = $_[$i+1]; my ($x1, $y1); if ($i+2 > $#_) { $x1 = $_[0]; $y1 = $_[1]; } else { $x1 = $_[$i+2]; $y1 = $_[$i+3]; } $i += 2; my $a1 = 0.5*($x0 + $x1); my $a2 = ($x0**2 + $x0*$x1 + $x1**2)/6; my $a3 = ($x0*$y1 + $y0*$x1 + 2*($x1*$y1 + $x0*$y0))/6; my $b0 = $y1 - $y0; $area += $a1 * $b0; $x += $a2 * $b0; $y += $a3 * $b0; } return split ' ', sprintf "%.0f %0.f" => $x/$area, $y/$area; } #################################################################### __END__