Create random circles according to an arithmetic calculation exercise

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

  1. 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
  1. 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

2 Likes