Beefy Boxes and Bandwidth Generously Provided by pair Networks
Pathologically Eclectic Rubbish Lister
 
PerlMonks  

Drawing arcs with Tk and labeling them, problems with the math?

by Anonymous Monk
on Sep 10, 2003 at 17:25 UTC ( [id://290476]=perlquestion: print w/replies, xml ) Need Help??

Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi all,

So this bit of code has been driving me absolutely nuts!! I can't seem to get it right. Any help would be greatly appreciated.

What I'm trying to do is the following :

  1. Draw a circle made up of overlapping arcs
  2. Each segment that is visible after the overlapping arc are drawn needs to be labeled. I'm doing this with a line coming off of the arc and some text as a label.

The big problem for me is the following:

I'm working with and trying to get the geometry right. It looks (by eye) that the arcs are being drawn in the right place, with the right colors and everything makes sense. Drawing the tick marks is the problem. The arcs are drawn in degrees, but the cos/sin functions are calculated in radians by default (something I discovered today). It looks like maybe the tick marks are drawn in the right order, but the position is incorrect and the length of the tick is variable.

You can see a stripped down version of the code that I'm using to debug below.

Thanks in advance for the help.
-Mark

use CWD; use Tk; @myorfs = ([1,'foo1',1000,850],[2,'foo2',750,600],[3,'foo3',575,375],[ +4,'moo1',350,10]); @colors = qw/grey purple pink blue turquoise green chartreuse yellow g +old orange/; $canvas_height = 800; $canvas_width = 800; $mw = MainWindow->new(); $canvas = $mw->Canvas(-height=>$canvas_height, -width=> $canvas_width, + -background=> 'white')->pack(); $radius = 200; # radius is 200 pixels $pi = 3.1417; # Approximate pi $deg2rad = $pi/180; # conversion factor to go from degrees to ra +dians $circum = 2*$pi*$radius; # C = 2 * pi * radius $genome_length=0; for ($i=0;$i<($#myorfs+1);$i++) { $orf = $myorfs[$i][2] - $myorfs[$i][3]; $genome_length = $genome_length + $orf; # find genome length } print"genome length=$genome_length\n"; $drawn_angle=0; $canvas->createLine($canvas_width/2, # draw a line wh +ere start point should be $canvas_height/2-$radius, $canvas_width/2, $canvas_height/2-$radius-30); $canvas->createText($canvas_width/2, # draw "start" a +t end of the line $canvas_height/2-$radius-35, -text=>"Start"); for ($i=0;$i<($#myorfs+1);$i++) { $color = int($i % 10); $arcolor = $colors[$color]; $orig_dist = $myorfs[$i][2] - $myorfs[$i][3]; # calc original orf + length $orf_pct = $orig_dist/$genome_length; # convert orf lengt +h to pct of genome length $graph_arc_length = $circum * $orf_pct; # calc equivalent a +rc length corresponding to same pct of circumference $central_angle = 360 * ($graph_arc_length / $circum); # calc centra +l angle for that arc $gene_name = $myorfs[$i][1]; if ($i == 0 ) { $canvas->createArc($canvas_width / 2 - $radius, # draw first +arc all the way around circle $canvas_height / 2 - $radius, # set drawn_a +ngle = angle you want this orf to be $canvas_width / 2 + $radius, # It will be +used to set the extent for the next arc $canvas_height / 2 + $radius, # drawn, leav +ing the right arc length exposed for this orf. -width => 4, -outline=> $arcolor, -style => 'arc', -start => 90, -extent => -359.99999999); $drawn_angle = 360 - $central_angle; } else { $canvas->createArc($canvas_width / 2 - $radius, # draw all of + the other arcs on top of the first arc $canvas_height / 2 - $radius, $canvas_width / 2 + $radius, $canvas_height / 2 + $radius, -width => 4, -outline=> $arcolor, -style => 'arc', -start => 90, -extent => -$drawn_angle); $drawn_angle = $drawn_angle - $central_angle; } $tick_length = 5; # tick length + (supposedly) $xstart = int($canvas_width/2.0 + $radius*cos($drawn_angle*$deg2rad +)); $ystart = int($canvas_height/2.0 + $radius*sin($drawn_angle*$deg2ra +d)); $xstop = int($xstart + $tick_length*cos($drawn_angle*$deg2rad)); $ystop = int($xstop + $tick_length*sin($drawn_angle*$deg2rad)); $canvas->createLine($xstart,$ystart,$xstop,$ystop); $canvas->createText($xstop,$ystop, -anchor=>'n', -text=>"$gene_name +($xstop,$ystop)"); print"=======================\ni=$i,color=$arcolor,gene=$gene_name, +radius=$radius,circum=$circum,central angle=$central_angle,drawn_angl +e=$drawn_angle\n"; } MainLoop;

Janitored by ybiC: Balanced <readmore> tags around code

Replies are listed 'Best First'.
Re: Drawing arcs with Tk and labeling them, problems with the math?
by benn (Vicar) on Sep 10, 2003 at 19:13 UTC
    $ystop = int($xstop + $tick_length*sin($drawn_angle*$deg2rad));
    Ermm - shouldn't that be $ystart instead of $xstop?

    As an aside, 3.1417 is not as near an approximation to PI (3.14159...) as 3.1416 is :)

    Cheers, Ben.

      Ben, Thanks that worked great. Now I just have a problem with where the ticks come from. I need one tick per arc but I'm not getting that. I think it's a math problem. Any ideas? Thanks, Mark

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://290476]
Approved by herveus
help
Chatterbox?
and the web crawler heard nothing...

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

    No recent polls found