示例#1
0
def jarvis(points, cutoff=False):
    if cutoff: points = interior_elimination(points)

    #removing duplicate points
    pts = list(set(points))
   
    P0 = min(pts, key=lambda p: (p[1], p[0]))
    H = [P0]
    
    # Since 'for loops' works as generators, 'H' is gonna be 
    # populated within the loop and 'h' will always be
    # the most recent added. In the last iteration, 'H' won't
    # be updated (case when P0 is reached again) 
    # and the 'for loop' ends.
    for h in H:
        a = h 
        for b in pts:
            if ccw(h, a, b) < 0 or (ccw(h, a, b) == 0 and \
                distance(h, b) > distance(h, a)):
                a = b
        if a is not P0:
            H.append(a)

    assert is_convex(H)
    return H
示例#2
0
def andrew(points, cutoff=False):
    if cutoff: points = interior_elimination(points)
    pts = sorted(set(points))
    H = half_hull(pts)[:-1] + \
        half_hull(reversed(pts))[:-1]

    assert is_convex(H)
    return H
示例#3
0
def andrew(points, cutoff=False):
    if cutoff: points = interior_elimination(points)
    pts = sorted(set(points))
    H = half_hull(pts)[:-1] + \
        half_hull(reversed(pts))[:-1]

    assert is_convex(H)
    return H
示例#4
0
def graham(points, cutoff=False):
    if cutoff: points = interior_elimination(points)

    #removing duplicate points
    pts = list(set(points)) 

    P0 = min(pts, key=lambda p: (p[1], p[0]))
    pts.remove(P0)

    # sorting by polar angles and ignoring collinear points 
    # (keeping the farthest one)
    to_ignore = {}
    pts.sort(lambda B, C: compare(P0, B, C, to_ignore))

    H = [P0] + pts[:2]

    for i in range(2, len(pts)):
        if pts[i] in to_ignore: continue
        while ccw(H[-2], H[-1], pts[i]) <= 0:
            H.pop()
        H.append(pts[i])

    assert is_convex(H)
    return H
示例#5
0
def graham(points, cutoff=False):
    if cutoff: points = interior_elimination(points)

    #removing duplicate points
    pts = list(set(points))

    P0 = min(pts, key=lambda p: (p[1], p[0]))
    pts.remove(P0)

    # sorting by polar angles and ignoring collinear points
    # (keeping the farthest one)
    to_ignore = {}
    pts.sort(lambda B, C: compare(P0, B, C, to_ignore))

    H = [P0] + pts[:2]

    for i in range(2, len(pts)):
        if pts[i] in to_ignore: continue
        while ccw(H[-2], H[-1], pts[i]) <= 0:
            H.pop()
        H.append(pts[i])

    assert is_convex(H)
    return H
示例#6
0
def plot(points):
    SIZE = (1024, 768)
    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    GREEN = (0, 255, 0)
    RED = (255, 0, 0)
    BLUE = (0, 0, 255)
    GRAY = (100, 100, 100)
    MARGIN = 50
    PANELW = 200
    SAMPLE = 100
    LIMIT = 1000
    ZOOM = 10
    CIRCLE = 2

    up_sample = False
    down_sample = False
    x, y = 0, 0
    pygame.init()
    # ch = graham(points[:])
    # ch = jarvis(points[:])
    # ch = andrew(points[:])
    ch = graham(points[:])

    screen = pygame.display.set_mode(SIZE)

    def scale(points):
        xmax = max(points, key=lambda p: p[0])[0]
        xmin = min(points, key=lambda p: p[0])[0]
        ymin = min(points, key=lambda p: p[1])[1]
        ymax = max(points, key=lambda p: p[1])[1]
        dx = float(xmax - xmin)
        dy = float(ymax - ymin)

        # preventing division per zero
        if dy == 0:
            dy = 0.0001
        if dx == 0:
            dx = 0.0001

        wx = float(1024 - 2 * MARGIN - PANELW)
        hy = float(768 - 2 * MARGIN)

        pts = map(lambda p: (p[0] + -xmin, ymax - p[1]), points)

        pts = map(lambda p: (p[0] * 724.0 / dx, p[1] * 668.0 / dy), pts)

        xmaxk = max(pts, key=lambda p: p[0])[0]
        xmink = min(pts, key=lambda p: p[0])[0]
        ymaxk = max(pts, key=lambda p: p[1])[1]
        ymink = min(pts, key=lambda p: p[1])[1]
        dxk = (MARGIN + wx / 2.0) - (xmaxk - xmink) / 2.0
        dyk = (MARGIN + hy / 2.0) - (ymaxk - ymink) / 2.0

        pts = map(lambda p: (p[0] + dxk, p[1] + dyk), pts)

        pts = map(lambda p: (int(p[0]), int(p[1])), pts)
        # pygame.draw.circle(screen, (0, 255, 0), (MARGIN + int(wx/2.), MARGIN + int(hy/2.)), 2)
        return pts

    def random_points():
        wx = float(1024 - 2 * MARGIN - PANELW)
        hy = float(768 - 2 * MARGIN)
        # return [(random.randrange(-wx, wx), random.randrange(-hy, hy)) for i in range(SAMPLE)]
        # return inside_rectangle(SAMPLE)
        # return inside_circle(SAMPLE)
        # return on_circle(SAMPLE)
        return inside_triangle(SAMPLE)

    while 1:
        for event in pygame.event.get():
            if event.type == pygame.MOUSEMOTION:
                x, y = event.pos
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    sys.exit()
                elif event.key == pygame.K_UP:
                    up_sample = True
                elif event.key == pygame.K_DOWN and SAMPLE > 3:
                    down_sample = True
                elif event.key == pygame.K_r:
                    restart = True
                    points = random_points()
                    # ch = graham(points[:])
                    # ch = jarvis(points[:])
                    # ch = andrew(points[:])
                    ch = graham(points[:])
                    print len(ch)
                    # print ch
                elif event.key == pygame.K_e:
                    pts = interior_elimination(points)
                    print len(points), len(pts)
                    points = pts

            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_UP:
                    up_sample = False
                elif event.key == pygame.K_DOWN:
                    down_sample = False

        if up_sample:
            SAMPLE += 1
        if down_sample and SAMPLE > 3:
            SAMPLE -= 1

        screen.fill(WHITE)

        def draw_ch():
            # plot axis lines
            pygame.draw.aaline(screen, GRAY, (0, SIZE[1] / 2), (SIZE[0] - PANELW, SIZE[1] / 2), 2)
            pygame.draw.aaline(screen, GRAY, ((SIZE[0] - PANELW) / 2, 0), ((SIZE[0] - PANELW) / 2, SIZE[1]), 2)

            # plot convex hull edges
            pts = scale(ch)
            for p in range(1, len(pts)):
                pygame.draw.aaline(screen, BLUE, pts[p - 1], pts[p], 2)
            pygame.draw.aaline(screen, BLUE, pts[-1], pts[0], 2)

            # plot points
            pts = scale(points)
            for point in pts:
                pygame.draw.circle(screen, RED, point, CIRCLE)
            pygame.draw.rect(screen, GRAY, (SIZE[0] - PANELW, 0, PANELW, SIZE[1]))

            # plot convex hull vertices
            pts = scale(ch)
            for p in pts:
                pygame.draw.circle(screen, BLACK, p, CIRCLE + 1)

        draw_ch()

        # plot text
        text = pygame.font.SysFont("", 20)
        label = text.render("Commands", 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, 0.5 * MARGIN))

        text = pygame.font.SysFont("", 15)
        label = text.render("r: randomize points", 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, MARGIN))

        text = pygame.font.SysFont("", 15)
        label = text.render("e: eliminate points", 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, 1.5 * MARGIN))

        label = text.render("up arrow: increase sample size", 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, 2 * MARGIN))

        label = text.render("down arrow: decrease sample size", 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, 2.5 * MARGIN))

        label = text.render("Sample size: %d" % SAMPLE, 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, 3 * MARGIN))

        label = text.render("Mouse position: %d, %d" % (x, y), 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, 15 * MARGIN))

        pygame.display.flip()
示例#7
0
def plot(points):
    SIZE = (1024, 768)
    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    GREEN = (0, 255, 0)
    RED = (255, 0, 0)
    BLUE = (0, 0, 255)
    GRAY = (100, 100, 100)
    MARGIN = 50
    PANELW = 200
    SAMPLE = 100 
    LIMIT = 1000
    ZOOM = 10
    CIRCLE = 2

    up_sample = False
    down_sample = False
    x, y = 0, 0
    pygame.init()
    #ch = graham(points[:])
    #ch = jarvis(points[:])
    #ch = andrew(points[:])
    ch = graham(points[:])

    screen = pygame.display.set_mode(SIZE)


    def scale(points):
        xmax = max(points, key=lambda p: p[0])[0]
        xmin = min(points, key=lambda p: p[0])[0]
        ymin = min(points, key=lambda p: p[1])[1]
        ymax = max(points, key=lambda p: p[1])[1]
        dx = float(xmax - xmin)
        dy = float(ymax - ymin)

        # preventing division per zero
        if dy == 0: dy = 0.0001
        if dx == 0: dx = 0.0001

        wx = float(1024 - 2*MARGIN - PANELW)
        hy = float(768 - 2*MARGIN)
        
        pts = map(lambda p: (p[0] + -xmin, ymax - p[1]), points)

        pts = map(lambda p: (p[0]*724./dx, p[1]*668./dy), pts)

        xmaxk = max(pts, key=lambda p: p[0])[0]
        xmink = min(pts, key=lambda p: p[0])[0]
        ymaxk = max(pts, key=lambda p: p[1])[1]
        ymink = min(pts, key=lambda p: p[1])[1]
        dxk = (MARGIN + wx/2.) - (xmaxk - xmink)/2. 
        dyk = (MARGIN + hy/2.) - (ymaxk - ymink)/2. 

        pts = map(lambda p: (p[0] + dxk, p[1] + dyk), pts)

        pts =  map(lambda p: (int(p[0]), int(p[1])), pts) 
        #pygame.draw.circle(screen, (0, 255, 0), (MARGIN + int(wx/2.), MARGIN + int(hy/2.)), 2)
        return pts


    def random_points():
        wx = float(1024 - 2*MARGIN - PANELW)
        hy = float(768 - 2*MARGIN)
        #return [(random.randrange(-wx, wx), random.randrange(-hy, hy)) for i in range(SAMPLE)]
        #return inside_rectangle(SAMPLE)
        #return inside_circle(SAMPLE)
        #return on_circle(SAMPLE)
        return inside_triangle(SAMPLE)

    while 1:
        for event in pygame.event.get():
            if event.type == pygame.MOUSEMOTION:
                x, y = event.pos
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    sys.exit()
                elif event.key == pygame.K_UP:
                    up_sample = True
                elif event.key == pygame.K_DOWN and SAMPLE > 3:
                    down_sample = True
                elif event.key == pygame.K_r:
                    restart = True
                    points = random_points()
                    #ch = graham(points[:])
                    #ch = jarvis(points[:])
                    #ch = andrew(points[:])
                    ch = graham(points[:])
                    print len(ch)
                    #print ch
                elif event.key == pygame.K_e:
                   pts = interior_elimination(points) 
                   print len(points), len(pts)
                   points = pts

            elif event.type == pygame.KEYUP:
                if event.key == pygame.K_UP:
                    up_sample = False
                elif event.key == pygame.K_DOWN:
                    down_sample = False

        if up_sample: SAMPLE += 1
        if down_sample and SAMPLE > 3: SAMPLE -= 1

        screen.fill(WHITE)

        
        def draw_ch():
            #plot axis lines
            pygame.draw.aaline(screen, GRAY, (0, SIZE[1]/2), (SIZE[0] - PANELW, SIZE[1]/2), 2)
            pygame.draw.aaline(screen, GRAY, ((SIZE[0] - PANELW)/2, 0), ((SIZE[0] - PANELW)/2, SIZE[1]), 2)

            #plot convex hull edges
            pts = scale(ch)
            for p in range(1, len(pts)):
                pygame.draw.aaline(screen, BLUE, pts[p-1], pts[p], 2)
            pygame.draw.aaline(screen, BLUE, pts[-1], pts[0], 2)

            #plot points
            pts = scale(points)
            for point in pts:
                pygame.draw.circle(screen, RED, point, CIRCLE)
            pygame.draw.rect(screen, GRAY, (SIZE[0] - PANELW, 0, PANELW, SIZE[1]))

            #plot convex hull vertices
            pts = scale(ch)
            for p in pts:
                pygame.draw.circle(screen, BLACK, p, CIRCLE + 1)
    
        draw_ch()
    
        #plot text
        text = pygame.font.SysFont("", 20)
        label = text.render("Commands", 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, 0.5*MARGIN))


        text = pygame.font.SysFont("", 15)
        label = text.render("r: randomize points", 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, MARGIN))

        text = pygame.font.SysFont("", 15)
        label = text.render("e: eliminate points", 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, 1.5*MARGIN))

        label = text.render("up arrow: increase sample size", 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, 2*MARGIN))

        label = text.render("down arrow: decrease sample size", 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, 2.5*MARGIN))

        label = text.render("Sample size: %d" % SAMPLE, 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, 3*MARGIN))
        
        label = text.render("Mouse position: %d, %d" % (x, y), 1, WHITE)
        screen.blit(label, (SIZE[0] - PANELW + 20, 15*MARGIN))

        pygame.display.flip()