Hi There!
This is a fun one and does require some coding alright! Here is a demo, but let me talk it through so you know how to change it, build on it and learn some coding!
makeCircles.psyexp (20.7 KB)
First we need a few functions (these are in the “initialize” routine).
- A function to check if 2 circles overlap (locally, we can use overlaps but since you are using circles it is easy to calculate manually, and this one works online too).
def customOverlaps(a, b):
''' a custom function to detect overlap between circular objects
Locally we can use psychopys inbuild overlaps method, this does not
yet exist in psychoJS so we need a custom function for online use.
input:
a: a circular object with attributed pos and size
b: a circular object with attributes pos and size'''
pt1 = a.pos
pt2 = b.pos
sep = ((pt1[0]-pt2[0])**2+(pt1[1]-pt2[1])**2)**0.5
# if the seperation is less than the sum of the radi
if sep < a.size[0]/2 + b.size[0]/2:
return True
else:
return False
- A function to check if a smaller circle is inside a larger circle
def insideCircle(circle1, circle2):
'''
circle1: larger circle
circle2: smaller circle
return: boolean true or false if smaller circle inside larger
'''
x1 = circle1.pos[0]
y1 = circle1.pos[1]
r1 = circle1.size[0]/2
x2 = circle2.pos[0]
y2 = circle2.pos[1]
r2 = circle2.size[0]/2
distSq = (((x1 - x2)* (x1 - x2))+ ((y1 - y2)* (y1 - y2)))**(.5)
isInside = False
if (distSq + r2 == r1):
print("The smaller circle lies completely"
" inside the bigger circle with "
"touching each other "
"at a poof circumference. ")
elif (distSq + r2 < r1):
print("The smaller circle lies completely"
" inside the bigger circle without"
" touching each other "
"at a poof circumference. ")
isInside = True
else:
print("The smaller does not lies inside"
" the bigger circle completely.")
return isInside
OK then in your main trial
routine you need to make a set of circles in code, we actually now have a tutorial on how this works here - in case you want to learn more coding. The difference with your code is we start with a blank white circle, wait for a key response then add more stimuli to be drawn, in the end routine tab:
# if the right arrow was pressed, add a circle to the circle list
if key_resp.keys == 'right':
circleSet = False
while not circleSet:
# make a circle in a random location (can use same method to make random size)
thisCircle = visual.Polygon(
win=win, name='black_circle',
edges=100, size=(0.2, 0.2),
ori=0.0, pos=(random()-0.5, random()-0.5),# using random to pick random position (-0.5 to center around 0 in height units)dividing by 2 so it will always be in perimiter of large circle
lineWidth=1.0, colorSpace='rgb', lineColor='white', fillColor='black',
opacity=None, depth=0.0, interpolate=True)
overlap = False # do the circles overlap each other
for circle in circleList:
if customOverlaps(circle, thisCircle):
print('circle overlaps with existing circle, creating new one')
overlap = True
isInside = insideCircle(whiteCircle, thisCircle) # is the circle inside he white circle
if not overlap and isInside:
circleList.append(thisCircle)
circleSet = True
elif key_resp.keys == 'left':
continueRoutine = False
addCircleLoop.finished = True
OK, so I hope this gives you the framework to move forward!
Becca
please note that I made this with local use in mind as you didn’t mention this would be online. If you want to take this online at the moment you will need to do some work to aid the pythong to javascript translation - I highly recommend looking at the crib sheet) - hope this helps