Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make a directed arc of a circle (or a directed curve)?

I'd like to display a directed circular arc in Mathematica, using something as simple as Arrow. The best I have been able to come up with is this example that nails an Arrow onto one end of a circular arc. But I suspect there is a more direct way to achieve the same effect.

start=\[Pi];
Manipulate[
Graphics[{
   Arrow[{{Cos[\[Theta] + If[\[Theta] < start, .01, -.01]], 
           Sin[\[Theta] + If[\[Theta] < start, .01, -.01]]}, 
          {Cos[\[Theta]], Sin[\[Theta]]}}],
   Circle[{0, 0}, 1, {start, \[Theta]}]},
PlotRange -> 2], 
{{\[Theta], .7 start}, 0, 2 start} 
           ]

arrow

Arrow accepts BSplineCurves and BezierCurvesbut I can't get them to stay on a circular arc. Tube accepts the formula for a curve in 3D but I can't figure out how to get it to work in 2D.

All suggestions are welcome. If your solution works for any 2D curve, all the better!


Epilogue:

I learned quite a bit from the suggestions: Mark McClure showed that Arrow itself can handle the demands when given a list of points.

yoda gave a fairly general solution using ParametricPlot.

I ended up finding belisarius' suggestions the most helpful. His approach was to work on minor variations of familiar graphical objects. In the end, I cautiously chose to define a new object, arcArrow, that employs the parameters of Circle: center, radius, {start,finish}. Unprotect still scares me! Anyway, here's what I settled with. I also stubbornly held on to some features of my original approach.

Manipulate[
 Graphics[{  
   arcArrow[center, radius, {start, end}],
   PointSize[Large], Blue, If[showCenter, Point[center]]},
  PlotRange -> p, ImageSize -> 250],
 {{start, \[Pi]/2}, -2 \[Pi], 2 \[Pi], ImageSize -> Small},
 {{end, 0}, -2 \[Pi], 2 \[Pi], ImageSize -> Small},
 {{radius, 1}, 1/2, 4, ImageSize -> Small},
 {{center, {0, 0}}, {-p, -p}, {p, p}, Slider2D},
 {showCenter, {True, False}},

 Initialization :> {p = 3;
   arcArrow[a_, r_, {start_, end_}] :=
    {Circle[a, r, {start, end}], 
     Arrowheads[Medium],
     Arrow[{a + r {Cos[end + If[end < start, .01, -.01]], 
                   Sin[end + If[end < start, .01, -.01]]}, 
            a + r {Cos[end], Sin[end]}}]} }]

final version


like image 872
DavidC Avatar asked Apr 18 '11 15:04

DavidC


1 Answers

Using Circle[ ]:

f[s_Circle] := 
 s /. Circle[a_, r_, {start_, end_}] :>
      ({s,Arrow[{# - r/10^6 {-Sin@end, Cos@end}, #}]} &[a+r {Cos@end, Sin@end}]) 

Graphics@f[Circle[{0, 0}, 1, {4 Pi/3, 2 Pi}]]

enter image description here

Edit

Redefining the default Circle[ ] behavior:

Unprotect[Circle];
Circle[a_: {0, 0}, r_: 1, {start_, end_}] :=
  Block[{$inMsg = True},
    {Circle[a, r, {start, end}],
     Circle[a, r, {start, end}] /. 
      Circle[aa_, 
        ar_, {astart_, aend_}] :> (Arrow[If[start < end, #, Reverse@#]] &@
             {# - r/10^6 {-Sin@end, Cos@end}, #} &
               [aa + ar {Cos@aend, Sin@aend}])}
    ] /; ! TrueQ[$inMsg];
Protect[Circle];

enter image description here

like image 102
Dr. belisarius Avatar answered Sep 23 '22 23:09

Dr. belisarius