psychopy.org | Reference | Downloads | Github

Checking stimulus overlap while ignoring translucent pixels

Hello!

I am new to PsychoPy and am still getting comfortable with it. I have a black circle surrounded by a hollow ring (a ball-in-hoop situation) - the ball is supposed to move, and participants should guide the ring to make sure it always surrounds the ball, and the trial will end if participants lag and the edge of the ring touches the ball at any point.

Right now I have my simple script:

#PSYCHOPY SETUP

img_dir = 'images'
win = visual.Window(
    size=[1200, 700],
    units="pix",
    fullscr=False
)
circle = visual.ImageStim(
    win=win,
    image=path.join(img_dir, "circle.png"),
    units="pix"
)
ring = visual.ImageStim(
    win=win,
    image=path.join(img_dir, "ring.png"),
    units="pix"
)
ring.size = np.round(ring.size * 0.75)


#LOOP
waitingForSpace = True
#draw the stimuli and update the window
while waitingForSpace: #this creates a never-ending loop
    scan_codes, _, _ = wp.read_full_buffer()
    if HID_CODE_SPACE in scan_codes:
        waitingForSpace = False
    print(circle.overlaps(ring))
    print(ring.overlaps(circle))
    circle.draw()
    star.draw()
    win.flip()

(please ignore the wp bits, that is regarding our weird keyboard). The print statements above are pumping out Trues. Is it possible to set this up so that the script only cares about the non-transparent edge of the ring? Am I asking too much?

Any guidance would be greatly appreciated!

Sincerely,
Henry

If it is mainly collision detection you are after, then it doesn’t really matter whether you use shape or image stimuli, you just need to know the relative positions of the centres of each of the stimuli and their difference in radius.

The .overlaps() method of the ShapeStim class is not where you want to go here, as ImageStim is inherently rectangular. Just handle the geometry yourself, based on the Euclidean distance between the centres of the two stimuli.

Let’s say your ring stimulus is 20 pixels in radius larger than the inner ball stimulus. Then if the absolute Euclidean distance between the centres of two stimuli is less than 20 pixels, then the inner stimulus is contained entirely within the outer one. If it exceeds 20 pixels, then they are overlapping (unless it exceeds the sum of their two radii, in which case, one is completely outside the other).

Lastly, I would recommend using ShapeStim instead of ImageStim, and in particular the Circle class:

https://www.psychopy.org/api/visual/shapestim.html
https://www.psychopy.org/api/visual/circle.html

That way you can easily manipulate the attributes of your stimulus (size, line thickness, colour, etc) in code, rather than having to craft a bitmap stimulus externally. They also aren’t constrained to have rectangular boundaries in terms of mouse click detection, which can make it superior for clicking and dragging a stimulus, as only clicks within the ring will be valid.

1 Like

Hi Michael,

These were incredibly clear and helpful notes. Thank you very much!

Henry

1 Like