Sim*_*mon 5 wolfram-mathematica
一个最近的SO问题,让我想起了一些代码,我试着写了一段时间回来.目的是创建一个CircularSlider[]可用于动态对象中类角度变量的对象.
我的解决方案框架(如下所示)来自高级操作功能教程中的ValueThumbSlider[]定义.主要区别在于滑块的值和位置是相同的,而在我的它们不是 - 这会导致问题.ValueThumbSlider[]LocatorPlane[]CircularSlider[]
第一个问题是移动Locator不会改变滑块值.这是通过使用在第二个参数固定的Dynamic:(x = #/Abs[Complex @@ #]) &.
这反过来会导致这样的问题:如果从外部设置slider(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]]]
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:有人可以用上面的kludges来完成这项工作吗?
对于问题#1,我不会考虑将第二个参数Dynamic用作kludge - 这就是第二个参数的用途.因此,我没有替代解决方案.
如果你不在t第一个参数中赋值,可以避免问题#2 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
]
]
Run Code Online (Sandbox Code Playgroud)
此版本与原始版本之间唯一的实质区别在于,第一个参数Dynamic是一个没有副作用的表达.
我只是在Mathematica 8中偶然发现了这个未记录的实验性功能:
DynamicModule[{x = RandomReal[{0, 50}]},
{Experimental`AngularSlider[Dynamic@x], Dynamic@x}
]
Run Code Online (Sandbox Code Playgroud)

| 归档时间: |
|
| 查看次数: |
676 次 |
| 最近记录: |