Tk compass dial
zentara
created: 2006-04-27 15:33:19
UPDATE: The Tk::Trace part of this, isn't really necessary, I was planning to use that to feed an angle into the program from a remote source, to update the display.

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);

}

Re: Tk compass dial
created: 2006-05-27 11:01:48
zentara,
A couple of comments. The first is that you define the PI constant but never use it. The second is that I think 360 should be 359. As is, your compass ends up with 361 degrees (0 - 360).

Cheers - L~R

Re^2: Tk compass dial
created: 2006-05-27 12:10:09
Thanks, I removed the PI constant, and fixed the 361 problem.

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

perlmonks.org content © perlmonks.org and Limbic~Region, zentara

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03