圆形/角度滑块

发布于 2024-10-07 15:50:04 字数 1704 浏览 2 评论 0 原文

最近的问题让我想起了我不久前尝试编写的一些代码。目的是创建一个可用于动态对象中类似角度变量的 CircularSlider[] 对象。

我的解决方案的框架(如下)来自 ValueThumbSlider[] ="nofollow noreferrer">高级操作功能教程。主要区别在于,在 ValueThumbSlider[] 中,滑块的值和 LocatorPlane[] 的位置是相同的,而在我的 CircularSlider[] 中 它们不是——这会导致问题。

第一个问题是移动 Locator 将不改变滑块值。通过使用 Dynamic: (x = #/Abs[Complex @@ #]) &

这又导致了一个问题:如果您从外部设置滑块的值 (t),它将立即恢复为之前的值。通过保留旧值 (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


所以我的问题是:有人可以在没有上述组装的情况下完成这项工作吗?

A recent SO question reminded me of some code I tried to write a while back. The aim is to make a CircularSlider[] object that can be used for angle-like variables in dynamic objects.

The framework for my solution (below) comes from the ValueThumbSlider[] defined in the Advanced Manipulate Functionality tutorial. The main difference is that in ValueThumbSlider[] the value of the slider and the position of the LocatorPlane[] are the same thing, whilst in my CircularSlider[] they are not - and this leads to problems.

The first problem is that moving the Locator will not change the slider value. This is fixed by using the 2nd argument in the Dynamic: (x = #/Abs[Complex @@ #]) &.

This in turn leads to the problem that if you externally set the value of the slider (t) from outside, it will immediately revert to its previous value. This is fixed by keeping the old value (t0) and comparing to t. If they don't match then it's assumed that t has changed and so the Locator position x is updated to its new position.

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


So my question is: can someone make this work with out the above kludges?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

笨死的猪 2024-10-14 15:50:04

至于问题#1,我不会考虑将Dynamic 的第二个参数用作拼凑——这就是第二个参数的用途。因此,我没有其他解决方案。

如果您不将第一个参数中的 t 分配给 Dynamic,则问题 #2 可以避免。

考虑到这一点,这是另一个实现:

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

As for problem#1, I wouldn't consider the use of the second argument to Dynamic as a kludge -- that is what the second argument is for. Therefore, I don't have an alternative solution for that one.

Problem #2 can be avoided if you refrain from assigning t in the first argument to Dynamic.

With this in mind, here is another implementation:

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
      ]
  ]

The only material difference between this version and the original version is that the first argument to Dynamic is an expresssion that is free of side-effects.


Edit

I just stumbled across this undocumented experimental feature in Mathematica 8:

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

angular slider

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文