如何制作一个圆形视觉对象,其面积平均分为三种或更多种颜色?
How can I make a circular visual object with its area evenly divided among three or more colors?
背景:
对 python 和精神病学有点陌生。我正在尝试构建一个可以在功能上复制轮盘的功能,我基本上已经这样做了。此功能将围绕一个大圆圈旋转一个小圆圈,并在旋转时按 'space' 将启动小圆圈的公转速度的指数减速。为了模拟轮盘(较大的圆圈),我使用了 PsychoPy
中的 visual.RadialStim
组件。据我所知,它确实是为了方便地构建旋转棋盘视觉效果而设计的,这些视觉效果通常用作 fMRI 实验中的控件。然而,这意味着它将轮子均匀地分成交替的颜色部分,这对我的目的很有帮助。这是正在执行的任务的可视化:
问题:
我希望能够在色盘上放置两种以上的颜色,但我不确定 visual.RadialStim
是否可行。查看文档,我看不出有什么帮助,不过,我确实遇到了这个 old thread ,乔恩似乎暗示这是可能的,但坦率地说,我无法弄清它的正面或反面,我认为 OP 也没有解决它。有谁知道我对 RadialStim
的怀疑是否正确(即不能使用两种以上的颜色)?或者,有没有人有其他推荐的解决方案来替换它,这样我就可以在这个更大的圆圈上模拟 3 或 4 种颜色?
代码:
请注意 - 对于那些不熟悉 PsychoPy 的人,它是一个专门为创建研究而构建的集合函数,并且需要任何使用它的代码在 PsychoPy 终端中 运行(而不是任何旧的 Python终端)。 PsychoPy 可以 运行 任何 Python 包,但是 Python 终端不能 运行 PsychoPy 代码,所以如果你试图在没有 PsychoPy 的情况下自己 运行 这个,它可能行不通。
# 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
# 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
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
# Creating the ball
ball = visual.Circle(win, edges=100,radius=0.02, fillColor='white', lineColor=None, pos=[position,position])
# Creating the wheel
wheel = visual.RadialStim(win, pos=(0,0), size=((wheel_radius * 2), (wheel_radius * 2)),
color =('red', 'blue', 'white'), angularRes=300,
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()
尽我所能,我无法使纹理方法起作用,但我选择了一个少得多的 eloquent 解决方案。通过降低 RadialStim 的不透明度并以半不透明度覆盖另一个补色的 RadialStim,并以 30 度角放置,我能够或多或少地创建四种颜色的外观。不激动,但现在就可以了。期待其他人出现。
# 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
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
# Creating the ball
ball = visual.Circle(win, edges=100,radius=0.02, fillColor='white', lineColor=None, pos=[position,position])
# Creating the wheel
wheel_base = visual.RadialStim(win, pos=(0,0), size=((wheel_radius * 2), (wheel_radius * 2)),
color ='yellow', angularRes=300,
angularCycles=3, radialCycles = 0, opacity= 0.9, autoLog=False)
wheel_layer = visual.RadialStim(win, pos=(0,0), size=((wheel_radius * 2), (wheel_radius * 2)),
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)),
((math.cos(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()
背景:
对 python 和精神病学有点陌生。我正在尝试构建一个可以在功能上复制轮盘的功能,我基本上已经这样做了。此功能将围绕一个大圆圈旋转一个小圆圈,并在旋转时按 'space' 将启动小圆圈的公转速度的指数减速。为了模拟轮盘(较大的圆圈),我使用了 PsychoPy
中的 visual.RadialStim
组件。据我所知,它确实是为了方便地构建旋转棋盘视觉效果而设计的,这些视觉效果通常用作 fMRI 实验中的控件。然而,这意味着它将轮子均匀地分成交替的颜色部分,这对我的目的很有帮助。这是正在执行的任务的可视化:
问题:
我希望能够在色盘上放置两种以上的颜色,但我不确定 visual.RadialStim
是否可行。查看文档,我看不出有什么帮助,不过,我确实遇到了这个 old thread ,乔恩似乎暗示这是可能的,但坦率地说,我无法弄清它的正面或反面,我认为 OP 也没有解决它。有谁知道我对 RadialStim
的怀疑是否正确(即不能使用两种以上的颜色)?或者,有没有人有其他推荐的解决方案来替换它,这样我就可以在这个更大的圆圈上模拟 3 或 4 种颜色?
代码:
请注意 - 对于那些不熟悉 PsychoPy 的人,它是一个专门为创建研究而构建的集合函数,并且需要任何使用它的代码在 PsychoPy 终端中 运行(而不是任何旧的 Python终端)。 PsychoPy 可以 运行 任何 Python 包,但是 Python 终端不能 运行 PsychoPy 代码,所以如果你试图在没有 PsychoPy 的情况下自己 运行 这个,它可能行不通。
# 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
# 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
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
# Creating the ball
ball = visual.Circle(win, edges=100,radius=0.02, fillColor='white', lineColor=None, pos=[position,position])
# Creating the wheel
wheel = visual.RadialStim(win, pos=(0,0), size=((wheel_radius * 2), (wheel_radius * 2)),
color =('red', 'blue', 'white'), angularRes=300,
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()
尽我所能,我无法使纹理方法起作用,但我选择了一个少得多的 eloquent 解决方案。通过降低 RadialStim 的不透明度并以半不透明度覆盖另一个补色的 RadialStim,并以 30 度角放置,我能够或多或少地创建四种颜色的外观。不激动,但现在就可以了。期待其他人出现。
# 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
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
# Creating the ball
ball = visual.Circle(win, edges=100,radius=0.02, fillColor='white', lineColor=None, pos=[position,position])
# Creating the wheel
wheel_base = visual.RadialStim(win, pos=(0,0), size=((wheel_radius * 2), (wheel_radius * 2)),
color ='yellow', angularRes=300,
angularCycles=3, radialCycles = 0, opacity= 0.9, autoLog=False)
wheel_layer = visual.RadialStim(win, pos=(0,0), size=((wheel_radius * 2), (wheel_radius * 2)),
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)),
((math.cos(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()