6
$\begingroup$

The objective: Create a slider that, when displaced from the center, increases-decreases the value of another variable at a rate proportional to the displacement.

So, I create a slider that automatically comes back to the center

Slider[Dynamic[var, {(var = #) &, (var = 0.) &}], {-1, 1}]

Now I want a second variable to be dynamically increased/decreased when var!=0.

My ideas are:

  1. insert in the previous dynamic, something that does the updating
  2. use an animator with its speed set by var when var!=0. that updates the value

Problems with the above:

  1. How to control the speed of the updating given that I can't know for sure the intervals in which val will be updated, and UpdateIntervals sets an upper bound?
  2. How to make it work without it showing in the screen?

Any other alternatives are welcome (ideally I'd like an elegant solution).

$\endgroup$
1
  • $\begingroup$ @R.M, hope this pings you. Heike's answer shows my intentions clearly. Now that Dynamic[y, {y=g[x]}] I wasn't aware of. I thought the second argument was supposed to be a function and that they only made sense when the dynamic was "being set by a control". What does it do? $\endgroup$
    – Rojo
    Commented Jun 3, 2012 at 19:04

2 Answers 2

2
$\begingroup$

Maybe you could do something like this,

var = 0.; p = 0.; interval = .2;
task = RunScheduledTask[p += var, interval];
{Slider[Dynamic[var, {(var = #) &, (var = 0.) &}], {-1, 1}], Dynamic[p]}

The downside is that rather than increasing p by a fixed amount at variable time intervals, this increases p by a variable amount at a fixed frequency. Also, you need to remember to remove task (using RemoveScheduledTask) once you're done with it.

$\endgroup$
3
  • $\begingroup$ I think this is probably a good-enough approach. +1, thanks. I'll be waiting for other options for a while to accept. One could add the run and remove scheduled tasks in the second argument of the slider's dynamic, right? So that only when dragged the task exists $\endgroup$
    – Rojo
    Commented Jun 3, 2012 at 19:02
  • $\begingroup$ You could also create it once and use StartScheduledTask and StopScheduledTask in the second argument of Dynamic to start and stop it. $\endgroup$
    – Heike
    Commented Jun 3, 2012 at 19:14
  • $\begingroup$ Makes sense. Create it in Initialization and remove it in Deinitialization $\endgroup$
    – Rojo
    Commented Jun 3, 2012 at 19:15
4
$\begingroup$

Here's another way using Refresh that's perhaps a bit cleaner:

DynamicModule[{x = 0, y = 0},
    {Slider[Dynamic[x, {(x = #) &, (x = 0.) &}], {-1, 1}], 
     Dynamic[Refresh[y += x, TrackedSymbols :> {}, UpdateInterval -> 0.1]]}
]
$\endgroup$
4
  • $\begingroup$ +1. I took it and turned the second dynamic into the second argument of a DynamicWrapper so it becomes what I wanted: just a slider that does the updating. DynamicWrapper[Slider..., Refresh[...]] $\endgroup$
    – Rojo
    Commented Jun 3, 2012 at 19:57
  • $\begingroup$ This is way neater, but for some reason I don't understand, Heike's solution allows me to put lower update intervals before it gets way slower than it should $\endgroup$
    – Rojo
    Commented Jun 3, 2012 at 20:01
  • $\begingroup$ Interesting... didn't notice that $\endgroup$
    – rm -rf
    Commented Jun 3, 2012 at 20:12
  • $\begingroup$ @Rojo, R.M: This is beautiful and elegant, nice use of Refresh & DynamicWrapper! $\endgroup$ Commented Jun 4, 2012 at 11:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.