A recent node got me thinking how to make a rudimentary gauge to control the radar on my roof top, with my mouse. Just a simple snippet that you might find instructive.
#!/usr/bin/perl
use warnings;
use strict;
package Tk;
use Tk::Trace;
package main;
use Tk;
use constant PI => 3.1415926;
my $mw = MainWindow->new;
my $gray50_width = 2;
my $gray50_height = 2;
my $gray50_bits = pack "CC", 0x02, 0x01;
$mw->DefineBitmap('mask' => 2,2, $gray50_bits);
$mw->fontCreate('medium',
-family=>'courier',
-weight=>'bold',
-size=>int(-14*14/10));
my $c = $mw->Canvas(
-width => 200,
-height => 200,
-bd => 2,
-relief => 'sunken',
-background => 'black',
)->pack;
$c->createLine(100,100,10,100,
-tags => ['needle'],
-arrow => 'last',
-width => 5,
-fill => 'hotpink',
);
my $gauge = $c->createOval(
10,10, 190,190,
-fill=> 'lightblue',
-outline => 'skyblue',
-width => 5,
-tags => ['gauge'],
-stipple => 'mask',
);
my $hub = $c->createOval(
90,90, 110,110,
-fill => 'lightgreen',
-outline => 'seagreen',
-width => 2,
-tags => ['hub'],
);
my $v = 180;
$mw->traceVariable(\$v, 'w' => [\&update_meter]);
$mw->bind('' => sub{
my $ev = $c->XEvent;
&update_meter($ev->x,$ev->y);
});
my $text = $c->createText(
100,50,
-text => $v,
-font => 'medium',
-fill => 'yellow',
-anchor => 's',
-tags => ['text']
);
$c->raise('needle','text');
$c->raise('hub','needle');
MainLoop;
sub update_meter {
my($x,$y) = @_;
# transform coords center to 100,100
$x = $x - 100;
$y = 100 - $y;
my $cos = $x/($x**2 + $y**2)**(.5);
my $sin = $y/($x**2 + $y**2)**(.5);
my $x1 = 100.0 + 90.0 * $cos;
my $y1 = 100.0 - 90.0 * $sin;
$c->coords('needle', 100,100, $x1, $y1);
#see perldoc -f cos
my $angle = sprintf('%.2d', 180 / 3.1416 * atan2( sqrt(1 - $cos * $cos), $cos ));
if( $y < 0){ $angle = 360 - $angle }
$c->itemconfigure($text,-text => $angle);
}
perlmonks.org content © perlmonks.org and Limbic~Region, zentara
prlmnks.org © 2006 edmund von der burg (eccles & toad)
v 0.03