Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

comment on

( [id://3333]=superdoc: print w/replies, xml ) Need Help??
Scaling and rotations can be tricky because they are predefined to the group's origin (usually root group at 0,0, but it may be the canvas center point, depends on the canvas type and setup). The first time you try to rotate something, people ar usually surprised to see the item fly off the screen because the $cx and $cy is 0,0 (unless you moved the root group). I havn't tried it yet, but it looks like you want to use
$item->set_simple_transform ($x, $y, $scale, $rotation)
where $x and $y will be the center point of the scale; presumably the weighted center of your item. Computing the weighted center can be tricky for odd shapes, so you may have to resort to making a special group for each item to be scaled, add the item to the group centered, move the group, and scale it.

It's one of those things you just need to play with to get right. Look at the 'animation' section of the Goo demo.

As far as the x,y coordinates of the mouse I think you need to setup an event handler on the canvas and the items.

sub event_handler{ my ( $widget, $event ) = @_; print $widget ,' ',$event->type,"\n"; my ($x,$y) = ($event->x,$event->y); print "$x $y\n"; }
Once again, look at the demo and see how it does the Events tab.

Just to show you how difficult a centered rotation can be, here is an example on the Gnome2::Canvas, you will then appreciate Goo's set_simple_transform :-)

#!/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::Polygo +n', 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::Poly +gon', 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; } ####################################################################

I'm not really a human, but I play one on earth Remember How Lucky You Are

In reply to Re: Goo Canvas Scaling and X-Y coordinates by zentara
in thread Goo Canvas Scaling and X-Y coordinates by renegadex

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Are you posting in the right place? Check out Where do I post X? to know for sure.
  • Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
    <code> <a> <b> <big> <blockquote> <br /> <dd> <dl> <dt> <em> <font> <h1> <h2> <h3> <h4> <h5> <h6> <hr /> <i> <li> <nbsp> <ol> <p> <small> <strike> <strong> <sub> <sup> <table> <td> <th> <tr> <tt> <u> <ul>
  • Snippets of code should be wrapped in <code> tags not <pre> tags. In fact, <pre> tags should generally be avoided. If they must be used, extreme care should be taken to ensure that their contents do not have long lines (<70 chars), in order to prevent horizontal scrolling (and possible janitor intervention).
  • Want more info? How to link or How to display code and escape characters are good places to start.
Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (5)
As of 2024-04-16 05:12 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found