psychopy.org | Reference | Downloads | Github

Adjust Stimulus Movement Speed on Screen

I’m practicing with moving stimuli during a task. I have a countdown timer, a progress bar, and a circle that makes a loop around the countdown timer. My problem is that the circle does not make a complete loop before the timer is finished, and I don’t know how to speed this up. Is there a better way than what I have? Here is what I’ve been doing:

from __future__ import division
from psychopy import locale_setup, visual, core, event, data, gui
import os, platform, math, shlex
import subprocess as subp

#Set window and remove mouse during experiment:
win = visual.Window(fullscr=True, pos=(0,0), units="norm", color = "Black")
event.Mouse(visible=False)

#Determine Monitor Resolution:
if platform.system() == "Windows":
    from win32api import GetSystemMetrics
    width, height = GetSystemMetrics(0), GetSystemMetrics(1)
elif platform.system() == "Darwin":
    p = subp.Popen(shlex.split("system_profiler SPDisplaysDataType"), stdout=subp.PIPE)
    output = subp.check_output(('grep', 'Resolution'), stdin=p.stdout)
    width, height = [int(x.strip(' ')) for x in output.split(':')[-1].split(' x ')]
    
#Create stimuli:
text = visual.TextStim(win, text=' ', pos=(0,0), height = 0.5, color="White")
circle = visual.Circle(win, radius=0.05, pos = (0,0.5), fillColor="Yellow")
prog_bar = visual.Rect(win, pos=(-1.0, -0.8), fillColor="White")    

#Set varaibles
cdTime = 5.0 
speed = 4/cdTime
pi = math.pi
radius = text.boundingBox[1]/height + 0.1

#Set timer:
timer = core.Clock()

timer.reset()
time_start = timer.getTime()
countdownTimer = core.CountdownTimer(cdTime)

while countdownTimer.getTime() > 0.0:
    thesekeys = event.getKeys(keyList=["escape"])
    if len(thesekeys):
        break
        
    text.text= int(round(math.ceil(countdownTimer.getTime()),0))
    prog_bar.size = (((cdTime-countdownTimer.getTime())*2)*speed, 0.3) #Multiply by 2 to move progress bar in 1 direction, multiply by speed for progress to finish when timer finishes
    circle.pos = (radius*math.cos(cdTime-countdownTimer.getTime()+0.1), radius*math.sin(cdTime-countdownTimer.getTime())+0.1)
    text.draw()
    circle.draw()
    prog_bar.draw()
    
    win.flip()
time_end = timer.getTime()

print "Length of countdown: %s" %(time_end - time_start)

#Finish
win.close()
core.quit()

It’s a trig issue. What you want is for the cos and sin values to be the same when the countdown timer is at 5 seconds and at 0 seconds. Right now that’s not the case. At t=0s, when countdowntimer.gettime returns 5, you’re getting radiuscos(0+.1). At t=5s, when gettime returns 0, you’re getting radiuscos(5+.1). If you look at a graph for cos(x), when x=.1 and x=5.1, you don’t get the same value. You want it to be more like at t=0s you’re getting cos(0) and at t=5s you’re getting cos(2pi)

Here’s a replacement for the circle.pos line that should work better:

circle.pos = (radius*math.cos(((cdTime-countdownTimer.getTime())/cdTime)*2*pi), radius*math.sin(((cdTime-countdownTimer.getTime())/cdTime)*2*pi))
1 Like

Thanks for your response. That fixed my issue.

No problem. Make sure to tick ‘solved’ on this thread, it helps the developer(s) keep track of what’s still an open issue.

2 Likes