Круговой / Угловой слайдер - PullRequest
5 голосов
/ 12 декабря 2010

A недавний вопрос SO напомнил мне некоторый код, который я пытался написать некоторое время назад.Цель состоит в том, чтобы создать объект CircularSlider[], который можно использовать для угловых переменных в динамических объектах.

Основа для моего решения (ниже) взята из ValueThumbSlider[], определенного в AdvancedФункциональность манипулирования учебник.Основное отличие состоит в том, что в ValueThumbSlider[] значение ползунка и положение LocatorPlane[] - это одно и то же, в то время как в моем CircularSlider[] они не совпадают - и это приводит к проблемам.

Первая проблема заключается в том, что перемещение Locator не изменит значение ползунка.Это исправлено с помощью 2-го аргумента в Dynamic: (x = #/Abs[Complex @@ #]) &.

Это, в свою очередь, приводит к проблеме, заключающейся в том, что при внешнем задании значения ползунка (* 1023)*) извне он немедленно вернется к своему предыдущему значению.Это исправлено путем сохранения старого значения (t0) и сравнения с t.Если они не совпадают, то предполагается, что t изменилось, и поэтому позиция Locator x обновляется до новой позиции.

CircularSlider[t_] := CircularSlider[t, {0, 1}];
CircularSlider[Dynamic[t_], {min_, max_}] /; max > min := 
 With[{d = (max - min)/(2. Pi)},
  DynamicModule[{td = t/d, x, t0}, x = {Cos[td], Sin[td]};
   LocatorPane[
    Dynamic[If[!NumberQ[t], t = min; x = {Cos[td], Sin[td]}];
     If[t != t0, t0 = t; x = {Cos[td], Sin[td]}];
     t = Mod[Arg[Complex @@ x] d, max, min]; t0 = t;
     x, (x = #/Abs[Complex @@ #]) &],
    Graphics[{AbsoluteThickness[1.5], Circle[], 
      Dynamic[{Text[NumberForm[t, {3, 2}], {0, 0}]}]}],
    ImageSize -> Small]]]

alt text


Итак, мой вопрос: кто-то может заставить это работать без вышеупомянутых кладджей?

1 Ответ

5 голосов
/ 13 декабря 2010

Что касается проблемы # 1, я бы не стал рассматривать использование второго аргумента для Dynamic в качестве кладжи - для этого и нужен второй аргумент.Поэтому у меня нет альтернативного решения для этого.

Проблемы # 2 можно избежать, если вы воздерживаетесь от присвоения t в первом аргументе Dynamic.

св этой связи есть еще одна реализация:

CircularSlider2[Dynamic[t_], r:{min_, max_}:{0, 1}] :=
  DynamicModule[{scale, toXY, fromXY},
      scale = (max - min) / (2. Pi);
      toXY[a_?NumberQ] := Through@{Cos, Sin}[a / scale];
      toXY[a_] := {1, 0};
      fromXY[{x_, y_}] := Mod[Arg[x + I y] scale, max, min];
      LocatorPane[
        Dynamic[toXY[t], (t = fromXY[#])&],
        Graphics[{
            AbsoluteThickness[1.5], Circle[],
            Dynamic[{Text[NumberForm[t, {3,2}], {0, 0}]}]
          }],
        ImageSize -> Small
      ]
  ]

Единственное существенное различие между этой версией и исходной версией заключается в том, что первый аргумент Dynamic является выражением, которое не имеет побочных эффектов.


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

Я только что наткнулся на эту недокументированную экспериментальную функцию в Mathematica 8:

DynamicModule[{x = RandomReal[{0, 50}]},
  {Experimental`AngularSlider[Dynamic@x], Dynamic@x}
]

angular slider

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...