Python Forum
how to make complex shapes using swarm of dots......like chair,rocket and many more
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
how to make complex shapes using swarm of dots......like chair,rocket and many more
#1
# 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 30-star #####
filename = '30-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()
Output:
[img]https://drive.google.com/open?id=1PjnxxuHCU8SGJcHckP1Oc1QQgEi2GK2U[/img]
Reply
#2
Cool :)
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Try Python without dots! Gribouillis 5 3,919 May-30-2021, 02:37 PM
Last Post: Gribouillis

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020