def draw_mandelbrot(r1=-2, r2=1, i1=-1, i2=1, tag=""): assert (r1 < r2 and i1 < i2) cx = (r1 + r2) / 2 cy = (i1 + i2) / 2 dif_r = abs(r1 - r2) dif_i = abs(i1 - i2) zoom_lvl = 3 / dif_r # increasing iterations by zoom level (found this one on net) iters = math.sqrt(2 * math.sqrt(abs(1 - math.sqrt(10 * zoom_lvl)))) * ITERS #iters = 50+math.log(((4/abs(dif_r))), 10)**5 print( "cx: %f, cy: %f, r1: %f, r2: %f, i1: %f, i2: %f, zoom_lvl: %f, iters: %f" % (cx, cy, r1, r2, i1, i2, zoom_lvl, iters)) img = BMPImage(width=WIDTH, height=HEIGHT, scale=1, bg="red", origin="cartesian") for xi in range(RES_X): x = r1 + dif_r * (xi / RES_X) for yi in range(RES_Y): y = i1 + dif_i * (yi / RES_Y) color = in_mandelbrot(x, y, iters) new_x = x * HEIGHT / 2 new_y = y * HEIGHT / 2 nx = map_point(new_x, -400, 200, r1 * 200, r2 * 200) ny = map_point(new_y, -200, 200, i1 * 200, i2 * 200) put_pixel(img, nx, ny, color) img.save("img/mandelbrot/{TAG}mandelbrot_{R1}_{R2}_{I1}_{I2}.bmp".format( TAG=tag, R1=r1, R2=r2, I1=i1, I2=i2))
def circle_implicit(save_file, r, a=None, b=None, img_scale=3): """ circle implicit (x-a)**2 + (y-b)**2 = r**2 """ img = BMPImage(scale=3) if not a and not b: a = img.get_width() / 2 b = img.get_height() / 2 for x in range(img.get_width()): for y in range(img.get_height()): if (x - a)**2 + (y - b)**2 < r**2: img.put_pixel(x, y, (0, 0, 0)) img.save(save_file)
def circle_parametric(save_file, r, edge_width, a=None, b=None, spirale_turns=1, img_scale=3): """ circle parametric x = a + r*cos(t) y = b + r*sin(t) spirale_turns: if > 1, circle will become spirale with spirale_turns turns """ img = BMPImage(width=1000, height=1000, scale=img_scale) if not a and not b: a = img.get_width() / 2 b = img.get_height() / 2 for t in range(360 * spirale_turns): for i in range(r, r + edge_width): ni = 0 if spirale_turns > 1: ni = t / spirale_turns x = a + (i + ni) * math.cos(math.radians(t)) y = a + (i + ni) * math.sin(math.radians(t)) img.put_pixel(x, y, (0, 0, 0)) img.save(save_file)
def draw_sierpinski_triangle(r=0.5, iterations=1000000, save_after=[100, 1000, 10000]): img = BMPImage(width=WIDTH, height=HEIGHT, scale=1, bg="black", origin="cartesian") SIDE = int(HEIGHT / 1.2) ITERATIONS = iterations DISCARD = 10 h = int((math.sqrt(3) / 2) * SIDE) a = (-SIDE / 2, -int(h / 2)) b = (SIDE / 2, -int(h / 2)) c = (0, int(h / 2)) x = get_random_point() for i in range(ITERATIONS): chosen_point = random.choice([a, b, c]) nx = point_between_points(chosen_point, x, r) if i > DISCARD: # Throw away first N points img.put_pixel(*nx, WHITE) x = nx if i in save_after: img.save( "img/chaos_game_sierpinski_r_{R}_after_{ITERS}.bmp".format( R=r, ITERS=i)) img.save("img/chaos_game_sierpinski_r_{R}_after_{ITERS}.bmp".format( R=r, ITERS=ITERATIONS))
def triangle(save_file, img_scale=3, a=None, b=None): """ triangle when using cartesian coords: y <= x+10 and y <= -x+10 and y >= 0 """ img = BMPImage(scale=img_scale, origin="cartesian") side = 70 for x in img.get_x_coords(): for y in img.get_y_coords(): if y <= x + side and y <= -x + side and y >= 0: img.put_pixel(x, y, (2 * abs(x), abs(x) + abs(y), 2 * abs(y))) img.save(save_file)
def draw_pascals(): DEPTH = 30 MODULUS = 5 SCALE = 20 pascals = generate_pascals(DEPTH, MODULUS) #for row in pascals: print(row) # the magic takes care of redundant column in case of even width img = BMPImage(width=(DEPTH*2 if DEPTH*2 % 2 != 0 else DEPTH*2-1), height=DEPTH, scale=SCALE, bg="black") # set color specturm spectrum = [0]*(MODULUS+MODULUS) step = int(255/len(spectrum)) last = 0 for i, num in enumerate(spectrum): spectrum[i] += last+step last = spectrum[i] #print(spectrum) # draw triangle to img spaces = int(DEPTH)-1 for y in range(len(pascals)): for x in range(y+1): num = pascals[y][x] img.put_pixel(2*x+spaces, y, (spectrum[num], spectrum[num], int((spectrum[num]+spectrum[num])/2))) spaces -= 1 img.save("img/pascals.bmp")
def ellipse(save_file, img_scale=1, r=250, a=1, b=0.5): """ ellipse implicit: (x/a)**2 + (y/b)**2 = r**2 parametric: x = a*cos(t) y = b*sin(t) """ img = BMPImage(width=500, height=500, scale=img_scale, origin="cartesian") for x in img.get_x_coords(): for y in img.get_y_coords(): if (x / a)**2 + (y / b)**2 <= r**2: c = int(math.sqrt((x / a)**2 + (y / b)**2)) img.put_pixel(x, y, (c, c, c)) img.save(save_file)
def feigenbaum_diagram(r1=0, r2=4, x1=0, x2=1, draw_rect=True): assert (r1 < r2 and x1 < x2) assert (0 <= r1 <= 4 and 0 <= r2 <= 4) assert (0 <= x1 <= 1 and 0 <= x2 <= 1) WIDTH = 1000 HEIGHT = 600 GENERATIONS = 500 GENERATIONS_TAKE = 100 WHITE = (255, 255, 255) RED = (255, 0, 0) img = BMPImage(width=WIDTH, height=HEIGHT, scale=1, bg="black", origin="bottom_left") if draw_rect: # draw red rectangle in upper-right quadrant img.draw_rect(WIDTH / 2, HEIGHT / 2, WIDTH - 5, HEIGHT - 5, color=RED) for growth_rate in range(WIDTH): x = 0.5 r = growth_rate / WIDTH * (r2 - r1) assert (r2 >= r1 + r >= r1) population = [] for generation in range(GENERATIONS): x = (r1 + r) * x * (1 - x) if x1 < x < x2 and generation > (GENERATIONS - GENERATIONS_TAKE): population.append(x) assert (0.0 <= x <= 1.0) attractors = list(set(population)) for x in attractors: a = int(r * WIDTH / (r2 - r1)) b = int(x * HEIGHT) nb = b - (x1 * HEIGHT) nx = (x2 - x1) * HEIGHT bb = nb / nx * HEIGHT img.put_pixel(a, bb, WHITE) img.save( "img/feigenbaum_diagram_r1_{R1}_r2_{R2}_x1_{X1}_x2_{X2}.bmp".format( R1=r1, R2=r2, X1=x1, X2=x2))
def draw_effect_ellipses(num_of_ellipses, r1, r2, a, b): img = BMPImage(scale=1, width=1000, height=1000, origin="top_left") draw_field(img) img.set_origin("cartesian") for i in range(1, num_of_ellipses + 1): draw_inverted_ellipse(img, r1, r2, a=a, b=b, tilt=i) for i in range(-num_of_ellipses, 0): draw_inverted_ellipse(img, r1, r2, a=a, b=b, tilt=i) img.save( "img/ellipses_effect_{num_of_ellipses}_{r1}_{r2}_{a}_{b}.bmp".format( num_of_ellipses=num_of_ellipses, r1=r1, r2=r2, a=a, b=b))
def draw_newton(r1=-2, r2=2, i1=-2, i2=2, tag=""): assert (r1 < r2 and i1 < i2) dif_r = abs(r1 - r2) dif_i = abs(i1 - i2) img = BMPImage(width=WIDTH, height=HEIGHT, scale=1, bg="white", origin="cartesian") for xi in range(RES_X): x = r1 + dif_r * (xi / RES_X) for yi in range(RES_Y): y = i1 + dif_i * (yi / RES_Y) root = newtons_method(complex(x, y)) nx = x * WIDTH / 4 ny = y * HEIGHT / 4 img.put_pixel(nx, ny, pick_color(root)) img.save("img/newton.bmp".format(TAG=tag))
def draw_julia(c, r1=-2, r2=2, i1=-2, i2=2, tag=""): assert (r1 < r2 and i1 < i2) dif_r = abs(r1 - r2) dif_i = abs(i1 - i2) zoom_lvl = 3 / dif_r iters = ITERS print("c.real: %f, c.imag: %f, iters: %f" % (c.real, c.imag, iters)) img = BMPImage(width=WIDTH, height=HEIGHT, scale=1, bg="white", origin="cartesian") for xi in range(RES_X): x = r1 + dif_r * (xi / RES_X) for yi in range(RES_Y): y = i1 + dif_i * (yi / RES_Y) color = in_julia(c, x, y, iters) nx = x * WIDTH / 4 ny = y * HEIGHT / 4 img.put_pixel(nx, ny, color) img.save("img/julia/{TAG}.bmp".format(TAG=tag, CR=c.real, CI=c.imag))
""" Tomas Meszaros Test drawings using bitmap graphics. """ from bmplib import BMPImage img = BMPImage(width=256, height=256) for i in range(img.width): for j in range(img.height): img.put_pixel(i, j, (i, 0, j)) img.save("img/test_bmp.bmp")
cur_i = i # right for j in range(cur_j + 1, cur_j + ((loop + 1) * 2 - 1) + 1): if cnt == len(nums): # we are finished, we dont want to start another loop continue matrix[cur_i][j] = nums[cnt] cnt += 1 cur_j = j loop += 1 #pp(matrix) ## Filter number from matrix and make images img_primes = BMPImage(width=IMG_SIDE, height=IMG_SIDE, bg="white") img_div_by_4 = BMPImage(width=IMG_SIDE, height=IMG_SIDE, bg="white") img_div_by_5 = BMPImage(width=IMG_SIDE, height=IMG_SIDE, bg="white") img_div_by_8 = BMPImage(width=IMG_SIDE, height=IMG_SIDE, bg="white") for i in range(int(img_primes.get_width())): for j in range(img_primes.get_height()): if is_prime(matrix[i][j]): img_primes.put_pixel(i, j, (0, 0, 0)) if matrix[i][j] % 4 == 0: img_div_by_4.put_pixel(i, j, (0, 0, 0)) if matrix[i][j] % 5 == 0: img_div_by_5.put_pixel(i, j, (0, 0, 0)) if matrix[i][j] % 8 == 0: img_div_by_8.put_pixel(i, j, (0, 0, 0))
def draw_effect_concentric_circles(): img = BMPImage(scale=1, width=1000, height=1000, origin="top_left") draw_field(img) img.set_origin("cartesian") draw_circles(img) img.save("img/circles_effect.bmp")
""" From wikipedia """ steps = 1 if a == 0 or b == 0: return (1, steps) while a != b: if a > b: a = a - b else: b = b - a steps += 1 return (a, steps) WIDTH = 512 HEIGHT = 512 img_divs = BMPImage(WIDTH, HEIGHT) img_euclid_steps_mod = BMPImage(WIDTH, HEIGHT) img_euclid_steps_sub = BMPImage(WIDTH, HEIGHT) img_euclid_steps_mix = BMPImage(WIDTH, HEIGHT) for i in range(img_divs.get_width()): for j in range(img_divs.get_height()): div_mod, steps_mod = gcd_mod_variant(i, j) _, steps_sub = gcd_sub_variant(i, j) # to get nicer colors steps_mod *= 20 steps_sub *= 10 steps_mix = int((steps_mod + steps_sub) / 2) div_mod = int(math.log(1 if div_mod == 0 else div_mod, 1.5) * 10)
points[-1][0], points[-1][1], color=color, width=line_width, precision=precision) def flood_fill(img, x, y, color=(255, 0, 0)): # TODO: make this iterative if x < 0 or x >= img.get_width() or y < 0 or y >= img.get_height(): return r, g, b = img.get_pixel(x, y) if r == 255 and g == 255 and b == 255: img.put_pixel(x, y, color) flood_fill(img, x + 1, y) flood_fill(img, x - 1, y) flood_fill(img, x, y + 1) flood_fill(img, x, y - 1) img = BMPImage(scale=5, width=200, height=200, origin="bottom_left") polygon_points = [(10, 10), (180, 20), (160, 150), (100, 50), (20, 180)] draw_polygon(img, polygon_points, line_width=7, precision=10) sys.setrecursionlimit(sys.getrecursionlimit() * 10) # TODO: 15 15 is works only sometimes flood_fill(img, 15, 15) img.save("img/polygon.bmp")