예제 #1
0
    def generate_attraction_points(self, N):
        """ drop shape from:
https://math.stackexchange.com/a/481988/660780 """
        i = 0
        points = []
        while i < N:
            x, y, z = np.random.rand(3)
            x = remap(x, 0, 1, -1, 1)
            y = remap(y, 0, 1, -1, 1)
            z = remap(z, 0, 1, -1, 0)
            in_drop_shape = (x**2 + y**2 + z**4 - z**2 <= 0)
            if in_drop_shape:
                points.append((x, remap(z, -1, 0, 1, 2), y))
                i += 1
        return points
예제 #2
0
def run(args):
    MIN_LEN = 10
    MAX_LEN = 70

    dx_noise = OpenSimplex(42)
    dx_noise_mult = 0.010
    dy_noise = OpenSimplex(211)
    dy_noise_mult = 0.010

    img = cv2.imread(args.pic)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    H, W = gray.shape[:2]
    pos = np.random.randint(0, min(H, W), size=2).astype(np.float64)
    path = [pos.copy()]

    i = 0
    ITER = 50000
    pbar = tqdm.tqdm(total=ITER)
    while i < ITER:
        # direction = np.random.rand(2) - 0.5
        dx = dx_noise.noise2d(x=pos[0] * dx_noise_mult,
                              y=pos[1] * dx_noise_mult)
        dy = dy_noise.noise2d(x=pos[0] * dy_noise_mult,
                              y=pos[1] * dy_noise_mult)
        direction = np.array([dy, dx])
        direction /= np.linalg.norm(direction)
        try:
            value = gray[int(np.round(pos[0])), int(np.round(pos[1]))]
        except IndexError:
            value = 255
        length = remap(value, 0, 255, MIN_LEN, MAX_LEN)
        length = MAX_LEN
        new_pos = pos + direction * length
        if np.any(new_pos < 0) or np.any(new_pos >= (H, W)):
            direction = np.array([H / 2, W / 2]) - pos
            direction /= np.linalg.norm(direction)
        pos += direction * length

        path.append(pos.copy())
        i += 1
        pbar.update()
    pbar.close()

    vis = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR)
    path = np.round(path).astype(np.int32)
    print('path.shape: {}'.format(path.shape))
    # print('path: {}'.format(path))
    for i in range(1, path.shape[0]):
        cv2.line(vis, tuple(path[i - 1, ::-1]), tuple(path[i, ::-1]),
                 (0, 0, 255), 1)

    # cv2.imshow("cv: img", img)
    # cv2.imshow("cv: gray", gray)
    cv2.imshow("cv: vis", vis)
    while True:
        c = cv2.waitKey(0)
        if c == ord('q'):
            break
    return 0
예제 #3
0
def squiggle(points, r=10):
    r_noise = OpenSimplex(42)
    angle_noise = OpenSimplex(211)
    result = []
    r_noise_mult = 0.01
    angle_noise_mult = 0.02
    angles = []
    pts = np.concatenate((points[-1, np.newaxis, :], points),
                         axis=0).astype(np.float32)
    prev_dist = 0
    for i in tqdm.tqdm(range(1, len(pts))):
        prev_pt = pts[i - 1, :]
        pt = pts[i, :]
        dist = np.linalg.norm(prev_pt - pt)
        for step in np.linspace(0, 1, 100):
            cur_dist = step * dist + (1 - step) * prev_dist
            x = prev_pt[0] + step * (pt[0] - prev_pt[0])
            y = prev_pt[1] + step * (pt[1] - prev_pt[1])

            new_r = remap(
                r_noise.noise2d(x=x * r_noise_mult, y=y * r_noise_mult),
                -1,
                1,
                cur_dist / 2,
                cur_dist,
            )
            new_angle = remap(
                angle_noise.noise2d(x=x * angle_noise_mult,
                                    y=y * angle_noise_mult),
                -1,
                1,
                0,
                2 * np.pi,
            )
            # new_angle = angle
            angles.append(new_angle)
            x = new_r * np.cos(new_angle) + prev_pt[0] + step * (pt[0] -
                                                                 prev_pt[0])
            y = new_r * np.sin(new_angle) + prev_pt[1] + step * (pt[1] -
                                                                 prev_pt[1])
            result.append((x, y))
        prev_dist = dist

    return np.array(result)
예제 #4
0
 def d_sep_fn(pos):
     x, y = clip_to_img(np.round(pos), gray).astype(np.int32)
     val = gray[y, x] / 255
     val = val**2
     return remap(val, 0, 1, 0.8, 10)
예제 #5
0
def chiu2015tone_scribble(points, r=1, speed_img=None, edge_dist_img=None):
    points = points.astype(np.float32)
    r_abs_min = 10
    r_min = 20
    r_max = r
    r = r  # disk radius

    # state
    tracer = PolylineTracer(points)
    pos = tracer.step(0)
    angle = 0

    angular_velocity = np.pi / 10  # radians per time unit
    # min_pos_velocity = 0.1  # pixels per time unit
    # max_pos_velocity = 5  # pixels per time unit
    min_pos_velocity = 0.1  # pixels per time unit
    max_pos_velocity = 13  # pixels per time unit
    step_frequency = 1  # steps per time unit

    def velocity_at_pos(x):
        if speed_img is None:
            coeff = 1
        else:
            int_pos = clip_to_img(np.int32(np.round(x)), speed_img)
            coeff = speed_img[int_pos[1], int_pos[0]]
            # coeff = piecewise_linear(coeff,
            #                          (0, 0.0),
            #                          (0.2, 0.1),
            #                          (0.21, 1),
            #                          (1, 1))
            # coeff = 0.2

        velocity = min_pos_velocity + coeff * (max_pos_velocity -
                                               min_pos_velocity)
        return velocity

    def radius_at_pos(x):
        int_pos = clip_to_img(np.int32(np.round(x)), speed_img)

        coeff = speed_img[int_pos[1], int_pos[0]]
        # coeff = piecewise_linear(coeff,
        #                          (0, 0.0),
        #                          (0.6, 0.1),
        #                          (0.61, 1),
        #                          (1, 1))
        radius = r_min + coeff * (r_max - r_min)
        if edge_dist_img is None:
            return radius
        else:
            edge_dist = edge_dist_img[int_pos[1], int_pos[0]]
            radius = np.clip(radius, r_min, edge_dist)
            radius = np.clip(radius, r_abs_min, r_max)
            return radius

    theta_noise = OpenSimplex(42)
    flat_noise = OpenSimplex(211)

    step = 0
    output_pts = []
    while pos is not None:
        step += 1
        # if step > 1000:
        #     break
        current_velocity = velocity_at_pos(pos)
        current_radius = radius_at_pos(pos)

        theta = remap(theta_noise.noise2d(x=0, y=step * 1e-2 / step_frequency),
                      -1, 1, 0, 2 * np.pi)
        flatness = remap(
            flat_noise.noise2d(x=0, y=step * 1e-2 / step_frequency), -1, 1,
            0.2, 1)
        R = rotation_matrix(theta)
        scribble_pos = np.array((flatness * current_radius * np.cos(angle),
                                 current_radius * np.sin(angle)))
        scribble_pos = np.matmul(R, scribble_pos)
        scribble_pos = pos + scribble_pos

        output_pts.append(scribble_pos)

        pos = tracer.step(current_velocity / step_frequency)
        # pos = tracer.step(4)
        angle += angular_velocity / step_frequency

    output_pts = np.array(output_pts)
    return output_pts
예제 #6
0
def rev_geomspace(start, stop, num):
    return remap(np.geomspace(start, stop, num), start, stop, stop, start)
예제 #7
0
def run(args):
    N_per_layer = 8
    N_per_blob = 21
    N_layers = 12
    r_min_layer = 5.5
    r_layer_step = 1.6
    N_per_circle = 30
    r_circle_min = 0.05
    r_circle_max = 1.1

    paths = []
    for i_layer in range(N_layers):
        r_layer = r_min_layer + i_layer * r_layer_step
        center_angles = np.linspace(0,
                                    2 * np.pi,
                                    N_per_blob * N_per_layer,
                                    endpoint=False)
        # center_angles -= np.exp(remap(i_layer, 0, N_layers-1,
        #                               0, 0.6))
        # center_angles -= np.exp(i_layer*1.618 / N_layers)
        center_angles -= remap(i_layer, 0, N_layers - 1, 0, np.radians(120))
        # center_angles += 1.618033 * i_layer
        for i_blob in range(N_per_layer):
            for i_circle in range(N_per_blob):
                center_x = r_layer * np.cos(
                    center_angles[i_blob * N_per_blob + i_circle])
                center_y = r_layer * np.sin(
                    center_angles[i_blob * N_per_blob + i_circle])
                # r_circle = remap(abs(i_circle - N_per_blob // 2),
                #                  0, N_per_blob // 2,
                #                  r_circle_max, r_circle_min)
                r_circle = np.sin(remap(i_circle, 0, N_per_blob, 0,
                                        np.pi)) * r_circle_max + r_circle_min

                angle_start = np.random.rand() * 2 * np.pi
                angle_end = angle_start + 2 * np.pi
                angles = np.linspace(angle_start, angle_end, N_per_circle)
                sins = np.sin(angles)
                cosins = np.cos(angles)

                points = np.zeros((N_per_circle, 2))
                points[:, 0] = cosins * r_circle + center_x
                points[:, 1] = sins * r_circle + center_y
                paths.append(points)

    # plt.axis('equal')
    # vis_drawing(paths, 'k-', linewidth=0.1)
    # plt.gca().invert_yaxis()
    # plt.show()

    x_margin_mm = 10
    y_margin_mm = 10
    H = 210  # A4
    W = 297  # A4

    to_draw = resize_and_center(paths, H, W, x_margin_mm, x_margin_mm,
                                y_margin_mm, y_margin_mm)
    vis_drawing(to_draw, 'r-', linewidth=0.1)
    to_draw = optimize(to_draw, line_simplification_threshold=0.1)
    vis_drawing(to_draw, 'k-', linewidth=0.1)
    plt.plot([0, W, W, 0, 0], [0, 0, H, H, 0], 'k:')
    plt.axis('equal')
    plt.gca().invert_yaxis()
    plt.show()

    H = 210  # A4
    W = 297  # A4

    # baud = 115200
    baud = 9600
    with Plotter('/dev/ttyUSB0', baud) as p:
        p.load_config('config.json')
        p.set_input_limits((0, 0), (W, 0), (0, H), (W, H))
        p.draw_polylines(to_draw)

    return 0