Как я могу сделать направленную дугу круга (или направленную кривую)? - PullRequest
9 голосов
/ 18 апреля 2011

Я бы хотел отобразить направленную круговую дугу в Mathematica, используя что-то простое, например Arrow.Лучшее, что я смог придумать, - это пример, который прибивает Arrow к одному концу дуги окружности.Но я подозреваю, что есть более прямой способ достижения того же эффекта.

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 принимает BSplineCurves и BezierCurves, но я не могу получитьих остаться на дуге окружности.Tube принимает формулу для кривой в 3D, но я не могу понять, как заставить ее работать в 2D.

Все предложения приветствуются.Если ваше решение работает для любой 2D-кривой , тем лучше!


Эпилог:

Я многому научился из предложенийМарк МакКлюр показал, что Arrow сам может справиться с требованиями, когда ему предоставлен список точек.

Йода дал довольно общее решение, используя ParametricPlot.

В итоге я нашел предложения Велисария наиболееполезно.Его подход заключался в работе над небольшими вариациями знакомых графических объектов.В конце я осторожно решил определить новый объект, arcArrow, который использует параметры Circle: центр, радиус, {начало, конец}.Unprotect все еще пугает меня!Во всяком случае, вот что я решил.Я также упорно держался некоторые черты моего оригинального подхода.

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

1037 *

Ответы [ 3 ]

8 голосов
/ 18 апреля 2011

Вы также можете добавить стрелку к конечной точке дуги, например:

circle[x_] = {Cos[x], Sin[x]};
ParametricPlot[{0.9 circle[x], 0.7 circle[x + Pi/3], 0.4 circle[-x]}, 
 {x, Pi/4, Pi/2}, PlotRange -> {-1, 1}, Axes -> False] 
/.Line[x__] :> Sequence[Arrowheads[.03], Arrow[x]]

enter image description here

Возможно, это гораздо проще контролировать, поскольку вы можете программно установить радиус и длину дуги и просто заменить стрелки в конце.

Вы также должны взглянуть на обсуждение добавления стрелок по краям кривой . Там есть много хороших подходов, возможно, лучше, чем этот. Лично я нашел ответ Саймона на его собственный вопрос довольно изящной маленькой функцией, которая есть в моей маленькой коллекции «функций из Интернета», и я использовал ее не раз, чтобы размещать стрелки на графиках, которые продолжают вне участка.

EDIT

Как я определил выше, стрелка помещается в конце строки. Например, если вы строите линию от L до R, она помещает ее справа и слева в противном случае. Таким образом, в примере положительное увеличение x идет против часовой стрелки, и, следовательно, стрелки в этом направлении. Увеличение отрицательного dir будет производить стрелку по часовой стрелке. Чтобы избежать второй команды заговора, я просто изменил x на -x в третьей функции в списке, что дало тот же эффект на кривой золотистого цвета.

В целом, вы можете изменить ориентацию стрелок, изменив входные данные на Arrowheads следующим образом:

Стрелки, идущие в обратном направлении

enter image description here

стрелки на обоих концах

enter image description here

Перевернутые стрелки

enter image description here

7 голосов
/ 18 апреля 2011

Использование Круг [] :

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

Редактировать

Переопределение поведения Circle [] по умолчанию:

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

7 голосов
/ 18 апреля 2011

Arrow принимает список точек произвольной длины.Таким образом, возможно, что-то вроде этого.

Manipulate[Graphics[
  Arrow[Table[{Cos[t], Sin[t]}, {t, 0, T, Sign[T] Pi/100}]],
  PlotRange -> 1.1], {{T, 0}, -2 Pi, 2 Pi}]
...