restarting
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,3 @@ | ||||
| #*.png | ||||
| *.mkv | ||||
| *.mp4 | ||||
							
								
								
									
										1
									
								
								README
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1 @@ | ||||
| I will organize and collect this code all into one project some time! | ||||
							
								
								
									
										
											BIN
										
									
								
								animation/asdf.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.0 MiB | 
							
								
								
									
										146
									
								
								animation/gpu_migration.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						| @ -0,0 +1,146 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.animation as animation | ||||
| import pyopencl as cl | ||||
| from alive_progress import alive_bar | ||||
| from matplotlib.backend_bases import MouseButton | ||||
| 
 | ||||
| img_res_x = 1000 | ||||
| img_res_y = 1000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = 0 | ||||
| 
 | ||||
| x_min = (-periods * np.pi) + (square_x * np.pi) | ||||
| x_max = (periods  * np.pi) + (square_x * np.pi) | ||||
| y_min = (-periods * np.pi) + (square_y * np.pi) | ||||
| y_max = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| animation_progres_save = "ani1_less.mp4" | ||||
| single_frame_save = "asdf.png" | ||||
| 
 | ||||
| opencl_context = cl.create_some_context(interactive=False) | ||||
| opencl_queue = cl.CommandQueue(opencl_context) | ||||
| 
 | ||||
| kernel_src_path = "./kernel.c" | ||||
| 
 | ||||
| frames = 200 | ||||
| rendered_frames = [] | ||||
| 
 | ||||
| image = np.empty([img_res_x, img_res_y], np.uint32) | ||||
| image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes) | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| #ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| bruh = None | ||||
| 
 | ||||
| def on_click(event): | ||||
|     global bruh | ||||
|     split_ratio = 1 | ||||
|     if (event.button is MouseButton.MIDDLE) and (event.inaxes): | ||||
|         # there's probably a way to set global coordinates; | ||||
|         # I don't expect this to go anywhere so I don't really care | ||||
|         on_x = ((event.xdata / img_res_x) * abs(x_max - x_min)) + x_min | ||||
|         on_y = ((event.ydata / img_res_y) * abs(y_max - y_min)) + y_min | ||||
| 
 | ||||
|         #I, uh, also don't know the best way to replicate the openCL code automaticly in python | ||||
|         #so ajust if nessesary | ||||
|         x_hops = [] | ||||
|         y_hops = [] | ||||
|         for i in range(iterations): | ||||
|             x_hops.append(((on_x - x_min) / abs(x_max - x_min)) * img_res_x) | ||||
|             y_hops.append(((on_y - y_min) / abs(y_max - y_min)) * img_res_y) | ||||
|             next_x = on_x/np.tan(on_y) | ||||
|             on_y = on_y/np.tan(on_x) | ||||
|             on_x = next_x | ||||
|             if on_x**2 + on_y**2 > escape: | ||||
|                 break | ||||
|         print(y_hops[0]) | ||||
|         print(on_y) | ||||
|         print("{} hops".format(len(x_hops))) | ||||
|         if bruh: | ||||
|             bruh.pop(0).remove() | ||||
|         bruh = ax.plot(x_hops, y_hops) | ||||
|         plt.draw() | ||||
| 
 | ||||
|           | ||||
| 
 | ||||
|         print(on_x, on_y) | ||||
| 
 | ||||
| 
 | ||||
| print("compiling openCL kernel...") | ||||
| with open(kernel_src_path, 'r') as kernel_src: | ||||
|   compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build() | ||||
| 
 | ||||
| encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves') | ||||
| 
 | ||||
| def display_encoder_progress(current_frame: int, total_frames: int): | ||||
|     print("Encoding: frame {}/{}".format(current_frame, frames)) | ||||
| 
 | ||||
| 
 | ||||
| mp_image = None | ||||
| 
 | ||||
| print("Rendering {} frames...".format(frames)) | ||||
| plt.show(block=False) | ||||
| if frames > 1: | ||||
|     with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total: | ||||
|         for frame_i in range(0, frames): | ||||
|             compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, | ||||
|                                          np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                          np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                          np.double(x_min), np.double(y_min),  | ||||
|                                          np.uint32(iterations), np.uint32(escape), | ||||
|                                          np.double(frame_i / frames)) | ||||
| 
 | ||||
| 
 | ||||
|             cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|             rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated="True", interpolation='none') | ||||
|             if frame_i == 0: | ||||
|               mp_image = rendered_frame | ||||
|             else: | ||||
|               pass | ||||
|             #mp_image.set_array(image) | ||||
|             rendered_frames.append([rendered_frame]) | ||||
|             bar_total() | ||||
|             #fig.canvas.draw() | ||||
|             #fig.canvas.flush_events() | ||||
|     print("Encoding/Saving...") | ||||
|     ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True) | ||||
|     ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc") | ||||
| else: | ||||
|         compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, | ||||
|                                      np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                      np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                      np.double(x_min), np.double(y_min),  | ||||
|                                      np.uint32(iterations), np.uint32(escape), | ||||
|                                      np.double(1)) | ||||
|         cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|         ax.imshow(image, norm="log", aspect="auto", cmap=cmap) | ||||
|         fig.savefig(single_frame_save) | ||||
|         plt.autoscale(False) | ||||
|         plt.connect('motion_notify_event', on_click) | ||||
|         plt.show() | ||||
| 
 | ||||
|          | ||||
							
								
								
									
										30
									
								
								animation/kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,30 @@ | ||||
| __kernel void basic_test() { | ||||
|   printf("this cores ID: (%lu, %lu)\n", get_global_id(0), get_global_id(1)); | ||||
| } | ||||
| double cosecant_single(double a, double b) { return a / tan(b); } | ||||
| double secant_single(double a, double b) { return a / sin(b); } | ||||
| 
 | ||||
| __kernel void render_frame(__global unsigned int *frame_output, | ||||
|     double x_step, double y_step, | ||||
|     double x_start, double y_start, | ||||
|     unsigned int iterations, unsigned int escape, double r) {   | ||||
|   unsigned int iter; | ||||
|    | ||||
|   double x_cart = (get_global_id(0) * x_step) + x_start; | ||||
|   double y_cart = (get_global_id(1) * y_step) + y_start; | ||||
|   size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0); | ||||
|   | ||||
|    | ||||
|   double x = sqrt(pow(x_cart, 2) + pow(y_cart, 2)); | ||||
|   double y = atan(y_cart / x_cart); | ||||
|   double next_x; | ||||
| 
 | ||||
|   for(iter = 0; iter < iterations; iter++) {  | ||||
|     next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y)); | ||||
|     y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x)); | ||||
|     x = next_x; | ||||
|     if((pow(x, 2) + pow(y, 2)) >= escape) break; | ||||
|   } | ||||
|    | ||||
|   frame_output[img_index] = iter; | ||||
| } | ||||
							
								
								
									
										79
									
								
								animation/notes
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,79 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.animation as animation | ||||
| import pyopencl as cl | ||||
| from alive_progress import alive_bar | ||||
| 
 | ||||
| img_res_x = 2000 | ||||
| img_res_y = 2000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = 0 | ||||
| 
 | ||||
| xmin = (-periods * np.pi) + (square_x * np.pi) | ||||
| xmax = (periods  * np.pi) + (square_x * np.pi) | ||||
| ymin = (-periods * np.pi) + (square_y * np.pi) | ||||
| ymax = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| animation_progres_save = "./animations" | ||||
| frames = 120 | ||||
| 
 | ||||
| rendered_frames = [] | ||||
| 
 | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| opencl_context = cl.create_some_context() | ||||
| opencl_queue = cl.CommandQueue(opencl_context) | ||||
| 
 | ||||
| 
 | ||||
| #def render(): | ||||
| #  image = np.empty([img_res_y, img_res_x]) | ||||
| #  print("Rendering frames") | ||||
| #  with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total: | ||||
| #    for frame in range(frames): | ||||
| #      split_ratio = frame / frames | ||||
| #      for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)): | ||||
| #        for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)): | ||||
| #          on_x = x | ||||
| #          on_y = y | ||||
| #          for i in range(iterations): | ||||
| #            next_x = (split_ratio * (on_x/np.sin(on_y))) + ((1 - split_ratio) * on_x/np.tan(on_y)) | ||||
| #            on_y = (split_ratio * (on_y/np.sin(on_x))) + ((1 - split_ratio) * on_y/np.tan(on_x)) | ||||
| #            on_x = next_x | ||||
| #            if on_x**2 + on_y**2 > escape: | ||||
| #              break | ||||
| #          image[pix_y][pix_x] = i | ||||
| #      rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated=False) | ||||
| #      rendered_frames.append([rendered_frame]) | ||||
| #      bar_total() | ||||
|          | ||||
| def display(): | ||||
|   print(rendered_frames) | ||||
|   ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True) | ||||
|   ani.save("test.mp4") | ||||
|   plt.show() | ||||
| 
 | ||||
| render() | ||||
| display() | ||||
							
								
								
									
										62
									
								
								backup
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,62 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| from alive_progress import alive_bar | ||||
| 
 | ||||
| img_res_x = 1000 | ||||
| img_res_y = 1000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = .25 | ||||
| square_x = 1 | ||||
| square_y = 1 | ||||
| 
 | ||||
| xmin = (-periods * np.pi) + (square_x * np.pi) | ||||
| xmax = (periods  * np.pi) + (square_x * np.pi) | ||||
| ymin = (-periods * np.pi) + (square_y * np.pi) | ||||
| ymax = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| 
 | ||||
| image = np.empty([img_res_y, img_res_x]) | ||||
| 
 | ||||
| with alive_bar(img_res_y, bar = 'filling', spinner = 'waves') as bar: | ||||
|   for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)): | ||||
|     for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)): | ||||
|       on_x = x | ||||
|       on_y = y | ||||
|       for i in range(iterations): | ||||
|         completed_ratio = (((pix_x * pix_y * 1)) / total_pixels) | ||||
|         next_x = (completed_ratio * (on_x/np.sin(on_y))) + ((1 - completed_ratio) * on_x/np.tan(on_y)) | ||||
|         on_y = (completed_ratio * (on_y/np.sin(on_x))) + ((1 - completed_ratio) * on_y/np.tan(on_x)) | ||||
|         on_x = next_x | ||||
|         if on_x**2 + on_y**2 > escape: | ||||
|           break | ||||
|       image[pix_y][pix_x] = i | ||||
|     bar() | ||||
| 
 | ||||
| 
 | ||||
|        | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| ax.imshow(image, norm="log", aspect="auto", cmap=cmap) | ||||
| fig.savefig("linear_transform_sin_tan_arnolds_tongue_hotspot.png") | ||||
| plt.show() | ||||
							
								
								
									
										
											BIN
										
									
								
								collective/.gpu_migration.py.swo
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								collective/.gpu_migration.py.swp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								collective/.kernel.c.swp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										165
									
								
								collective/gpu_migration.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						| @ -0,0 +1,165 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.animation as animation | ||||
| import matplotlib.style as mplstyle | ||||
| import pyopencl as cl | ||||
| from alive_progress import alive_bar | ||||
| from matplotlib.backend_bases import MouseButton | ||||
| from PIL import Image | ||||
| 
 | ||||
| # HELLO READER ------------------------------------------------------------------------ | ||||
| # yes, I know this script is horrid, but it's more of a scratchpad to quickly test ideas | ||||
| # and not anything I'm ever going to show anyone else. | ||||
| 
 | ||||
| img_res_x = 1000 | ||||
| img_res_y = 1000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = -2 | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = (255*3) | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| animation_progres_save = "ani1_less.mp4" | ||||
| single_frame_save = "asdf.png" | ||||
| 
 | ||||
| opencl_context = cl.create_some_context(interactive=False) | ||||
| opencl_queue = cl.CommandQueue(opencl_context) | ||||
| 
 | ||||
| kernel_src_path = "./kernel.c" | ||||
| 
 | ||||
| frames = 1 | ||||
| rendered_frames = [] | ||||
| 
 | ||||
| image = np.empty([img_res_x, img_res_y], np.double) | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| 
 | ||||
| manual_limits = [15.832664460420503,  | ||||
|                  16.161782579162786, | ||||
|                  0.21263776938088172, | ||||
|                  0.2668613889327035] | ||||
| 
 | ||||
| 
 | ||||
| #ax.invert_yaxis() | ||||
| ax.set_xlim((-periods * np.pi) + (square_x * np.pi), (periods  * np.pi) + (square_x * np.pi)) | ||||
| ax.set_ylim((-periods * np.pi) + (square_y * np.pi), (periods * np.pi) + (square_y * np.pi)) | ||||
| #ax.set_xlim(manual_limits[0], manual_limits[1]) | ||||
| #ax.set_ylim(manual_limits[2], manual_limits[3]) | ||||
| 
 | ||||
| #ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| mplstyle.use('fast') | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| print("compiling openCL kernel...") | ||||
| with open(kernel_src_path, 'r') as kernel_src: | ||||
|   compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build() | ||||
| 
 | ||||
| encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves') | ||||
| 
 | ||||
| def display_encoder_progress(current_frame: int, total_frames: int): | ||||
|     print("Encoding: frame {}/{}".format(current_frame, frames)) | ||||
| 
 | ||||
| temp_render_hook = False | ||||
| mp_image = None | ||||
| 
 | ||||
| def render(axes): | ||||
|   global temp_render_hook | ||||
|   global mp_image | ||||
|   if not temp_render_hook: | ||||
|     temp_render_hook = True | ||||
|     x_min = axes.get_xlim()[0] | ||||
|     x_max = axes.get_xlim()[1] | ||||
|     y_min = axes.get_ylim()[1] | ||||
|     y_max = axes.get_ylim()[0] | ||||
|     print(axes.get_ylim()) | ||||
|     compiled_kernel.render_frame_curvature(opencl_queue, image.shape, None, image_buffer, mask_buffer, | ||||
|                                  np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                  np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                  np.double(x_min), np.double(y_min),  | ||||
|                                  np.uint32(iterations), np.uint32(escape), | ||||
|                                  np.double(1)) | ||||
|     cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|     print("kernel") | ||||
|     if mp_image == None: | ||||
|       mp_image = ax.imshow(image, norm="linear", aspect="auto", cmap=cmap, interpolation='none', extent=(x_min, x_max, y_min, y_max)) # TODO | ||||
|     else: | ||||
|       mp_image.set(extent=(x_min, x_max, y_min, y_max)) | ||||
|       #ax.set_aspect('equal') | ||||
|       #mp_image.set_data(image) | ||||
|       mp_image.set_array(image) | ||||
|        | ||||
| 
 | ||||
|     fig.canvas.draw_idle() | ||||
|     fig.canvas.flush_events() | ||||
|     temp_render_hook = False | ||||
| 
 | ||||
| #plt.ion() | ||||
| 
 | ||||
| #open image | ||||
| mask_path = "mask.png" | ||||
| mask = np.asarray(Image.open(mask_path).convert("L").resize((img_res_x, img_res_y)), dtype=np.double) | ||||
| #mask = np.zeros((img_res_x, img_res_y), dtype=np.double) | ||||
| mask.setflags(write=1) | ||||
| mask /= np.max(mask) # normalize | ||||
| #print(mask.shape) | ||||
| #print(mask.dtype) | ||||
| #print(mask) | ||||
| #ax.imshow(mask, norm="linear") | ||||
| #plt.show() | ||||
| 
 | ||||
| image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes) | ||||
| mask_buffer = cl.Buffer(opencl_context, cl.mem_flags.READ_ONLY, mask.nbytes) | ||||
| cl.enqueue_copy(opencl_queue, mask_buffer, mask).wait() | ||||
| #mask_buffer = cl.array.Array(opencl_context,mask.shape, dtype=np.uint8, data=mask) | ||||
| 
 | ||||
| #move to render | ||||
| print("Rendering {} frames...".format(frames)) | ||||
| if frames > 1: | ||||
|     x_min = ax.get_xlim()[0] | ||||
|     x_max = ax.get_xlim()[1] | ||||
|     y_min = ax.get_ylim()[1] | ||||
|     y_max = ax.get_ylim()[0] | ||||
|     with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total: | ||||
|         for frame_i in range(0, frames): | ||||
|           compiled_kernel.render_frame_curvature(opencl_queue, image.shape, None, image_buffer, mask_buffer, | ||||
|                                                  np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                                  np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                                  np.double(x_min), np.double(y_min),  | ||||
|                                                  np.uint32(iterations), np.uint32(escape), | ||||
|                                                  np.double(frame_i/frames)) | ||||
| 
 | ||||
| 
 | ||||
|           cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|           rendered_frame = ax.imshow(image, norm="linear", aspect="auto", cmap=cmap, animated="True") | ||||
|           rendered_frames.append([rendered_frame]) | ||||
|           bar_total() | ||||
|     print("Encoding/Saving...") | ||||
|     ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True) | ||||
|     ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc") | ||||
| else: | ||||
|   ax.callbacks.connect('ylim_changed', render) | ||||
|   ax.callbacks.connect('xlim_changed', render) | ||||
|   render(ax) | ||||
|   plt.savefig("out_texture.png") | ||||
|   plt.show(block=True) | ||||
							
								
								
									
										116
									
								
								collective/kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,116 @@ | ||||
| //#include <math.h>
 | ||||
| #define PI 3.141592653589793115997963468544185161590576171875 | ||||
| 
 | ||||
| double cosecant_single(double a, double b) { return a / cos(b); } | ||||
| double secant_single(double a, double b) { return a / cos(b); } | ||||
| 
 | ||||
| /**
 | ||||
| __kernel void render_frame_orbit_trap(__global double *frame_output, __global double *mask,  | ||||
|     double x_step, double y_step, | ||||
|     double x_start, double y_start, | ||||
|     unsigned int iterations, unsigned int escape, double ratio) {   | ||||
|    | ||||
|   const vec2 point = (0, 0); | ||||
|    | ||||
|   unsigned int result; | ||||
|   unsigned int iter; | ||||
| 
 | ||||
|   double min_distance = DBL_MAX;  | ||||
|    | ||||
|   for(iter = 0; iter < iterations; iter++) {  | ||||
|     double next_x; | ||||
|     double r = mask[img_index]; | ||||
|     next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y)); | ||||
|     y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x)); | ||||
|     x = next_x; | ||||
|     if((pow(x, 2) + pow(y, 2)) >= escape) break; | ||||
|   } | ||||
|    | ||||
|   frame_output[img_index] = total_curve / iter; | ||||
| 
 | ||||
| } | ||||
| **/ | ||||
|   | ||||
| 
 | ||||
| __kernel void render_frame_curvature(__global double *frame_output, __global double *mask,  | ||||
|     double x_step, double y_step, | ||||
|     double x_start, double y_start, | ||||
|     unsigned int iterations, unsigned int escape, double ratio) {   | ||||
|   unsigned int result; | ||||
|   unsigned int iter; | ||||
|    | ||||
|   double x_cart = (get_global_id(0) * x_step) + x_start; | ||||
|   double y_cart = (get_global_id(1) * y_step) + y_start; | ||||
|   double x = sqrt(pow(x_cart, 2) + pow(y_cart, 2)); | ||||
|   double y = atan(y_cart / x_cart); | ||||
|   | ||||
|   //double x = (get_global_id(0) * x_step) + x_start;
 | ||||
|   //double y = (get_global_id(1) * y_step) + y_start;
 | ||||
|   size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0); | ||||
| 
 | ||||
|   double total_curve = 0; | ||||
|    | ||||
|   //just found out vectors are a thing
 | ||||
|   double2 lp[3]; | ||||
|    | ||||
|   for(iter = 0; iter < iterations; iter++) {  | ||||
|     double next_x; | ||||
|     double r = mask[img_index]; | ||||
|     next_x = (r * secant_single(x, y)) + ((1 - r) * cosecant_single(x, y)); | ||||
|     y = (r * secant_single(y, x)) + ((1 - r) * cosecant_single(y, x)); | ||||
|     x = next_x; | ||||
| 
 | ||||
|     if((pow(x, 2) + pow(y, 2)) >= escape) break; | ||||
|     lp[2] = lp[1]; | ||||
|     lp[1] = lp[0]; | ||||
|     lp[0] = (double2)(x, y); //why do I have to cast this? hope no accuracy lost
 | ||||
|        | ||||
|     /**
 | ||||
|     if(img_index == 254234) { | ||||
|       printf("%u\n", ratio); | ||||
|     } | ||||
|     **/ | ||||
|     if(iter >= 2) { | ||||
|       double curl = acos(dot((lp[0] - lp[1]), (lp[2] - lp[1])) / (distance(lp[0], lp[1]) * distance(lp[2], lp[1]))); | ||||
|       total_curve = (total_curve + curl); | ||||
|     } | ||||
|   } | ||||
|   frame_output[img_index] = total_curve / iter; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| __kernel void render_frame(__global double *frame_output, __global double *mask,  | ||||
|     double x_step, double y_step, | ||||
|     double x_start, double y_start, | ||||
|     unsigned int iterations, unsigned int escape, double ratio) {   | ||||
|   unsigned int result; | ||||
|   double x_cart = (get_global_id(0) * x_step) + x_start; | ||||
|   double y_cart = (get_global_id(1) * y_step) + y_start; | ||||
|   size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0); | ||||
| 
 | ||||
|   double x = sqrt(pow(x_cart, 2) + pow(y_cart, 2)); | ||||
|   double y = atan(y_cart / x_cart); | ||||
|    | ||||
|   //double x = (get_global_id(0) * x_step) + x_start;
 | ||||
|   //double y = (get_global_id(1) * y_step) + y_start;
 | ||||
|    | ||||
| 
 | ||||
|   unsigned int iter; | ||||
| 
 | ||||
|   //vec2 pos; 
 | ||||
|    | ||||
|   for(iter = 0; iter < iterations; iter++) {  | ||||
|     double next_x; | ||||
|     double r = ratio; | ||||
|     next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y)); | ||||
|     y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x)); | ||||
|     x = next_x; | ||||
|     //if(distance(pos) >= escape) break;
 | ||||
|     if((pow(x, 2) + pow(y, 2)) >= escape) break; | ||||
|   } | ||||
|    | ||||
| 
 | ||||
|   //TODO turn back to int whenever 
 | ||||
|   frame_output[img_index] = (double)iter; | ||||
|   //frame_output[img_index] = mask[img_index] * 255;
 | ||||
| } | ||||
							
								
								
									
										1
									
								
								collective/mask.png
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						| @ -0,0 +1 @@ | ||||
| ../masks/clouds.png | ||||
							
								
								
									
										79
									
								
								collective/notes
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,79 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.animation as animation | ||||
| import pyopencl as cl | ||||
| from alive_progress import alive_bar | ||||
| 
 | ||||
| img_res_x = 2000 | ||||
| img_res_y = 2000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = 0 | ||||
| 
 | ||||
| xmin = (-periods * np.pi) + (square_x * np.pi) | ||||
| xmax = (periods  * np.pi) + (square_x * np.pi) | ||||
| ymin = (-periods * np.pi) + (square_y * np.pi) | ||||
| ymax = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| animation_progres_save = "./animations" | ||||
| frames = 120 | ||||
| 
 | ||||
| rendered_frames = [] | ||||
| 
 | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| opencl_context = cl.create_some_context() | ||||
| opencl_queue = cl.CommandQueue(opencl_context) | ||||
| 
 | ||||
| 
 | ||||
| #def render(): | ||||
| #  image = np.empty([img_res_y, img_res_x]) | ||||
| #  print("Rendering frames") | ||||
| #  with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total: | ||||
| #    for frame in range(frames): | ||||
| #      split_ratio = frame / frames | ||||
| #      for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)): | ||||
| #        for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)): | ||||
| #          on_x = x | ||||
| #          on_y = y | ||||
| #          for i in range(iterations): | ||||
| #            next_x = (split_ratio * (on_x/np.sin(on_y))) + ((1 - split_ratio) * on_x/np.tan(on_y)) | ||||
| #            on_y = (split_ratio * (on_y/np.sin(on_x))) + ((1 - split_ratio) * on_y/np.tan(on_x)) | ||||
| #            on_x = next_x | ||||
| #            if on_x**2 + on_y**2 > escape: | ||||
| #              break | ||||
| #          image[pix_y][pix_x] = i | ||||
| #      rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated=False) | ||||
| #      rendered_frames.append([rendered_frame]) | ||||
| #      bar_total() | ||||
|          | ||||
| def display(): | ||||
|   print(rendered_frames) | ||||
|   ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True) | ||||
|   ani.save("test.mp4") | ||||
|   plt.show() | ||||
| 
 | ||||
| render() | ||||
| display() | ||||
							
								
								
									
										
											BIN
										
									
								
								collective/out.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.8 MiB | 
							
								
								
									
										
											BIN
										
									
								
								collective/out_grad.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.2 MiB | 
							
								
								
									
										
											BIN
										
									
								
								collective/out_texture.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.8 MiB | 
							
								
								
									
										21
									
								
								collective/texput.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,21 @@ | ||||
| This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024/Arch Linux) (preloaded format=pdflatex 2024.4.22)  28 APR 2024 21:33 | ||||
| entering extended mode | ||||
|  restricted \write18 enabled. | ||||
|  %&-line parsing enabled. | ||||
| ** | ||||
| 
 | ||||
| ! Emergency stop. | ||||
| <*>  | ||||
|      | ||||
| End of file on the terminal! | ||||
| 
 | ||||
|   | ||||
| Here is how much of TeX's memory you used: | ||||
|  3 strings out of 476076 | ||||
|  113 string characters out of 5793775 | ||||
|  1925187 words of memory out of 5000000 | ||||
|  22212 multiletter control sequences out of 15000+600000 | ||||
|  558069 words of font info for 36 fonts, out of 8000000 for 9000 | ||||
|  14 hyphenation exceptions out of 8191 | ||||
|  0i,0n,0p,13b,6s stack positions out of 10000i,1000n,20000p,200000b,200000s | ||||
| !  ==> Fatal error occurred, no output PDF file produced! | ||||
							
								
								
									
										6
									
								
								cool_places
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,6 @@ | ||||
| windows into space | ||||
|   15.832664460420503 | ||||
|   16.161782579162786 | ||||
| 
 | ||||
|   0.21263776938088172 | ||||
|   0.2668613889327035 | ||||
							
								
								
									
										62
									
								
								field_tests/backup
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,62 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| from alive_progress import alive_bar | ||||
| 
 | ||||
| img_res_x = 1000 | ||||
| img_res_y = 1000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = .25 | ||||
| square_x = 1 | ||||
| square_y = 1 | ||||
| 
 | ||||
| xmin = (-periods * np.pi) + (square_x * np.pi) | ||||
| xmax = (periods  * np.pi) + (square_x * np.pi) | ||||
| ymin = (-periods * np.pi) + (square_y * np.pi) | ||||
| ymax = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| 
 | ||||
| image = np.empty([img_res_y, img_res_x]) | ||||
| 
 | ||||
| with alive_bar(img_res_y, bar = 'filling', spinner = 'waves') as bar: | ||||
|   for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)): | ||||
|     for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)): | ||||
|       on_x = x | ||||
|       on_y = y | ||||
|       for i in range(iterations): | ||||
|         completed_ratio = (((pix_x * pix_y * 1)) / total_pixels) | ||||
|         next_x = (completed_ratio * (on_x/np.sin(on_y))) + ((1 - completed_ratio) * on_x/np.tan(on_y)) | ||||
|         on_y = (completed_ratio * (on_y/np.sin(on_x))) + ((1 - completed_ratio) * on_y/np.tan(on_x)) | ||||
|         on_x = next_x | ||||
|         if on_x**2 + on_y**2 > escape: | ||||
|           break | ||||
|       image[pix_y][pix_x] = i | ||||
|     bar() | ||||
| 
 | ||||
| 
 | ||||
|        | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| ax.imshow(image, norm="log", aspect="auto", cmap=cmap) | ||||
| fig.savefig("linear_transform_sin_tan_arnolds_tongue_hotspot.png") | ||||
| plt.show() | ||||
							
								
								
									
										168
									
								
								field_tests/basic_field_test.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,168 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| from alive_progress import alive_bar | ||||
| 
 | ||||
| img_res_x = 100 | ||||
| img_res_y = 100 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = 0 | ||||
| 
 | ||||
| #xmin = (-periods * np.pi) + (square_x * np.pi) | ||||
| #xmax = (periods  * np.pi) + (square_x * np.pi) | ||||
| #ymin = (-periods * np.pi) + (square_y * np.pi) | ||||
| #ymax = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| xmin = -10 | ||||
| xmax = 10 | ||||
| ymin = -10 | ||||
| ymax = 10 | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| 
 | ||||
| image = np.empty([img_res_y, img_res_x]) | ||||
| grid = np.meshgrid(np.linspace(ymin, ymax, img_res_y), np.linspace(xmin, xmax, img_res_x)) | ||||
| print(grid[0].dtype) | ||||
| 
 | ||||
| 
 | ||||
| class point_charge(): | ||||
|   def __init__(self, x, y, c, mod): | ||||
|     self.x = x | ||||
|     self.y = y | ||||
|     self.c = c | ||||
|     self.mod = mod | ||||
|   def get_field(self, to_x, to_y): | ||||
|     if(self.mod): | ||||
|       to_x = (to_x % self.mod) | ||||
|       to_y = (to_y % self.mod) | ||||
|     return ( | ||||
|         ((self.c * (self.x - to_x)) / ((self.x - to_x)**2 + (self.y - to_y)**2)**1.5), | ||||
|         ((self.c * (self.y - to_y)) / ((self.x - to_x)**2 + (self.y - to_y)**2)**1.5)) | ||||
| 
 | ||||
| #will remove all the point charge code if it turns out to be good enough to be impliemnted into openCL | ||||
| #point_charges = [point_charge(-5, -5, 100), point_charge(-5, 5, -100), point_charge(5, 0, 100)] | ||||
| point_charges = [point_charge(5,5, 100, 10), point_charge(0,0,-100, 0)] | ||||
| 
 | ||||
| 
 | ||||
| plt.ion() | ||||
| ax = plt.gca() | ||||
| fig = plt.gcf() | ||||
| ax.set_autoscale_on(False) | ||||
| ax.set_xlim([xmin, xmax]) | ||||
| ax.set_ylim([ymin, ymax]) | ||||
| 
 | ||||
| vector_arrows = None | ||||
| 
 | ||||
| def show_field(): | ||||
|   global vector_arrows | ||||
|   grid_f = np.zeros_like(grid) | ||||
|   for p in point_charges: | ||||
|     grid_f += p.get_field(grid[0], grid[1]) | ||||
|   #plt.streamplot(grid[0], grid[1], grid_f[0], grid_f[1], density=5) | ||||
|   vector_arrows = plt.quiver(grid[0], grid[1], grid_f[0], grid_f[1]) | ||||
|   plt.show(block=False) | ||||
|   plt.pause(.1) | ||||
| 
 | ||||
| 
 | ||||
| show_field() | ||||
| 
 | ||||
| timestep = .1 | ||||
| def test_sim(): | ||||
|   particle_grid = np.meshgrid(np.linspace(ymin, ymax, 100), np.linspace(xmin, xmax, 100)) | ||||
|   pos = particle_grid | ||||
|   acceleration = np.zeros_like(particle_grid) | ||||
|   velocity = np.zeros_like(particle_grid) | ||||
|   velocity = [np.ones_like(particle_grid[0]) * 1, np.ones_like(particle_grid[0]) * .5] | ||||
|   mass = 10 | ||||
|   charge = 1 | ||||
|   particle_plot = ax.plot(velocity[0], velocity[1], 'bo', animated=True) | ||||
|   #velocity += .1 | ||||
| 
 | ||||
|   background = fig.canvas.copy_from_bbox(ax.bbox) | ||||
|   ax.draw_artist(vector_arrows) | ||||
|   fig.canvas.blit(fig.bbox) | ||||
|    | ||||
|   while True: | ||||
|     fig.canvas.restore_region(background) | ||||
|     field = np.zeros_like(particle_grid) | ||||
|     # TODO can make this quicker by skipping initilization | ||||
|     for p in point_charges: | ||||
|       field += p.get_field(pos[0], pos[1]) | ||||
|     acceleration = ((charge * field) / mass) * timestep | ||||
|     #print(acceleration) | ||||
|     velocity += acceleration * timestep | ||||
|     pos += velocity * timestep | ||||
| 
 | ||||
|     fig.canvas.restore_region(background) | ||||
|     particle_plot[0].set_data(pos[0],pos[1]) | ||||
|     ax.draw_artist(particle_plot[0]) | ||||
|     fig.canvas.blit(fig.bbox) | ||||
|     fig.canvas.flush_events() | ||||
|     plt.pause(1/60) | ||||
| 
 | ||||
|     #fig.canvas.draw_idle() | ||||
| test_sim() | ||||
| 
 | ||||
| exit(1) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|      | ||||
| 
 | ||||
| #with alive_bar(iterations, bar = 'filling', spinner = 'waves') as bar: | ||||
| #  for i in range(iterations): | ||||
| #    next_x = xx / np.sin(yy) | ||||
| #    yy = yy / np.sin(xx) | ||||
| #    xx = next_x | ||||
| #    bar() | ||||
| #image = np.vstack([xx.ravel(), yy.ravel()]) | ||||
|    | ||||
| 
 | ||||
| #meshgrid makes things slower as we can't test individual points for breaking to infinity | ||||
| fractal_test = False | ||||
| if fractal_test: | ||||
|   with alive_bar(img_res_y, bar = 'filling', spinner = 'waves') as bar: | ||||
|     for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)): | ||||
|       for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)): | ||||
|         on_x = x | ||||
|         on_y = y | ||||
|         for i in range(iterations): | ||||
|           completed_ratio = (((pix_x * pix_y * 1)) / total_pixels) | ||||
|           next_x = (completed_ratio * (on_x/np.sin(on_y))) + ((1 - completed_ratio) * on_x/np.tan(on_y)) | ||||
|           on_y = (completed_ratio * (on_y/np.sin(on_x))) + ((1 - completed_ratio) * on_y/np.tan(on_x)) | ||||
|           on_x = next_x | ||||
|           if on_x**2 + on_y**2 > escape: | ||||
|             break | ||||
|         image[pix_y][pix_x] = i | ||||
|       bar() | ||||
| else: | ||||
|   exit() | ||||
| 
 | ||||
| 
 | ||||
| exit(1)       | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| ax.imshow(image, norm="log", aspect="auto", cmap=cmap) | ||||
| fig.savefig("linear_transform_sin_tan_arnolds_tongue_hotspot.png") | ||||
| plt.show() | ||||
							
								
								
									
										191
									
								
								field_tests/field.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						| @ -0,0 +1,191 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| from alive_progress import alive_bar | ||||
| 
 | ||||
| img_res_x = 250 | ||||
| img_res_y = 250 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = 0 | ||||
| 
 | ||||
| xmin = (-periods * np.pi) + (square_x * np.pi) | ||||
| xmax = (periods  * np.pi) + (square_x * np.pi) | ||||
| ymin = (-periods * np.pi) + (square_y * np.pi) | ||||
| ymax = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| #xmin = -10 | ||||
| #xmax = 10 | ||||
| #ymin = -10 | ||||
| #ymax = 10 | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| 
 | ||||
| grid = np.meshgrid(np.linspace(ymin, ymax, 200), np.linspace(xmin, xmax, 200)) | ||||
| #image = np.meshgrid(np.linspace(ymin, ymax, img_res_y), np.linspace(xmin, xmax, img_res_x)) | ||||
| image = np.zeros([img_res_y, img_res_x], dtype=np.double) | ||||
| 
 | ||||
| 
 | ||||
| class point_charge(): | ||||
|   def __init__(self, x, y, c, mod): | ||||
|     self.x = x | ||||
|     self.y = y | ||||
|     self.c = c | ||||
|     self.mod = mod | ||||
|   def get_field(self, to_x, to_y): | ||||
|     if(self.mod): | ||||
|       to_x = (to_x % self.mod) | ||||
|       to_y = (to_y % self.mod) | ||||
|     return np.array([ | ||||
|         ((self.c * (self.x - to_x)) / ((self.x - to_x)**2 + (self.y - to_y)**2)**1.5), | ||||
|         ((self.c * (self.y - to_y)) / ((self.x - to_x)**2 + (self.y - to_y)**2)**1.5)]) | ||||
| 
 | ||||
| #will remove all the point charge code if it turns out to be good enough to be impliemnted into openCL | ||||
| #point_charges = [point_charge(-5, -5, 100), point_charge(-5, 5, -100), point_charge(5, 0, 100)] | ||||
| #point_charges = [point_charge(-1,-1, 100, 10), point_charge(1,1,-100, 0)] | ||||
| point_charges = [] | ||||
| 
 | ||||
| 
 | ||||
| #plt.ion() | ||||
| ax = plt.gca() | ||||
| fig = plt.gcf() | ||||
| #ax.set_autoscale_on(False) | ||||
| #ax.set_xlim([xmin, xmax]) | ||||
| #ax.set_ylim([ymin, ymax]) | ||||
| 
 | ||||
| vector_arrows = None | ||||
| 
 | ||||
| def show_field(): | ||||
|   global vector_arrows | ||||
|   grid_f = np.zeros_like(grid) | ||||
|   for p in point_charges: | ||||
|     grid_f += p.get_field(grid[0], grid[1]) | ||||
|   #plt.streamplot(grid[0], grid[1], grid_f[0], grid_f[1], density=5) | ||||
|   vector_arrows = plt.quiver(grid[0], grid[1], grid_f[0], grid_f[1]) | ||||
|   plt.show(block=False) | ||||
|   plt.pause(.1) | ||||
| 
 | ||||
| 
 | ||||
| #show_field() | ||||
| 
 | ||||
| timestep = .1 | ||||
| def test_sim(): | ||||
|   particle_grid = np.meshgrid(np.linspace(ymin, ymax, 100), np.linspace(xmin, xmax, 100)) | ||||
|   pos = particle_grid | ||||
|   acceleration = np.zeros_like(particle_grid) | ||||
|   velocity = np.zeros_like(particle_grid) | ||||
|   velocity = [np.ones_like(particle_grid[0]) * 1, np.ones_like(particle_grid[0]) * .5] | ||||
|   mass = 10 | ||||
|   charge = 1 | ||||
|   particle_plot = ax.plot(velocity[0], velocity[1], 'bo', animated=True) | ||||
|   #velocity += .1 | ||||
| 
 | ||||
|   background = fig.canvas.copy_from_bbox(ax.bbox) | ||||
|   ax.draw_artist(vector_arrows) | ||||
|   fig.canvas.blit(fig.bbox) | ||||
|    | ||||
|   while True: | ||||
|     fig.canvas.restore_region(background) | ||||
|     field = np.zeros_like(particle_grid) | ||||
|     # TODO can make this quicker by skipping initilization | ||||
|     for p in point_charges: | ||||
|       field += p.get_field(pos[0], pos[1]) | ||||
|     acceleration = ((charge * field) / mass) * timestep | ||||
|     #print(acceleration) | ||||
|     velocity += acceleration * timestep | ||||
|     pos += velocity * timestep | ||||
| 
 | ||||
|     fig.canvas.restore_region(background) | ||||
|     particle_plot[0].set_data(pos[0],pos[1]) | ||||
|     ax.draw_artist(particle_plot[0]) | ||||
|     fig.canvas.blit(fig.bbox) | ||||
|     fig.canvas.flush_events() | ||||
|     plt.pause(1/60) | ||||
| 
 | ||||
|     #fig.canvas.draw_idle() | ||||
| #test_sim() | ||||
| 
 | ||||
| #exit(1) | ||||
| 
 | ||||
| 
 | ||||
| max_timesteps = 10 | ||||
| 
 | ||||
| def get_fractal_iter(img): | ||||
|   next_x = img[1][y][x] / np.sin(img[0][y][x]) | ||||
|   img[0][y][x] = img[0][y][x] / np.sin(img[1][y][x]) | ||||
|   img[1][y][x] = next_x | ||||
|   if (np.square(img[0][y][x]) + np.square(img[1][y][x])) >= escape: | ||||
|     z[y][x] = i | ||||
|      | ||||
| 
 | ||||
| #meshgrid makes things slower as we can't test individual points for breaking to infinity; | ||||
| #however, I will fix that later. | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| with alive_bar(img_res_y, bar = 'filling', spinner = 'waves') as bar: | ||||
|   for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)): | ||||
|     for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)): | ||||
|       on_x = x | ||||
|       on_y = y | ||||
|       for i in range(iterations): | ||||
|         completed_ratio = (((pix_x * pix_y * 1)) / total_pixels) | ||||
|         next_x = on_x/np.sin(on_y) | ||||
|         on_y = on_y/np.sin(on_x) | ||||
|         on_x = next_x | ||||
| 
 | ||||
| 
 | ||||
|         # do physics here - we could just use vectors but i keep rewriting things | ||||
|         timesteps = max_ | ||||
|         acceleration = np.array([0, 0], dtype=np.double) | ||||
|         velocity = np.array([on_x, on_y], dtype=np.double) # maybe multiply by stuff | ||||
|         pos = np.array([0,0], dtype=np.double) | ||||
|         for t in range(timesteps): | ||||
|           for p in point_charges: | ||||
|             acceleration += p.get_field(on_x, on_y) | ||||
|           velocity += acceleration | ||||
|           pos += velocity * (timesteps) | ||||
|           on_x += pos[0] | ||||
|           on_y += pos[1] | ||||
|          | ||||
|         if on_x**2 + on_y**2 > escape: | ||||
|           image[pix_x][pix_y] = i | ||||
|           break | ||||
|     bar() | ||||
| 
 | ||||
| ax.imshow(image, norm="log", aspect="auto", cmap=cmap) | ||||
| plt.show() | ||||
|          | ||||
| 
 | ||||
| # yeah, I shouldn't have switched to a meshgrid, oh well | ||||
| #z = np.empty_like(image[0]) | ||||
| exit(0) | ||||
| with alive_bar(img_res_x, bar = 'filling', spinner = 'waves') as bar: | ||||
|   for y in range(img_res_y): | ||||
|     for x in range(img_res_x): | ||||
|       for i in range(iterations): | ||||
|         if image[0][y][x] == np.NAN: | ||||
|           continue | ||||
|         next_x = image[1][y][x] / np.sin(image[0][y][x]) | ||||
|         image[0][y][x] = image[0][y][x] / np.sin(image[1][y][x]) | ||||
|         image[1][y][x] = next_x | ||||
|         if (np.square(image[0][y][x]) + np.square(image[1][y][x])) >= escape: | ||||
|           z[y][x] = i | ||||
|           image[0][y][x] = np.NAN | ||||
|           image[1][y][x] = np.NAN | ||||
|           break | ||||
| #        #do physics here | ||||
|          | ||||
|          | ||||
| 
 | ||||
|     bar() | ||||
| #image = np.clip(image, -escape, escape) | ||||
| 
 | ||||
							
								
								
									
										137
									
								
								field_tests/gpu_migration.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						| @ -0,0 +1,137 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.animation as animation | ||||
| import pyopencl as cl | ||||
| from alive_progress import alive_bar | ||||
| from matplotlib.backend_bases import MouseButton | ||||
| 
 | ||||
| img_res_x = 1000 | ||||
| img_res_y = 1000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = 0 | ||||
| 
 | ||||
| x_min = (-periods * np.pi) + (square_x * np.pi) | ||||
| x_max = (periods  * np.pi) + (square_x * np.pi) | ||||
| y_min = (-periods * np.pi) + (square_y * np.pi) | ||||
| y_max = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| animation_progres_save = "ani1_less.mp4" | ||||
| single_frame_save = "asdf.png" | ||||
| 
 | ||||
| opencl_context = cl.create_some_context(interactive=False) | ||||
| opencl_queue = cl.CommandQueue(opencl_context) | ||||
| 
 | ||||
| kernel_src_path = "./kernel.c" | ||||
| 
 | ||||
| frames = 1 | ||||
| rendered_frames = [] | ||||
| 
 | ||||
| image = np.empty([img_res_x, img_res_y], np.uint32) | ||||
| image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes) | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| #ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| bruh = None | ||||
| 
 | ||||
| def on_click(event): | ||||
|     global bruh | ||||
|     split_ratio = 1 | ||||
|     if (event.button is MouseButton.MIDDLE) and (event.inaxes): | ||||
|         # there's probably a way to set global coordinates; | ||||
|         # I don't expect this to go anywhere so I don't really care | ||||
|         on_x = ((event.xdata / img_res_x) * abs(x_max - x_min)) + x_min | ||||
|         on_y = ((event.ydata / img_res_y) * abs(y_max - y_min)) + y_min | ||||
| 
 | ||||
|         #I, uh, also don't know the best way to replicate the openCL code automaticly in python | ||||
|         #so ajust if nessesary | ||||
|         x_hops = [] | ||||
|         y_hops = [] | ||||
|         for i in range(iterations): | ||||
|             x_hops.append(((on_x - x_min) / abs(x_max - x_min)) * img_res_x) | ||||
|             y_hops.append(((on_y - y_min) / abs(y_max - y_min)) * img_res_y) | ||||
|             next_x = on_x/np.tan(on_y) | ||||
|             on_y = on_y/np.tan(on_x) | ||||
|             on_x = next_x | ||||
|             if on_x**2 + on_y**2 > escape: | ||||
|                 break | ||||
|         print(y_hops[0]) | ||||
|         print(on_y) | ||||
|         print("{} hops".format(len(x_hops))) | ||||
|         if bruh: | ||||
|             bruh.pop(0).remove() | ||||
|         bruh = ax.plot(x_hops, y_hops) | ||||
|         plt.draw() | ||||
| 
 | ||||
|           | ||||
| 
 | ||||
|         print(on_x, on_y) | ||||
| 
 | ||||
| 
 | ||||
| print("compiling openCL kernel...") | ||||
| with open(kernel_src_path, 'r') as kernel_src: | ||||
|   compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build() | ||||
| 
 | ||||
| encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves') | ||||
| 
 | ||||
| def display_encoder_progress(current_frame: int, total_frames: int): | ||||
|     print("Encoding: frame {}/{}".format(current_frame, frames)) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| print("Rendering {} frames...".format(frames)) | ||||
| if frames > 1: | ||||
|     with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total: | ||||
|         for frame_i in range(0, frames): | ||||
|             compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, | ||||
|                                          np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                          np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                          np.double(x_min), np.double(y_min),  | ||||
|                                          np.uint32(iterations), np.uint32(escape), | ||||
|                                          np.double(frame_i / frames)) | ||||
| 
 | ||||
| 
 | ||||
|             cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|             rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated="True") | ||||
|             rendered_frames.append([rendered_frame]) | ||||
|             bar_total() | ||||
|     print("Encoding/Saving...") | ||||
|     ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True) | ||||
|     ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc") | ||||
| else: | ||||
|         compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, | ||||
|                                      np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                      np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                      np.double(x_min), np.double(y_min),  | ||||
|                                      np.uint32(iterations), np.uint32(escape), | ||||
|                                      np.double(1)) | ||||
|         cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|         ax.imshow(image, norm="log", aspect="auto", cmap=cmap) | ||||
|         fig.savefig(single_frame_save) | ||||
|         plt.autoscale(False) | ||||
|         plt.connect('motion_notify_event', on_click) | ||||
|         plt.show() | ||||
| 
 | ||||
|          | ||||
							
								
								
									
										26
									
								
								field_tests/kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,26 @@ | ||||
| __kernel void basic_test() { | ||||
|   printf("this cores ID: (%lu, %lu)\n", get_global_id(0), get_global_id(1)); | ||||
| } | ||||
| 
 | ||||
| __kernel void render_frame(__global unsigned int *frame_output, | ||||
|     double x_step, double y_step, | ||||
|     double x_start, double y_start, | ||||
|     unsigned int iterations, unsigned int escape, double ratio) {   | ||||
|   unsigned int result; | ||||
|   double on_x = (get_global_id(0) * x_step) + x_start; | ||||
|   double on_y = (get_global_id(1) * y_step) + y_start; | ||||
|   double next_x; | ||||
|   unsigned int iter; | ||||
| 
 | ||||
|   orig_x = on_x; | ||||
|   orig_y = on_y; | ||||
|   for(iter = 0; iter < iterations; iter++) {  | ||||
|     if(orig_x == 123 && orig_y == 5) printf("%d, %d\n", orig_x,orig_y); | ||||
|     next_x = on_x / sin(on_y); | ||||
|     on_y = on_y / sin(on_x); | ||||
|     on_x = next_x; | ||||
|     if((pow(on_x, 2) + pow(on_y, 2)) >= escape) break; | ||||
|   } | ||||
|    | ||||
|   frame_output[(get_global_id(1) * get_global_size(1)) + get_global_id(0)] = iter; | ||||
| } | ||||
							
								
								
									
										4
									
								
								field_tests/makefile
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,4 @@ | ||||
| make: | ||||
| 	gcc -Wall -fpic -c field.c | ||||
| 	gcc -Wall -shared -o field.so field.o | ||||
| 	python3 field.py | ||||
							
								
								
									
										63
									
								
								linear_transform_test.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						| @ -0,0 +1,63 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| from alive_progress import alive_bar | ||||
| 
 | ||||
| img_res_x = 500 | ||||
| img_res_y = 500 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = .25 | ||||
| square_x = 1 | ||||
| square_y = 1 | ||||
| 
 | ||||
| xmin = (-periods * np.pi) + (square_x * np.pi) | ||||
| xmax = (periods  * np.pi) + (square_x * np.pi) | ||||
| ymin = (-periods * np.pi) + (square_y * np.pi) | ||||
| ymax = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| 
 | ||||
| image = np.empty([img_res_y, img_res_x]) | ||||
| 
 | ||||
| with alive_bar(img_res_y, bar = 'filling', spinner = 'waves') as bar: | ||||
|   for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)): | ||||
|     for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)): | ||||
|       on_x = x | ||||
|       on_y = y | ||||
|       for i in range(iterations): | ||||
|         completed_ratio = ((pix_y * img_res_y) + pix_x) / total_pixels | ||||
|         next_x = (completed_ratio * (on_x/np.sin(on_y))) + ((1 - completed_ratio) * on_x/np.tan(on_y)) | ||||
|         on_y = (completed_ratio * (on_y/np.sin(on_x))) + ((1 - completed_ratio) * on_y/np.tan(on_x)) | ||||
|         on_x = next_x | ||||
|         if on_x**2 + on_y**2 > escape: | ||||
|           break | ||||
|       print(completed_ratio) | ||||
|       image[pix_y][pix_x] = i | ||||
|     bar() | ||||
| 
 | ||||
| 
 | ||||
|        | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| ax.imshow(image, norm="log", aspect="auto", cmap=cmap) | ||||
| fig.savefig("linear_transform_sin_tan_arnolds_tongue_hotspot.png") | ||||
| plt.show() | ||||
							
								
								
									
										
											BIN
										
									
								
								live_play/.gpu_migration.py.swo
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								live_play/.gpu_migration.py.swp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								live_play/.kernel.c.swp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										154
									
								
								live_play/gpu_migration.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						| @ -0,0 +1,154 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.animation as animation | ||||
| import matplotlib.style as mplstyle | ||||
| import pyopencl as cl | ||||
| from alive_progress import alive_bar | ||||
| from matplotlib.backend_bases import MouseButton | ||||
| from PIL import Image | ||||
| 
 | ||||
| # HELLO READER ------------------------------------------------------------------------ | ||||
| # yes, I know this script is horrid, but it's more of a scratchpad to quickly test ideas | ||||
| # and not anything I'm ever going to show anyone else. | ||||
| 
 | ||||
| img_res_x = 1000 | ||||
| img_res_y = 1000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = -2 | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = (255*3)*2 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| animation_progres_save = "ani1_less.mp4" | ||||
| single_frame_save = "asdf.png" | ||||
| 
 | ||||
| opencl_context = cl.create_some_context(interactive=False) | ||||
| opencl_queue = cl.CommandQueue(opencl_context) | ||||
| 
 | ||||
| kernel_src_path = "./kernel.c" | ||||
| 
 | ||||
| frames = 1 | ||||
| rendered_frames = [] | ||||
| 
 | ||||
| image = np.empty([img_res_x, img_res_y], np.uint32) | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| 
 | ||||
| #ax.invert_yaxis() | ||||
| ax.set_xlim((-periods * np.pi) + (square_x * np.pi), (periods  * np.pi) + (square_x * np.pi)) | ||||
| ax.set_ylim((-periods * np.pi) + (square_y * np.pi), (periods * np.pi) + (square_y * np.pi)) | ||||
| 
 | ||||
| #ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| mplstyle.use('fast') | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| print("compiling openCL kernel...") | ||||
| with open(kernel_src_path, 'r') as kernel_src: | ||||
|   compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build() | ||||
| 
 | ||||
| encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves') | ||||
| 
 | ||||
| def display_encoder_progress(current_frame: int, total_frames: int): | ||||
|     print("Encoding: frame {}/{}".format(current_frame, frames)) | ||||
| 
 | ||||
| temp_render_hook = False | ||||
| mp_image = None | ||||
| 
 | ||||
| def render(axes): | ||||
|   global temp_render_hook | ||||
|   global mp_image | ||||
|   if not temp_render_hook: | ||||
|     temp_render_hook = True | ||||
|     x_min = axes.get_xlim()[0] | ||||
|     x_max = axes.get_xlim()[1] | ||||
|     y_min = axes.get_ylim()[1] | ||||
|     y_max = axes.get_ylim()[0] | ||||
|     print(axes.get_ylim()) | ||||
|     compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, mask_buffer, | ||||
|                                  np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                  np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                  np.double(x_min), np.double(y_min),  | ||||
|                                  np.uint32(iterations), np.uint32(escape), | ||||
|                                  np.double(1)) | ||||
|     cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|     print("kernel") | ||||
|     if mp_image == None: | ||||
|       mp_image = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, interpolation='none', extent=(x_min, x_max, y_min, y_max)) # TODO | ||||
|     else: | ||||
|       mp_image.set(extent=(x_min, x_max, y_min, y_max)) | ||||
|       #ax.set_aspect('equal') | ||||
|       #mp_image.set_data(image) | ||||
|       mp_image.set_array(image) | ||||
|        | ||||
| 
 | ||||
|     fig.canvas.draw_idle() | ||||
|     fig.canvas.flush_events() | ||||
|     temp_render_hook = False | ||||
| 
 | ||||
| #plt.ion() | ||||
| 
 | ||||
| #open image | ||||
| mask_path = "mask.png" | ||||
| mask = np.asarray(Image.open(mask_path).convert("L").resize((img_res_x, img_res_y)), dtype=np.double) | ||||
| #mask = np.zeros((1000, 1000), dtype=np.double) | ||||
| mask.setflags(write=1) | ||||
| mask /= np.max(mask) # normalize | ||||
| print(mask.shape) | ||||
| print(mask.dtype) | ||||
| print(mask) | ||||
| #ax.imshow(mask, norm="linear") | ||||
| #plt.show() | ||||
| 
 | ||||
| image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes) | ||||
| mask_buffer = cl.Buffer(opencl_context, cl.mem_flags.READ_ONLY, mask.nbytes) | ||||
| cl.enqueue_copy(opencl_queue, mask_buffer, mask).wait() | ||||
| #mask_buffer = cl.array.Array(opencl_context,mask.shape, dtype=np.uint8, data=mask) | ||||
| 
 | ||||
| #move to render | ||||
| print("Rendering {} frames...".format(frames)) | ||||
| if frames > 1: | ||||
|     with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total: | ||||
|         for frame_i in range(0, frames): | ||||
|             compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, mask, | ||||
|                                          np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                          np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                          np.double(x_min), np.double(y_min),  | ||||
|                                          np.uint32(iterations), np.uint32(escape), | ||||
|                                          np.double(frame_i / frames)) | ||||
| 
 | ||||
| 
 | ||||
|             cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|             rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated="True") | ||||
|             rendered_frames.append([rendered_frame]) | ||||
|             bar_total() | ||||
|     print("Encoding/Saving...") | ||||
|     ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True) | ||||
|     ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc") | ||||
| else: | ||||
|   ax.callbacks.connect('ylim_changed', render) | ||||
|   ax.callbacks.connect('xlim_changed', render) | ||||
|   render(ax) | ||||
|   plt.show(block=True) | ||||
| 
 | ||||
|          | ||||
							
								
								
									
										40
									
								
								live_play/kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,40 @@ | ||||
| //#include <math.h>
 | ||||
| #define PI 3.141592653589793115997963468544185161590576171875 | ||||
| 
 | ||||
| double cosecant_single(double a, double b) { return a / sin(b); } | ||||
| double secant_single(double a, double b) {  | ||||
|   //double killme = (double)floor(b / (PI / 2.0)) * (double)(PI / 2.0);
 | ||||
|   //return a / sin(killme); 
 | ||||
|   //return a / sin((PI / 2.0));
 | ||||
|   //return a / sin(PI);
 | ||||
|   return a / sin(-PI); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| __kernel void render_frame(__global unsigned int *frame_output, __global double *mask,  | ||||
|     double x_step, double y_step, | ||||
|     double x_start, double y_start, | ||||
|     unsigned int iterations, unsigned int escape, double ratio) {   | ||||
|   unsigned int result; | ||||
|   double x = (get_global_id(0) * x_step) + x_start; | ||||
|   double y = (get_global_id(1) * y_step) + y_start; | ||||
|   size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0); | ||||
| 
 | ||||
|   unsigned int iter; | ||||
| 
 | ||||
|      | ||||
|    | ||||
|   for(iter = 0; iter < iterations; iter++) {  | ||||
|     double next_x; | ||||
|     double r = mask[img_index]; | ||||
|     next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y)); | ||||
|     y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x)); | ||||
|     x = next_x; | ||||
|     if((pow(x, 2) + pow(y, 2)) >= escape) break; | ||||
|   } | ||||
|    | ||||
| 
 | ||||
|    | ||||
|   frame_output[img_index] = iter; | ||||
|   //frame_output[img_index] = mask[img_index] * 255;
 | ||||
| } | ||||
							
								
								
									
										1
									
								
								live_play/mask.png
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						| @ -0,0 +1 @@ | ||||
| ../masks/threedots.png | ||||
							
								
								
									
										79
									
								
								live_play/notes
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,79 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.animation as animation | ||||
| import pyopencl as cl | ||||
| from alive_progress import alive_bar | ||||
| 
 | ||||
| img_res_x = 2000 | ||||
| img_res_y = 2000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = 0 | ||||
| 
 | ||||
| xmin = (-periods * np.pi) + (square_x * np.pi) | ||||
| xmax = (periods  * np.pi) + (square_x * np.pi) | ||||
| ymin = (-periods * np.pi) + (square_y * np.pi) | ||||
| ymax = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| animation_progres_save = "./animations" | ||||
| frames = 120 | ||||
| 
 | ||||
| rendered_frames = [] | ||||
| 
 | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| opencl_context = cl.create_some_context() | ||||
| opencl_queue = cl.CommandQueue(opencl_context) | ||||
| 
 | ||||
| 
 | ||||
| #def render(): | ||||
| #  image = np.empty([img_res_y, img_res_x]) | ||||
| #  print("Rendering frames") | ||||
| #  with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total: | ||||
| #    for frame in range(frames): | ||||
| #      split_ratio = frame / frames | ||||
| #      for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)): | ||||
| #        for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)): | ||||
| #          on_x = x | ||||
| #          on_y = y | ||||
| #          for i in range(iterations): | ||||
| #            next_x = (split_ratio * (on_x/np.sin(on_y))) + ((1 - split_ratio) * on_x/np.tan(on_y)) | ||||
| #            on_y = (split_ratio * (on_y/np.sin(on_x))) + ((1 - split_ratio) * on_y/np.tan(on_x)) | ||||
| #            on_x = next_x | ||||
| #            if on_x**2 + on_y**2 > escape: | ||||
| #              break | ||||
| #          image[pix_y][pix_x] = i | ||||
| #      rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated=False) | ||||
| #      rendered_frames.append([rendered_frame]) | ||||
| #      bar_total() | ||||
|          | ||||
| def display(): | ||||
|   print(rendered_frames) | ||||
|   ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True) | ||||
|   ani.save("test.mp4") | ||||
|   plt.show() | ||||
| 
 | ||||
| render() | ||||
| display() | ||||
							
								
								
									
										30
									
								
								mask_tests/;
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,30 @@ | ||||
| unsigned int secant_fractal(double x, double y, unsigned int escape, unsigned int iterations) { | ||||
|   for(unsigned int iter = 0; iter < iterations; iter++) {  | ||||
|     double next_x; | ||||
|     next_x = x / cos(y); | ||||
|     y = y / cos(x); | ||||
|     x = next_x; | ||||
|     if((pow(x, 2) + pow(y, 2)) >= escape) return iter; | ||||
|   } | ||||
| } | ||||
| unsigned int cosecant_fractal(double x, double y, unsigned int escape, unsigned int iterations) { | ||||
|   for(unsigned int iter = 0; iter < iterations; iter++) {  | ||||
|     double next_x; | ||||
|     next_x = x / sin(y); | ||||
|     y = y / sin(x); | ||||
|     x = next_x; | ||||
|     if((pow(x, 2) + pow(y, 2)) >= escape) return iter; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| __kernel void render_frame(__global unsigned int *frame_output, //uint8_t *mask, //more bit depth is possible | ||||
|     double x_step, double y_step, | ||||
|     double x_start, double y_start, | ||||
|     unsigned int iterations, unsigned int escape, double ratio) {   | ||||
|   unsigned int result; | ||||
|   double on_x = (get_global_id(0) * x_step) + x_start; | ||||
|   double on_y = (get_global_id(1) * y_step) + y_start; | ||||
|    | ||||
|   frame_output[(get_global_id(1) * get_global_size(1)) + get_global_id(0)] = | ||||
|     secant_fractal(on_x, on_y, escape, iterations); | ||||
| } | ||||
							
								
								
									
										
											BIN
										
									
								
								mask_tests/asdf.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.0 MiB | 
							
								
								
									
										49
									
								
								mask_tests/kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,49 @@ | ||||
| unsigned int secant_fractal(double x, double y, unsigned int escape, unsigned int iterations) { | ||||
|   for(unsigned int iter = 0; iter < iterations; iter++) {  | ||||
|     double next_x; | ||||
|     next_x = x / cos(y); | ||||
|     y = y / cos(x); | ||||
|     x = next_x; | ||||
|     if((pow(x, 2) + pow(y, 2)) >= escape) return iter; | ||||
|   } | ||||
| } | ||||
| unsigned int cosecant_fractal(double x, double y, unsigned int escape, unsigned int iterations) { | ||||
|   for(unsigned int iter = 0; iter < iterations; iter++) {  | ||||
|     double next_x; | ||||
|     next_x = x / sin(y); | ||||
|     y = y / sin(x); | ||||
|     x = next_x; | ||||
|     if((pow(x, 2) + pow(y, 2)) >= escape) return iter; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| double cosecant_single(double a, double b) { return a / sin(b); } | ||||
| double secant_single(double a, double b) { return a / tan(b); } | ||||
| 
 | ||||
| 
 | ||||
| __kernel void render_frame(__global unsigned int *frame_output, __global double *mask,  | ||||
|     double x_step, double y_step, | ||||
|     double x_start, double y_start, | ||||
|     unsigned int iterations, unsigned int escape, double ratio) {   | ||||
|   unsigned int result; | ||||
|   double x = (get_global_id(0) * x_step) + x_start; | ||||
|   double y = (get_global_id(1) * y_step) + y_start; | ||||
|   size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0); | ||||
| 
 | ||||
|   unsigned int iter; | ||||
|      | ||||
|    | ||||
|   for(iter = 0; iter < iterations; iter++) {  | ||||
|     double next_x; | ||||
|     double r = mask[img_index]; | ||||
|     next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y)); | ||||
|     y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x)); | ||||
|     x = next_x; | ||||
|     if((pow(x, 2) + pow(y, 2)) >= escape) break; | ||||
|   } | ||||
|    | ||||
| 
 | ||||
|    | ||||
|   frame_output[img_index] = iter; | ||||
|   //frame_output[img_index] = mask[img_index] * 255;
 | ||||
| } | ||||
							
								
								
									
										1
									
								
								mask_tests/mask.png
									
									
									
									
									
										Symbolic link
									
								
							
							
						
						| @ -0,0 +1 @@ | ||||
| ../masks/threedots.png | ||||
							
								
								
									
										153
									
								
								mask_tests/mask.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						| @ -0,0 +1,153 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.animation as animation | ||||
| import pyopencl as cl | ||||
| from alive_progress import alive_bar | ||||
| from matplotlib.backend_bases import MouseButton | ||||
| from PIL import Image | ||||
| 
 | ||||
| img_res_x = 1000 | ||||
| img_res_y = 1000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = 0 | ||||
| 
 | ||||
| x_min = (-periods * np.pi) + (square_x * np.pi) | ||||
| x_max = (periods  * np.pi) + (square_x * np.pi) | ||||
| y_min = (-periods * np.pi) + (square_y * np.pi) | ||||
| y_max = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| animation_progres_save = "ani1_less.mp4" | ||||
| single_frame_save = "asdf.png" | ||||
| 
 | ||||
| opencl_context = cl.create_some_context(interactive=False) | ||||
| opencl_queue = cl.CommandQueue(opencl_context) | ||||
| 
 | ||||
| kernel_src_path = "./kernel.c" | ||||
| 
 | ||||
| frames = 1 | ||||
| rendered_frames = [] | ||||
| 
 | ||||
| image = np.empty([img_res_x, img_res_y], np.uint32) | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| #ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| mask_path = "mask.png" | ||||
| 
 | ||||
| bruh = None | ||||
| 
 | ||||
| def on_click(event): | ||||
|   global bruh | ||||
|   split_ratio = 1 | ||||
|   if (event.button is MouseButton.MIDDLE) and (event.inaxes): | ||||
|       # there's probably a way to set global coordinates; | ||||
|       # I don't expect this to go anywhere so I don't really care | ||||
|       on_x = ((event.xdata / img_res_x) * abs(x_max - x_min)) + x_min | ||||
|       on_y = ((event.ydata / img_res_y) * abs(y_max - y_min)) + y_min | ||||
| 
 | ||||
|       #I, uh, also don't know the best way to replicate the openCL code automaticly in python | ||||
|       #so ajust if nessesary | ||||
|       x_hops = [] | ||||
|       y_hops = [] | ||||
|       for i in range(iterations): | ||||
|           x_hops.append(((on_x - x_min) / abs(x_max - x_min)) * img_res_x) | ||||
|           y_hops.append(((on_y - y_min) / abs(y_max - y_min)) * img_res_y) | ||||
|           next_x = on_x/np.tan(on_y) | ||||
|           on_y = on_y/np.tan(on_x) | ||||
|           on_x = next_x | ||||
|           if on_x**2 + on_y**2 > escape: | ||||
|               break | ||||
|       print(y_hops[0]) | ||||
|       print(on_y) | ||||
|       print("{} hops".format(len(x_hops))) | ||||
|       if bruh: | ||||
|           bruh.pop(0).remove() | ||||
|       bruh = ax.plot(x_hops, y_hops) | ||||
|       plt.draw() | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|       print(on_x, on_y) | ||||
| 
 | ||||
| 
 | ||||
| print("compiling openCL kernel...") | ||||
| with open(kernel_src_path, 'r') as kernel_src: | ||||
|   compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build() | ||||
| 
 | ||||
| encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves') | ||||
| 
 | ||||
| def display_encoder_progress(current_frame: int, total_frames: int): | ||||
|   print("Encoding: frame {}/{}".format(current_frame, frames)) | ||||
| 
 | ||||
| #open image | ||||
| mask = np.asarray(Image.open(mask_path).convert("L"), dtype=np.double) | ||||
| mask.setflags(write=1) | ||||
| mask /= np.max(mask) # normalize | ||||
| print(mask.shape) | ||||
| print(mask.dtype) | ||||
| #ax.imshow(mask, norm="linear") | ||||
| #plt.show() | ||||
| 
 | ||||
| image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes) | ||||
| mask_buffer = cl.Buffer(opencl_context, cl.mem_flags.READ_ONLY, mask.nbytes) | ||||
| cl.enqueue_copy(opencl_queue, mask_buffer, mask).wait() | ||||
| #mask_buffer = cl.array.Array(opencl_context,mask.shape, dtype=np.uint8, data=mask) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| # TODO clean this up | ||||
| print("Rendering {} frames...".format(frames)) | ||||
| if frames > 1: | ||||
|   with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total: | ||||
|       for frame_i in range(0, frames): | ||||
|           compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, | ||||
|                                        np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                        np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                        np.double(x_min), np.double(y_min), | ||||
|                                        np.uint32(iterations), np.uint32(escape), | ||||
|                                        np.double(frame_i / frames)) | ||||
| 
 | ||||
| 
 | ||||
|           cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|           rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated="True") | ||||
|           rendered_frames.append([rendered_frame]) | ||||
|           bar_total() | ||||
|   print("Encoding/Saving...") | ||||
|   ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True) | ||||
|   ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc") | ||||
| else: | ||||
|   compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, mask_buffer, | ||||
|                                np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                np.double(x_min), np.double(y_min), | ||||
|                                np.uint32(iterations), np.uint32(escape), | ||||
|                                np.double(1)) | ||||
|   cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|   ax.imshow(image, norm="log", aspect="auto", cmap=cmap) | ||||
|   fig.savefig(single_frame_save) | ||||
|   plt.autoscale(False) | ||||
|   plt.connect('motion_notify_event', on_click) | ||||
|   plt.show() | ||||
							
								
								
									
										142
									
								
								mask_tests/mask.py.bak
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,142 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.animation as animation | ||||
| import pyopencl as cl | ||||
| from alive_progress import alive_bar | ||||
| from matplotlib.backend_bases import MouseButton | ||||
| from PIL import Image | ||||
| 
 | ||||
| img_res_x = 1000 | ||||
| img_res_y = 1000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = 0 | ||||
| 
 | ||||
| x_min = (-periods * np.pi) + (square_x * np.pi) | ||||
| x_max = (periods  * np.pi) + (square_x * np.pi) | ||||
| y_min = (-periods * np.pi) + (square_y * np.pi) | ||||
| y_max = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| animation_progres_save = "ani1_less.mp4" | ||||
| single_frame_save = "asdf.png" | ||||
| 
 | ||||
| opencl_context = cl.create_some_context(interactive=False) | ||||
| opencl_queue = cl.CommandQueue(opencl_context) | ||||
| 
 | ||||
| kernel_src_path = "./kernel.c" | ||||
| 
 | ||||
| frames = 1 | ||||
| rendered_frames = [] | ||||
| 
 | ||||
| image = np.empty([img_res_x, img_res_y], np.uint32) | ||||
| image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes) | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| #ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| mask_path = "mask.png" | ||||
| 
 | ||||
| bruh = None | ||||
| 
 | ||||
| def on_click(event): | ||||
|     global bruh | ||||
|     split_ratio = 1 | ||||
|     if (event.button is MouseButton.MIDDLE) and (event.inaxes): | ||||
|         # there's probably a way to set global coordinates; | ||||
|         # I don't expect this to go anywhere so I don't really care | ||||
|         on_x = ((event.xdata / img_res_x) * abs(x_max - x_min)) + x_min | ||||
|         on_y = ((event.ydata / img_res_y) * abs(y_max - y_min)) + y_min | ||||
| 
 | ||||
|         #I, uh, also don't know the best way to replicate the openCL code automaticly in python | ||||
|         #so ajust if nessesary | ||||
|         x_hops = [] | ||||
|         y_hops = [] | ||||
|         for i in range(iterations): | ||||
|             x_hops.append(((on_x - x_min) / abs(x_max - x_min)) * img_res_x) | ||||
|             y_hops.append(((on_y - y_min) / abs(y_max - y_min)) * img_res_y) | ||||
|             next_x = on_x/np.tan(on_y) | ||||
|             on_y = on_y/np.tan(on_x) | ||||
|             on_x = next_x | ||||
|             if on_x**2 + on_y**2 > escape: | ||||
|                 break | ||||
|         print(y_hops[0]) | ||||
|         print(on_y) | ||||
|         print("{} hops".format(len(x_hops))) | ||||
|         if bruh: | ||||
|             bruh.pop(0).remove() | ||||
|         bruh = ax.plot(x_hops, y_hops) | ||||
|         plt.draw() | ||||
| 
 | ||||
|           | ||||
| 
 | ||||
|         print(on_x, on_y) | ||||
| 
 | ||||
| 
 | ||||
| print("compiling openCL kernel...") | ||||
| with open(kernel_src_path, 'r') as kernel_src: | ||||
|   compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build() | ||||
| 
 | ||||
| encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves') | ||||
| 
 | ||||
| def display_encoder_progress(current_frame: int, total_frames: int): | ||||
|     print("Encoding: frame {}/{}".format(current_frame, frames)) | ||||
| 
 | ||||
| with open G | ||||
| 
 | ||||
| 
 | ||||
| # TODO clean this up | ||||
| print("Rendering {} frames...".format(frames)) | ||||
| if frames > 1: | ||||
|     with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total: | ||||
|         for frame_i in range(0, frames): | ||||
|             compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, | ||||
|                                          np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                          np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                          np.double(x_min), np.double(y_min),  | ||||
|                                          np.uint32(iterations), np.uint32(escape), | ||||
|                                          np.double(frame_i / frames)) | ||||
| 
 | ||||
| 
 | ||||
|             cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|             rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated="True") | ||||
|             rendered_frames.append([rendered_frame]) | ||||
|             bar_total() | ||||
|     print("Encoding/Saving...") | ||||
|     ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True) | ||||
|     ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc") | ||||
| else: | ||||
|         compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, | ||||
|                                      np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                      np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                      np.double(x_min), np.double(y_min),  | ||||
|                                      np.uint32(iterations), np.uint32(escape), | ||||
|                                      np.double(1)) | ||||
|         cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|         ax.imshow(image, norm="log", aspect="auto", cmap=cmap) | ||||
|         fig.savefig(single_frame_save) | ||||
|         plt.autoscale(False) | ||||
|         plt.connect('motion_notify_event', on_click) | ||||
|         plt.show() | ||||
| 
 | ||||
|          | ||||
							
								
								
									
										79
									
								
								mask_tests/notes
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,79 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.animation as animation | ||||
| import pyopencl as cl | ||||
| from alive_progress import alive_bar | ||||
| 
 | ||||
| img_res_x = 2000 | ||||
| img_res_y = 2000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = 0 | ||||
| 
 | ||||
| xmin = (-periods * np.pi) + (square_x * np.pi) | ||||
| xmax = (periods  * np.pi) + (square_x * np.pi) | ||||
| ymin = (-periods * np.pi) + (square_y * np.pi) | ||||
| ymax = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| animation_progres_save = "./animations" | ||||
| frames = 120 | ||||
| 
 | ||||
| rendered_frames = [] | ||||
| 
 | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| opencl_context = cl.create_some_context() | ||||
| opencl_queue = cl.CommandQueue(opencl_context) | ||||
| 
 | ||||
| 
 | ||||
| #def render(): | ||||
| #  image = np.empty([img_res_y, img_res_x]) | ||||
| #  print("Rendering frames") | ||||
| #  with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total: | ||||
| #    for frame in range(frames): | ||||
| #      split_ratio = frame / frames | ||||
| #      for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)): | ||||
| #        for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)): | ||||
| #          on_x = x | ||||
| #          on_y = y | ||||
| #          for i in range(iterations): | ||||
| #            next_x = (split_ratio * (on_x/np.sin(on_y))) + ((1 - split_ratio) * on_x/np.tan(on_y)) | ||||
| #            on_y = (split_ratio * (on_y/np.sin(on_x))) + ((1 - split_ratio) * on_y/np.tan(on_x)) | ||||
| #            on_x = next_x | ||||
| #            if on_x**2 + on_y**2 > escape: | ||||
| #              break | ||||
| #          image[pix_y][pix_x] = i | ||||
| #      rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated=False) | ||||
| #      rendered_frames.append([rendered_frame]) | ||||
| #      bar_total() | ||||
|          | ||||
| def display(): | ||||
|   print(rendered_frames) | ||||
|   ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True) | ||||
|   ani.save("test.mp4") | ||||
|   plt.show() | ||||
| 
 | ||||
| render() | ||||
| display() | ||||
							
								
								
									
										
											BIN
										
									
								
								masks/clouds.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 103 KiB | 
							
								
								
									
										
											BIN
										
									
								
								masks/hi.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 75 KiB | 
							
								
								
									
										
											BIN
										
									
								
								masks/test_circle.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 394 KiB | 
							
								
								
									
										
											BIN
										
									
								
								masks/test_circle_linear_smooth.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 433 KiB | 
							
								
								
									
										
											BIN
										
									
								
								masks/test_circle_perceptual_smooth.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 451 KiB | 
							
								
								
									
										
											BIN
										
									
								
								masks/test_diagnol.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 326 KiB | 
							
								
								
									
										
											BIN
										
									
								
								masks/test_diagnol_linear_smooth.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 573 KiB | 
							
								
								
									
										
											BIN
										
									
								
								masks/test_diagnol_perceptual_smooth.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 568 KiB | 
							
								
								
									
										
											BIN
										
									
								
								masks/threedots.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 178 KiB | 
							
								
								
									
										
											BIN
										
									
								
								photos_incorrectly_named/cosine_gpu_double_2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.8 MiB | 
							
								
								
									
										
											BIN
										
									
								
								photos_incorrectly_named/cpu.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 3.8 MiB | 
							
								
								
									
										
											BIN
										
									
								
								photos_incorrectly_named/ice_period_16.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.1 MiB | 
							
								
								
									
										
											BIN
										
									
								
								photos_incorrectly_named/ice_period_16_shifted_.25.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.1 MiB | 
							
								
								
									
										
											BIN
										
									
								
								photos_incorrectly_named/ice_period_16_shifted_.5.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.1 MiB | 
							
								
								
									
										
											BIN
										
									
								
								photos_incorrectly_named/ice_period_noshift_x_1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| After Width: | Height: | Size: 1.1 MiB | 
| After Width: | Height: | Size: 281 KiB | 
							
								
								
									
										
											BIN
										
									
								
								polar/.gpu_migration.py.swo
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								polar/.gpu_migration.py.swp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								polar/.kernel.c.swp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										157
									
								
								polar/gpu_migration.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						| @ -0,0 +1,157 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.animation as animation | ||||
| import matplotlib.style as mplstyle | ||||
| import pyopencl as cl | ||||
| from alive_progress import alive_bar | ||||
| from matplotlib.backend_bases import MouseButton | ||||
| from PIL import Image | ||||
| 
 | ||||
| # HELLO READER ------------------------------------------------------------------------ | ||||
| # yes, I know this script is horrid, but it's more of a scratchpad to quickly test ideas | ||||
| # and not anything I'm ever going to show anyone else. | ||||
| 
 | ||||
| img_res_x = 10000 | ||||
| img_res_y = 10000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = -2 | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = (255*3) | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| animation_progres_save = "ani1_less.mp4" | ||||
| single_frame_save = "asdf.png" | ||||
| 
 | ||||
| opencl_context = cl.create_some_context(interactive=False) | ||||
| opencl_queue = cl.CommandQueue(opencl_context) | ||||
| 
 | ||||
| kernel_src_path = "./kernel.c" | ||||
| 
 | ||||
| frames = 1 | ||||
| rendered_frames = [] | ||||
| 
 | ||||
| image = np.empty([img_res_x, img_res_y], np.uint32) | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| 
 | ||||
| #ax.invert_yaxis() | ||||
| #ax.set_xlim((-periods * np.pi) + (square_x * np.pi), (periods  * np.pi) + (square_x * np.pi)) | ||||
| #ax.set_ylim((-periods * np.pi) + (square_y * np.pi), (periods * np.pi) + (square_y * np.pi)) | ||||
| ax.set_xlim(-6.678564587410841, -4.837591292407222) | ||||
| ax.set_ylim(-1.0818908008385455, 0.9287284974589227) | ||||
| 
 | ||||
| #ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| mplstyle.use('fast') | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| print("compiling openCL kernel...") | ||||
| with open(kernel_src_path, 'r') as kernel_src: | ||||
|   compiled_kernel = cl.Program(opencl_context, kernel_src.read()).build() | ||||
| 
 | ||||
| encoding_progress = alive_bar(frames, bar = 'filling', spinner = 'waves') | ||||
| 
 | ||||
| def display_encoder_progress(current_frame: int, total_frames: int): | ||||
|     print("Encoding: frame {}/{}".format(current_frame, frames)) | ||||
| 
 | ||||
| temp_render_hook = False | ||||
| mp_image = None | ||||
| 
 | ||||
| def render(axes): | ||||
|   global temp_render_hook | ||||
|   global mp_image | ||||
|   if not temp_render_hook: | ||||
|     temp_render_hook = True | ||||
|     x_min = axes.get_xlim()[0] | ||||
|     x_max = axes.get_xlim()[1] | ||||
|     y_min = axes.get_ylim()[1] | ||||
|     y_max = axes.get_ylim()[0] | ||||
|     print(axes.get_ylim()) | ||||
|     compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, mask_buffer, | ||||
|                                  np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                  np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                  np.double(x_min), np.double(y_min),  | ||||
|                                  np.uint32(iterations), np.uint32(escape), | ||||
|                                  np.double(1)) | ||||
|     cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|     print("kernel") | ||||
|     if mp_image == None: | ||||
|       mp_image = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, interpolation='none', extent=(x_min, x_max, y_min, y_max)) # TODO | ||||
|     else: | ||||
|       mp_image.set(extent=(x_min, x_max, y_min, y_max)) | ||||
|       #ax.set_aspect('equal') | ||||
|       #mp_image.set_data(image) | ||||
|       mp_image.set_array(image) | ||||
|        | ||||
| 
 | ||||
|     fig.canvas.draw_idle() | ||||
|     fig.canvas.flush_events() | ||||
|     temp_render_hook = False | ||||
| 
 | ||||
| #plt.ion() | ||||
| 
 | ||||
| #open image | ||||
| mask_path = "mask.png" | ||||
| mask = np.asarray(Image.open(mask_path).convert("L").resize((img_res_x, img_res_y)), dtype=np.double) | ||||
| #mask = np.zeros((img_res_x, img_res_y), dtype=np.double) | ||||
| mask.setflags(write=1) | ||||
| mask /= np.max(mask) # normalize | ||||
| print(mask.shape) | ||||
| print(mask.dtype) | ||||
| print(mask) | ||||
| #ax.imshow(mask, norm="linear") | ||||
| #plt.show() | ||||
| 
 | ||||
| image_buffer = cl.Buffer(opencl_context, cl.mem_flags.WRITE_ONLY, image.nbytes) | ||||
| mask_buffer = cl.Buffer(opencl_context, cl.mem_flags.READ_ONLY, mask.nbytes) | ||||
| cl.enqueue_copy(opencl_queue, mask_buffer, mask).wait() | ||||
| #mask_buffer = cl.array.Array(opencl_context,mask.shape, dtype=np.uint8, data=mask) | ||||
| 
 | ||||
| #move to render | ||||
| print("Rendering {} frames...".format(frames)) | ||||
| if frames > 1: | ||||
|     with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total: | ||||
|         for frame_i in range(0, frames): | ||||
|             compiled_kernel.render_frame(opencl_queue, image.shape, None, image_buffer, mask, | ||||
|                                          np.double(abs(x_max - x_min) / img_res_x), | ||||
|                                          np.double(abs(y_max - y_min) / img_res_y), | ||||
|                                          np.double(x_min), np.double(y_min),  | ||||
|                                          np.uint32(iterations), np.uint32(escape), | ||||
|                                          np.double(frame_i / frames)) | ||||
| 
 | ||||
| 
 | ||||
|             cl.enqueue_copy(opencl_queue, image, image_buffer).wait() | ||||
|             rendered_frame = ax.imshow(image, norm="linear", aspect="auto", cmap=cmap, animated="True") | ||||
|             rendered_frames.append([rendered_frame]) | ||||
|             bar_total() | ||||
|     print("Encoding/Saving...") | ||||
|     ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True) | ||||
|     ani.save(animation_progres_save, extra_args=['-preset', 'lossless'], progress_callback=display_encoder_progress, codec="h264_nvenc") | ||||
| else: | ||||
|   ax.callbacks.connect('ylim_changed', render) | ||||
|   ax.callbacks.connect('xlim_changed', render) | ||||
|   render(ax) | ||||
|   plt.savefig("out.png") | ||||
|   #plt.show(block=True) | ||||
| 
 | ||||
|          | ||||
							
								
								
									
										35
									
								
								polar/kernel.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,35 @@ | ||||
| //#include <math.h>
 | ||||
| #define PI 3.141592653589793115997963468544185161590576171875 | ||||
| 
 | ||||
| double cosecant_single(double a, double b) { return a / sin(b); } | ||||
| double secant_single(double a, double b) { return a / tan(b); } | ||||
| 
 | ||||
| 
 | ||||
| __kernel void render_frame(__global unsigned int *frame_output, __global double *mask,  | ||||
|     double x_step, double y_step, | ||||
|     double x_start, double y_start, | ||||
|     unsigned int iterations, unsigned int escape, double ratio) {   | ||||
|   unsigned int result; | ||||
|   double x_cart = (get_global_id(0) * x_step) + x_start; | ||||
|   double y_cart = (get_global_id(1) * y_step) + y_start; | ||||
|   size_t img_index = (get_global_id(1) * get_global_size(1)) + get_global_id(0); | ||||
| 
 | ||||
|   double x = sqrt(pow(x_cart, 2) + pow(y_cart, 2)); | ||||
|   double y = atan(y_cart / x_cart); | ||||
| 
 | ||||
|   unsigned int iter; | ||||
|    | ||||
|   for(iter = 0; iter < iterations; iter++) {  | ||||
|     double next_x; | ||||
|     double r = mask[img_index]; | ||||
|     next_x = (r * cosecant_single(x, y)) + ((1 - r) * secant_single(x, y)); | ||||
|     y = (r * cosecant_single(y, x)) + ((1 - r) * secant_single(y, x)); | ||||
|     x = next_x; | ||||
|     if((pow(x, 2) + pow(y, 2)) >= escape) break; | ||||
|   } | ||||
|    | ||||
| 
 | ||||
|    | ||||
|   frame_output[img_index] = iter; | ||||
|   //frame_output[img_index] = mask[img_index] * 255;
 | ||||
| } | ||||
							
								
								
									
										79
									
								
								polar/notes
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,79 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| import matplotlib.animation as animation | ||||
| import pyopencl as cl | ||||
| from alive_progress import alive_bar | ||||
| 
 | ||||
| img_res_x = 2000 | ||||
| img_res_y = 2000 | ||||
| total_pixels = img_res_x * img_res_y # so we don't gotta compute it every time | ||||
| 
 | ||||
| periods = 1 | ||||
| square_x = 0 | ||||
| square_y = 0 | ||||
| 
 | ||||
| xmin = (-periods * np.pi) + (square_x * np.pi) | ||||
| xmax = (periods  * np.pi) + (square_x * np.pi) | ||||
| ymin = (-periods * np.pi) + (square_y * np.pi) | ||||
| ymax = (periods * np.pi) + (square_y * np.pi) | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255*3 | ||||
| c_x = 2 * np.pi | ||||
| c_y = 2 * np.pi | ||||
| 
 | ||||
| animation_progres_save = "./animations" | ||||
| frames = 120 | ||||
| 
 | ||||
| rendered_frames = [] | ||||
| 
 | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| opencl_context = cl.create_some_context() | ||||
| opencl_queue = cl.CommandQueue(opencl_context) | ||||
| 
 | ||||
| 
 | ||||
| #def render(): | ||||
| #  image = np.empty([img_res_y, img_res_x]) | ||||
| #  print("Rendering frames") | ||||
| #  with alive_bar(frames, bar = 'filling', spinner = 'waves') as bar_total: | ||||
| #    for frame in range(frames): | ||||
| #      split_ratio = frame / frames | ||||
| #      for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)): | ||||
| #        for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)): | ||||
| #          on_x = x | ||||
| #          on_y = y | ||||
| #          for i in range(iterations): | ||||
| #            next_x = (split_ratio * (on_x/np.sin(on_y))) + ((1 - split_ratio) * on_x/np.tan(on_y)) | ||||
| #            on_y = (split_ratio * (on_y/np.sin(on_x))) + ((1 - split_ratio) * on_y/np.tan(on_x)) | ||||
| #            on_x = next_x | ||||
| #            if on_x**2 + on_y**2 > escape: | ||||
| #              break | ||||
| #          image[pix_y][pix_x] = i | ||||
| #      rendered_frame = ax.imshow(image, norm="log", aspect="auto", cmap=cmap, animated=False) | ||||
| #      rendered_frames.append([rendered_frame]) | ||||
| #      bar_total() | ||||
|          | ||||
| def display(): | ||||
|   print(rendered_frames) | ||||
|   ani = animation.ArtistAnimation(fig, rendered_frames, interval=30, blit=True) | ||||
|   ani.save("test.mp4") | ||||
|   plt.show() | ||||
| 
 | ||||
| render() | ||||
| display() | ||||
							
								
								
									
										21
									
								
								polar/texput.log
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @ -0,0 +1,21 @@ | ||||
| This is pdfTeX, Version 3.141592653-2.6-1.40.26 (TeX Live 2024/Arch Linux) (preloaded format=pdflatex 2024.4.22)  28 APR 2024 21:33 | ||||
| entering extended mode | ||||
|  restricted \write18 enabled. | ||||
|  %&-line parsing enabled. | ||||
| ** | ||||
| 
 | ||||
| ! Emergency stop. | ||||
| <*>  | ||||
|      | ||||
| End of file on the terminal! | ||||
| 
 | ||||
|   | ||||
| Here is how much of TeX's memory you used: | ||||
|  3 strings out of 476076 | ||||
|  113 string characters out of 5793775 | ||||
|  1925187 words of memory out of 5000000 | ||||
|  22212 multiletter control sequences out of 15000+600000 | ||||
|  558069 words of font info for 36 fonts, out of 8000000 for 9000 | ||||
|  14 hyphenation exceptions out of 8191 | ||||
|  0i,0n,0p,13b,6s stack positions out of 10000i,1000n,20000p,200000b,200000s | ||||
| !  ==> Fatal error occurred, no output PDF file produced! | ||||
							
								
								
									
										55
									
								
								thorn_fractal.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						| @ -0,0 +1,55 @@ | ||||
| #!/usr/bin/env python3 | ||||
| import numpy as np | ||||
| import matplotlib.pyplot as plt | ||||
| 
 | ||||
| img_res_x = 2000 | ||||
| img_res_y = 2000 | ||||
| 
 | ||||
| xmin = -np.pi | ||||
| xmax = np.pi | ||||
| ymin = -np.pi | ||||
| ymax = np.pi | ||||
| 
 | ||||
| escape = 10000 | ||||
| iterations = 255 | ||||
| c_x = 0 | ||||
| c_y = 0 | ||||
| 
 | ||||
| 
 | ||||
| image = np.empty([img_res_y, img_res_x], np.float32) | ||||
| 
 | ||||
| for pix_y, y in enumerate(np.linspace(ymin, ymax, img_res_y)): | ||||
|   for pix_x, x in enumerate(np.linspace(xmin, xmax, img_res_x)): | ||||
|     on_x = x | ||||
|     on_y = y | ||||
|     for i in range(iterations): | ||||
|       next_x = (on_x/np.sin(on_y)) | ||||
|       on_y = (on_y/np.sin(on_x)) | ||||
|       on_x = next_x | ||||
|       if on_x**2 + on_y**2 > escape: | ||||
|         break | ||||
|     image[pix_y][pix_x] = i | ||||
|   #print(pix_y) | ||||
| 
 | ||||
| 
 | ||||
|        | ||||
| 
 | ||||
| plt.style.use('dark_background') | ||||
| # fuck this shit | ||||
| fig = plt.figure(frameon=False) | ||||
| fig.set_size_inches(img_res_x/fig.dpi, img_res_y/fig.dpi) | ||||
| #fig.set_size_inches(width/height, 1, forward=False) | ||||
| print(fig.dpi) | ||||
| 
 | ||||
| ax = plt.Axes(fig, [0., 0., 1., 1.]) | ||||
| ax.set_axis_off() | ||||
| fig.add_axes(ax) | ||||
| 
 | ||||
| cmap = plt.cm.viridis | ||||
| cmap.set_bad((0,0,0)) | ||||
| cmap.set_over((0,0,0)) | ||||
| cmap.set_under((0,0,0)) | ||||
| 
 | ||||
| ax.imshow(image, norm="log", aspect="auto", cmap=cmap) | ||||
| fig.savefig("animation/cpu.png") | ||||
| #plt.show() | ||||
 Brett Weiland
						Brett Weiland