Detecting collision when rotating
Question: I have a chain of squares represented in pygame. I have some code that lets me
rotate parts of the chain, as follows.

    
    
    #!/usr/bin/python
    import pygame
    
    def draw(square):
        (x,y) = square
        pygame.draw.rect(screen, black, (100+x*20,100+y*20,20,20), 1) 
    
    def rotate(chain, index, direction):
        (pivotx, pivoty) = chain[index]
        if (direction == 1):
            newchain = chain[:index]+[(y-pivoty+pivotx, (x-pivotx)+pivoty) for (x,y) in chain[index:]]
        else:
            newchain = chain[:index]+[(y-pivoty+pivotx, -(x-pivotx)+pivoty) for (x,y) in chain[index:]]
        return newchain
    
    pygame.init()
    
    size = [600, 600]
    screen = pygame.display.set_mode(size)
    white = (255,255,255)
    black = (0,0,0)
    
    n = 20
    chain = [(i,0) for i in xrange(n)]
    
    screen.fill(white)
    for square in chain:
        draw(square)
    
    pygame.display.flip()
    raw_input("Press Enter to continue...")
    newchain = rotate(chain, 5, 1)
    print chain
    print newchain
    screen.fill(white)
    for square in newchain:
        draw(square)
    
    pygame.display.flip()
    raw_input("Press Enter to continue...")
    
    screen.fill(white)
    newchain = rotate(newchain, 10,0)
    for square in newchain:
        draw(square)
    
    pygame.display.flip()
    raw_input("Press Enter to continue...")
    pygame.quit()
    

The function rotate takes an index of a square in the chain and rotates the
whole chain after that square by 90 degrees, pivoting around the initial
square. The problem is that this is meant to mimic a physical toy so it is not
allowed to collide with itself. I can check to see if two squares are on top
of each other after a rotation but how can I make sure they wouldn't collide
temporarily during a rotation?


Answer: It sounds like you already know how to know if they're overlapping once you do
the rotation, unless I am misunderstanding. If that's the case, then it would
be relatively easy to define a function to answer that question given a
potential rotation in the chain by adding a check to the end of your
comprehension:

    
    
    if (direction == 1):
        newchain = chain[:index]+[(y-pivoty+pivotx, (x-pivotx)+pivoty) for (x,y) in chain[index:] if not overlapping(x, y, pivotx, pivoty)]
    else:
        newchain = chain[:index]+[(y-pivoty+pivotx, -(x-pivotx)+pivoty) for (x,y) in chain[index:] if not overlapping(x, y, pivotx, pivoty)]
    

And of course relying on some kind of:

    
    
    def overlapping(x, y, px, py):
        if (some logic that determins if this is bad):
            raise Exception('Overlapping')
        return True
    

You would need to do something useful with the exception, but at least this
would check each square as you process it, and break out immediately instead
of waiting until after the whole rotation to verify that it's good.

