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