1

Here is the module I'm using: http://mcsp.wartburg.edu/zelle/python/graphics/graphics.pdf

I want to see whether a user's clicks are within a shape or not. I used the in operator, but I know that is incorrect. Below is a chunk of my code:

win = GraphWin("Click Speed", 700, 700)

theTarget = drawTarget(win, random.randrange(0,685), random.randrange(0,685))

while theTarget in win:
    click = win.getMouse()
    if click in theTarget:
        print("Good job")

I left out the code that draws theTarget shape because it is length and unnecessary. It is a moving circle.

I'm using a while loop so it allows me to constantly get the user's clicks.

How do I go about checking whether or not a user's clicks are in the specified Target shape by using the getMouse() command?

I'm going to have to use this in the future for more abstract shapes (not simple circles).

lemon master
  • 209
  • 2
  • 5
  • 11

1 Answers1

2

Circle

For the simple case of a circle, you can determine whether the mouse is inside using the distance formula. For example:

# checks whether pt1 is in circ
def inCircle(pt1, circ):

    # get the distance between pt1 and circ using the
    # distance formula
    dx = pt1.getX() - circ.getCenter().getX()
    dy = pt1.getY() - circ.getCenter().getY()
    dist = math.sqrt(dx*dx + dy*dy)

    # check whether the distance is less than the radius
    return dist <= circ.getRadius()

def main():
    win = GraphWin("Click Speed", 700, 700)

    # create a simple circle
    circ = Circle(Point(350,350),50)
    circ.setFill("red")
    circ.draw(win)

    while True:
        mouse = win.getMouse()
        if inCircle(mouse,circ):
            print ("Good job")

main()

Oval

For the more advanced example of an ellipse we will need to use a formula found here. Here is the function implemting that:

def inOval(pt1, oval):

    # get the radii
    rx = abs(oval.getP1().getX() - oval.getP2().getX())/2
    ry = abs(oval.getP1().getY() - oval.getP2().getY())/2

    # get the center
    h = oval.getCenter().getX()
    k = oval.getCenter().getY()

    # get the point
    x = pt1.getX()
    y = pt1.getY()

    # use the formula
    return (x-h)**2/rx**2 + (y-k)**2/ry**2 <= 1

Polygon

For a polygon of abitrary shape we need to reference this. I have converted that to a python equivalent for you. Check the link to see why it works because I am honestly not sure

def inPoly(pt1, poly):

    points = poly.getPoints()
    nvert = len(points) #the number of vertices in the polygon

    #get x and y of pt1
    x = pt1.getX()
    y = pt1.getY()

    # I don't know why this works
    # See the link I provided for details
    result = False
    for i in range(nvert):

        # note: points[-1] will give you the last element
        # convenient!
        j = i - 1

        #get x and y of vertex at index i
        vix = points[i].getX()
        viy = points[i].getY()

        #get x and y of vertex at index j
        vjx = points[j].getX()
        vjy = points[j].getY()

        if (viy > y) != (vjy > y) and (x < (vjx - vix) * (y - viy) / (vjy - viy) + vix):
            result = not result

    return result
averes
  • 81
  • 2