最近的问题让我想起了我不久前尝试编写的一些代码。目的是创建一个可用于动态对象中类似角度变量的 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]]]
所以我的问题是:有人可以在没有上述组装的情况下完成这项工作吗?
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]]]
So my question is: can someone make this work with out the above kludges?
发布评论
评论(1)
至于问题#1,我不会考虑将
Dynamic
的第二个参数用作拼凑——这就是第二个参数的用途。因此,我没有其他解决方案。如果您不将第一个参数中的
t
分配给Dynamic
,则问题 #2 可以避免。考虑到这一点,这是另一个实现:
此版本与原始版本之间的唯一实质性区别是
Dynamic
的第一个参数是一个没有副作用的表达式。编辑
我刚刚在 Mathematica 8 中偶然发现了这个未记录的实验功能:
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 toDynamic
.With this in mind, here is another implementation:
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: