# 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

# 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

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)),

# 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()
``````

Try as I could, I could not get the texture approach to work, but I settled on a far less eloquent solution. By reducing the opacity of the RadialStim and overlaying another RadialStim of a complementary color at half opacity, and situated at a 30-degree angle, I was able to more or less create the appearance of four colors. Not thrilled, but it’ll do for now. Looking forward to someone else showing me up.

``````# 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
# Needed to create colors for the roulette wheel
import numpy as np

# Specifying which monitor to use
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

# 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

# Creating the ball
ball = visual.Circle(win, edges=100,radius=0.02, fillColor='white', lineColor=None, pos=[position,position])

# Creating the wheel
color ='yellow', angularRes=300,
angularCycles=3, radialCycles = 0, opacity= 0.9, autoLog=False)
color ='red', angularRes=300, ori=30,
angularCycles=3, radialCycles = 0, opacity= 0.5, 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)),

# Produce the visualization of the wheel
wheel_base.draw()
wheel_layer.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:

# 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

# Randomly select a value between 0.005 and 0.035
rand_dec = random.uniform(0.005,0.035)

# 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()
``````