psychopy.org | Reference | Downloads | Github

Zooming In/Out of Stimuli

I’m programming a variation of an approach/avoid task in which after participants have made a response, the stimuli either increases or decreases in size.
I have an idea of how I might do this based on a key press, but I’d like the stimuli to change size after a certain duration of time has passed instead of the key press (to ensure continuity).

I was wondering if anyone has done this before or has any advice?

Builder maintains a variable called t that represents the time in seconds since the start of the routine. So you can easily animate stimuli by incorporating t in a formula for their size or position or whatever.

e.g. if you wanted a square stimulus to grow in size from 0 pixels at the start of the routine, at a rate of 50 pixels per second, then you would simply put this in the size field:

t * 50

and set the size field to update on every frame (typically 60 Hz). i.e. at the start of the trial, t == 0, so the stimulus is invisible. At t == 1.0, it is 50 pixels in size, at t == 2.0, it is 100 pixels in size, and so on.

If the stimulus was twice as wide as it was tall, then you would need to specify the size in both axes, in a list:

[t * 50 * 2, t * 50]

In your case, you want to specify a starting size and then have it grow after a certain point in time. Here we can make use of boolean logic, by comparing the current value of t to some specified start time. If t is less than that value, the expression will be False and evaluate to zero, so the growth factor won’t apply. If t is greater than that value, the expression evaluates to True or 1, so the factor will be added to the start value. e.g.

100 + (t > 2.0) * (10 * (t - 2.0))

i.e. in this case, the stimulus starts with dimensions of 100 × 100 pixels. While t < 2.0 seconds, the second expression evaluates to False, or 0, so the size stays constant. After 2.0 seconds have elapsed, the second term now equals 1, so the size grows by 10 pixels per second.

Hope that makes sense.

Thank you @Michael - that’s really helpful.

Just to check I’m understanding things…
My pictures are 300x300 so I’m currently entering the following:

0.3 + (t > 1.5) * (0.2 * t)

Which I understand to mean that my image will stay at the correct size for 1.5 seconds before increasing? However at the moment the picture is increasing immediately and also appears larger than the specified size. Or have I misunderstood?

I forgot that we need to subtract the threshold time to avoid an initial discontinuous jump in size, so your formula should look like this:

0.3 + (t > 1.5) * (0.2 * (t - 1.5))

i.e. you’re wanting the zoom to be a smooth increase form the current size (0.3), so we need to re-zero the time value at 1.5 to avoid a large discrete jump at that point.

Your (adjusted) formula works for me: a static size for 1.5 seconds, followed by a steady magnification. Can you clarify the issue?

The specified initial size is 0.3: what you see is dependent on the units you have chosen (presumably height units, to preserve the square shape of your stimulus). Maybe you would find it easier to work in pix units, to keep a very concrete idea of what size they should be?

Thanks, I’ve made the changes!

Using the exact formula above, the picture does not remain a static size for the 1.5 seconds, it starts increasing in size immediately and continues to do so for a total of 3 seconds. I’ll continue having a play around to try and find a solution.

I agree; pix will be much better for the actual experiment, however when I change the unit to pix, the stimuli appears in the centre of the screen every trial (as opposed to on the left or right as determined by a conditions file). I haven’t figures out why this is yet.

Presumably because your position coordinates are still listed in normalised coordinates, so if you switch to pixel coordinates, they will be vanishingly close to the centre of the screen. e.g. in norm coordinates, 0.5 is halfway between the centre of the screen and the edge, bit in pixel coordinates, 0.5 pixels is basically still on the centre pixel of the screen. You would need to scale these values up to, say 500 pixels to see a noticeable shift.

Is your stimulus actually set to start displaying at time 0?