как создавать сложные формы, используя рой точек ...... как стул, ракета и многое другое, используя пигмей и клочок - PullRequest
0 голосов
/ 18 апреля 2019

Я работаю над проектом алгоритмов роя и пытаюсь создавать сложные формы, используя консенсус роя.Тем не менее, математика для достижения этого кажется мне довольно сложной.

Мне удалось создать фигуры, такие как звезды, круги и треугольники, но сделать другие сложные фигуры кажется сложнее.Было бы очень полезно, если бы я получил представление об использовании массивов numpy для построения этих сложных фигур с использованием скоплений ....................................................


    # general function to reset radian angle to [-pi, pi)
    def reset_radian(radian):
        while radian >= math.pi:
            radian = radian - 2*math.pi
        while radian < -math.pi:
            radian = radian + 2*math.pi
        return radian



    # general function to calculate next position node along a heading direction
    def cal_next_node(node_poses, index_curr, heading_angle, rep_times):
        for _ in range(rep_times):
            index_next = index_curr + 1
            x = node_poses[index_curr][0] + 1.0*math.cos(heading_angle)
            y = node_poses[index_curr][1] + 1.0*math.sin(heading_angle)
            node_poses[index_next] = np.array([x,y])
            index_curr = index_next
        return index_next


    ##### script to generate star #####
    filename = 'star'
    swarm_size = 30
    node_poses = np.zeros((swarm_size, 2))
    outer_angle = 2*math.pi / 5.0
    devia_right = outer_angle
    devia_left = 2*outer_angle
    # first node is at bottom left corner
    heading_angle = outer_angle / 2.0  # current heading
    heading_dir = 0  # current heading direction: 0 for left, 1 for right
    seg_count = 0  # current segment count
    for i in range(1,swarm_size):
        node_poses[i] = (node_poses[i-1] +
            np.array([math.cos(heading_angle), math.sin(heading_angle)]))
        seg_count = seg_count + 1
        if seg_count == 3:
            seg_count = 0
            if heading_dir == 0:
                heading_angle = reset_radian(heading_angle - devia_right)
                heading_dir = 1
            else:
                heading_angle = reset_radian(heading_angle + devia_left)
                heading_dir = 0
    print(node_poses)
    with open(filename, 'w') as f:
        pickle.dump(node_poses, f)

    pygame.init()
    # find the right world and screen sizes
    x_max, y_max = np.max(node_poses, axis=0)
    x_min, y_min = np.min(node_poses, axis=0)
    pixel_per_length = 30
    world_size = (x_max - x_min + 2.0, y_max - y_min + 2.0)
    screen_size = (int(world_size[0])*pixel_per_length, int(world_size[1])*pixel_per_length)
    # convert node poses in the world to disp poses on screen
    def cal_disp_poses():
        poses_temp = np.zeros((swarm_size, 2))
        # shift the loop to the middle of the world
        middle = np.array([(x_max+x_min)/2.0, (y_max+y_min)/2.0])
        for i in range(swarm_size):
            poses_temp[i] = (node_poses[i] - middle +
                np.array([world_size[0]/2.0, world_size[1]/2.0]))
        # convert to display coordinates
        poses_temp[:,0] = poses_temp[:,0] / world_size[0]
        poses_temp[:,0] = poses_temp[:,0] * screen_size[0]
        poses_temp[:,1] = poses_temp[:,1] / world_size[1]
        poses_temp[:,1] = 1.0 - poses_temp[:,1]
        poses_temp[:,1] = poses_temp[:,1] * screen_size[1]
        return poses_temp.astype(int)
    disp_poses = cal_disp_poses()

    # draw the loop shape on pygame window
    color_white = (255,255,255)
    color_black = (0,0,0)
    screen = pygame.display.set_mode(screen_size)
    screen.fill(color_white)
    for i in range(swarm_size):
        pygame.draw.circle(screen, color_black, disp_poses[i], 5, 0)
    for i in range(swarm_size-1):
        pygame.draw.line(screen, color_black, disp_poses[i], disp_poses[i+1],2)
    pygame.draw.line(screen, color_black, disp_poses[0], disp_poses[swarm_size-1], 2)
    pygame.display.update()

1 Ответ

0 голосов
/ 18 апреля 2019

Ваш метод рисования использует огромное преимущество симметрии в фигурах, которые вы рисуете. Более сложные формы будут иметь меньше симметрий, поэтому вашему методу потребуется много утомительной работы, чтобы нарисовать их со звездами. Без симметрии вам лучше будет написать каждую отдельную строку «команда» в списке и следовать этому списку. Например, рисование числа 4, начиная снизу (при условии, что 0 градусов -> таким образом):

angles = [90,225,0]
distances = [20,15,12] 

Затем с помощью программы, аналогичной той, которая у вас есть, вы можете начать рисовать точки в линии под углом 90 градусов для 20 точек, затем для 225 градусов для 15 точек и т. Д. Затем, добавив к этим двум спискам, вы можете создать очень сложная форма без симметрии.

...