psychopy.org | Reference | Downloads | Github

Visual wedge asymmetry

screen

#1

Hi everyone, hoping you can help me figure out why the wedge I’m plotting seems to be asymmetric with respect to an array of dots, both of which should be aligned to vertical down.

This is a timing experiment based on the arcade game Cyclone. There is a circle of “lights” that “turn on” (flip black to white; excluded below for simplicity) in sequence counterclockwise from the bottom, such that the time from first to last is 1 sec. Subjects must respond within a given tolerance of the 1 sec interval to be right. The tolerance is plotted as a wedge covering the appropriate region of the loop of “lights”, and is adjusted using a simple 3 up 1 down staircase.

The problem is the wedge for the target zone isn’t centered on the bottom vertical (-180 degrees for radialStim, or -90/+270 degrees for pol2cart), which you can tell by looking at the edges compared to the evenly spaced dots (assuming pol2cart is plotting them correctly). When printing the right edge (origin) and left edge (origin+visibleWedge), the angles are correct, but the actual stimulus still isn’t aligned properly. This is true for both even and odd numbers of circles in the loop, and the circles are always evenly spaced by the linspace command and should thus be symmetrical regardless.

Is there something low level in the plotting I’m missing? Obviously, this is messing up the aesthetics of my paradigm and is incorrectly representing the target zone to participants.

Code below. System is Mac OSX 10.10.5, PsychoPy v1.84.2. Attached are screenshots of this default, plus after one iteration of update

# Parameters
loop_radius = 10
n_circ = 30
interval_dur = 1                    # duration (in sec) of target time interval
angle_ratio = 360/float(interval_dur)
tolerances = 0.125                   # allowed error in sec on EACH side

# Stimuli
win = visual.Window(size=(1920, 1200), fullscr=True, color=(0,0,0),
                    monitor='testMonitor',
                    allowGUI=False, units='cm')
target_zone = visual.RadialStim(win, tex='sqrXsqr', color='green', size=(loop_radius*2) + 1.5,  # size here = diameter
    visibleWedge=[0, angle_ratio * (tolerances*2)], radialCycles=1, angularCycles=0, interpolate=False,
    autoLog=False, units='cm')  
target_zone.ori = 180 - (tolerances * angle_ratio)   # zero starts at 12 oclock for radial stim.  
target_zone_cover = visual.Circle(win, radius = loop_radius - 1.5/2, edges=100,
    lineColor=None, fillColor=[0, 0, 0]) # Covers center of target zone wedge

circ_angles = np.linspace(-90,270,n_circ)
circ_X, circ_Y = pol2cart(circ_angles,[loop_radius] * n_circ)
circles = visual.ElementArrayStim(win, nElements=n_circ,sizes=.3,xys = zip(circ_X, circ_Y),
                           elementTex = None, elementMask = "circle",
                           colors=[(-1,-1,-1)] * n_circ)


# Plot first time
target_zone.draw()
target_zone_cover.draw()
circles.draw()
win.flip()

# Assume incorrect response, update target zone
tolerances+= 0.012    # add 0.012 sec to tolerance
target_zone.visibleWedge = [0,  2*tolerances*angle_ratio]
target_zone.ori = 180 - (tolerances * angle_ratio)

# Draw again for second attached image...

#2

Try increasing the angularRes parameter for the RadialStim to something like 360.


#3

Beautiful! angularRes=360 got close, and 500 seems to have done the trick. Thanks very much @djmannion!

One side concern- does anyone have a feel for how badly individual complex stimuli slow things down, say compared to having a bunch of simple stimuli? Just wondering if arbitrarily bumping up the angularRes is going to have consequences more comparable to drawing lots of circle stimuli or more like a single, large elementStimArray…