$item->set_simple_transform ($x, $y, $scale, $rotation)
####
sub event_handler{
my ( $widget, $event ) = @_;
print $widget ,' ',$event->type,"\n";
my ($x,$y) = ($event->x,$event->y);
print "$x $y\n";
}
####
#!/usr/bin/perl
use warnings;
use strict;
use Gnome2::Canvas;
use Gtk2 '-init';
my $window = Gtk2::Window->new();
my $sw = Gtk2::ScrolledWindow->new();
$sw->set_shadow_type ('etched-out');
$sw->set_policy ('automatic', 'always');
$sw->set_placement('top-right');
$sw->set_size_request (500, 500);
$sw->set_border_width(0);
my $black = Gtk2::Gdk::Color->new (0x0000,0x0000,0x0000);
my $white = Gtk2::Gdk::Color->new (0xFFFF,0xFFFF,0xFFFF);
my $canvas = Gnome2::Canvas->new_aa();
$canvas->set_size_request(500,500);
$canvas->set_scroll_region(0,0,1000,1000);
$canvas->modify_bg('normal',$white);
$canvas->set_center_scroll_region (0);
my $root = $canvas->root();
my @points = (50,50,80,20,90,100);
my $poly = Gnome2::Canvas::Item->new ($root, 'Gnome2::Canvas::Polygon',
points => \@points,
fill_color_rgba => 0x0000ff80,
outline_color => 'black');
$poly->{'points'} = \@points;
my $id = Glib::Timeout->add (100, sub {
&rotate($poly,10);
return 1;
});
# $ztree->set_pixels_per_unit(2);
$sw->add($canvas);
$window->signal_connect('destroy'=>sub { Gtk2->main_quit(); });
$window->set_default_size(450,350);
$window->add($sw);
$window->show_all();
Gtk2->main();
############################################################################
sub rotate {
my ( $item, $degree ) = @_;
my @points = @{$item->{'points'}};
$item->destroy;
@points = &rotate_poly($item, $degree);
$poly = Gnome2::Canvas::Item->new ($root, 'Gnome2::Canvas::Polygon',
points => \@points,
fill_color_rgba => 0xff000080,
outline_color => 'black');
$poly->{'points'} = \@points;
}
####################################################################3
sub rotate_poly {
my ($ind, $angle, $midx, $midy) = @_;
# Get the old coordinates.
my @coords = @{$ind->{'points'}};
# Get the center of the poly. We use this to translate the
# above coords back to the origin, and then rotate about
# the origin, then translate back. (old)
($midx, $midy) = _get_CM( @coords ) unless defined $midx;
my @new;
# Precalculate the sin/cos of the angle, since we'll call
# them a few times.
my $rad = 3.1416*$angle/180;
my $sin = sin $rad;
my $cos = cos $rad;
# Calculate the new coordinates of the line.
while (my ($x, $y) = splice @coords, 0, 2) {
my $x1 = $x - $midx;
my $y1 = $y - $midy;
push @new => $midx + ($x1 * $cos - $y1 * $sin);
push @new => $midy + ($x1 * $sin + $y1 * $cos);
}
# Redraw the poly.
return @new;
}
#################################################################
# 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;
}
####################################################################