Background:
I’m trying to build a task that would basically replicate a roulette wheel and I’ve essentially done so. This task will revolve a small circle around a large circle and pressing space will initiate an exponential deceleration in the revolution velocity of the smaller circle. In order to model the roulette wheel (the larger circle), I used the visual.RadialStim
component, knowing full-well that it’s probably better used for spinning checkboard type stuff. However, it evenly divides the wheel into alternating sections of color which is really helpful for my task.
Problem:
I’d like to be able to place more than two colors on the wheel, but I’m not sure that it’s possible with visual.RadialStim
. Looking through the documentation, I can’t see anything that helps, though, I did come across this old thread where Jon seems to suggest that it is possible, but I frankly can’t make heads or tails of it and I think the OP left it unresolved as well. Does anyone know for sure? If not, does anyone have another recommended solution to replacing it so that I could maybe get 3 or 4 colors modeled on this larger circle?
Code:
# Psychopy modules
from psychopy import core, event, visual, gui
# Needed to calculate the trajectory of the revolving ball
import math
# Needed to calculcate the deceleration of the revolving ball
import random
# Variables
monitor=0
# The speed with which the ball revolves around the wheel
speed = 0.125
# The radius of the wheel around which the ball is revolving
wheel_radius=0.45
# How many frames per second the animation should use
fps = 30
# Specifying Window & Screen Information -----
win = visual.Window(size=(1024, 768),
fullscr=True,
screen= monitor,
winType='pyglet',
allowGUI=True,
allowStencil=False,
monitor='testMonitor',
color=[0,0,0],
colorSpace='rgb',
blendMode='avg',
useFBO=True,
units='height')
# Noting the starting position of the revolving ball
position = 0.0
# Noting whether the ball is decelerating
decelerate = False
# Draw a circle
ball = visual.Circle(win, edges=100,radius=0.02, fillColor='white', lineColor=None, pos=[position,position])
# Draw a circle
# wheel = visual.Circle(win, edges=300, radius=wheel_radius, fillColor='black', lineColor=None, pos=[0,0])
wheel = visual.RadialStim(win, pos=(0,0), size=((wheel_radius * 2), (wheel_radius * 2)),
color = 'red', angularCycles=6, radialCycles = 0, opacity= 0.8, autoLog=False)
# While speed is greater than 0:
while speed > 0:
# Change the position of the ball according to the current value of position
ball.pos = [((math.sin(position)/10) * (wheel_radius * 10)),
((math.cos(position)/10) * (wheel_radius * 10))]
# Produce the visualization of the wheel
wheel.draw()
# Produce the visualization of the ball
ball.draw()
# If the participant hasn't asked to stop the spinner yet
if decelerate == False:
# Continue spinning the ball around the wheel according to the specified speed
position += speed
# If the participant has asked to stop the spinner
if decelerate == True:
# Randomly select a value between 0.005 and 0.035
rand_dec = random.uniform(0.005,0.035)
# Reduce speed to be a percentage (99.5% - 96.5%) of its last value
# Randomizing the the value of the deceleration will hopefully prevent
# participants from being able to predict where the ball will stop. Also
# making speed a fraction or what it once was, rather than using a linear value
# will better model friction and exponential decay in the real world
speed *= 1 - rand_dec
# Continue spinning the ball around the wheel according to the new speed
position += speed
# If speed drops below 0.001
if speed < 0.001:
# Round speed down to 0
speed = 0
# If escape is pressed, end the task
if event.getKeys('escape'):
break
# If space is pressed, begin slowing the ball
if event.getKeys('space'):
decelerate = True
# Refresh the screen according to the core.wait rate allowing for objects and visualizations
# to change position
win.flip()
# How long psychopy should wait before updating the screen
core.wait(1/fps)
# close the window
win.close()