You can get the coordinates for the end point of the arc with the following subroutine:

use strict; use warnings; use Math::Trig; sub getArcEnd { my ($x, $y, $x2, $y2, $start, $extent) = @_; # -------------------------------------- # Note: this was added in response to liverpole's note below # Optional patch to allow denormalized bounding boxes if ($x2 < $x) { my $tmp = $x; $x=$x2; $x2=$tmp; } if ($y2 < $y) { my $tmp = $y; $y=$y2; $y2=$tmp; } # -------------------------------------- # $x, $y, $x2, $y2 can be the bounding box of an # ellipse (not just a circle) so calculate vertical # and horizontal radius separately my $radiusX = ($x2 - $x)/2; my $centerX = $x + $radiusX; my $radiusY = ($y2 - $y)/2; my $centerY = $y + $radiusY; # Tk expects the starting angle and length of the # arc (extent) to be in degrees but cos and sin expect # them in radian my $radians = deg2rad($start + $extent); # [ x coord of arc end point, y coord of arc end point ] # the coordinate system for Tk::Canvas makes "down" # positive so we need to subtract the Y component # rather than add it. return [ $centerX + $radiusX*cos($radians) , $centerY - $radiusY*sin($radians) ]; }

The only way to get the arrow head to orient correctly on a line attached to the end of the circle would be to angle the line. That would require a very short line tangent to the circle. I'm not exactly sure how Tk draws its circles, but usually a circle is drawn just as you tried to do it with a series of very short lines. However, there is some smoothing going on so that the line looks less choppy to the human eye. In some cases the points of that short line may not coincide exactly with the points of the circle and you will see a slight thickening at the point where you want to join your arrow. Depending on the size of your arrow and the radius of your arc, it may or may not be noticable.

Another option is to draw your own arrow. To get the arrow aligned right, the arrow's coordinates need to be rotated clockwise 45 degrees (-45). To get you started, here is a quick routine that draws a very simple arrow head.

sub drawArrow { my ($xEnd, $yEnd, $start, $extent, $arrowLength) = @_; my $radians = deg2rad($start + $degrees-45); my $xArrow = $arrowLength * cos($radians); my $yArrow = $arrowLength * sin($radians); $can->createLine($xEnd, $yEnd, $xEnd+$xArrow, $yEnd-$yArrow); $can->createLine($xEnd, $yEnd, $xEnd+$yArrow, $yEnd+$xArrow); }

Best, beth

Update: Added explanation of how to draw a properly oriented arrow head.

Update 2: Added optional patch to allow non-normalized bounding boxes - see below, liverpole's note and responses for further discussion.


In reply to Re: Tk:Canvas - Arc with an arrow? by ELISHEVA
in thread Tk:Canvas - Arc with an arrow? by cmv

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



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.