import svgwrite import math # mogrify -format gif *.svg # gifsicle --scale 0.2 --delay=5 --loop --optimize=2 --colors=256 --multifile *.gif > OutGIF/out.gif order = 3 number_of_index_bits = order * 2 number_of_elements = pow(2, number_of_index_bits) x_offset = 130 y_offset = 130 class Diagram: def __init__(self, width, height): self.width = width self.height = height self.dwg = svgwrite.Drawing(profile='full', size=(str(width) + 'px', str(height) + 'px'), viewBox=('0 0 ' + str(width) + ' ' + str(height))) self.dwg.add(self.dwg.rect(insert=(0, 0), size=(width, height), fill='rgb(50,50,50)')) def coordinate_transform(width, height, size, cells, offset): return lambda v: [(v[0] + 0.5) * size / cells + offset[0], size - (v[1] + 0.5) * size / cells + offset[1]] def draw_grid(d, size, number_of_cells, position): ct = coordinate_transform(d.width, d.height, size, number_of_cells, position) d.dwg.add(d.dwg.rect(insert=(position[0], position[1]), size=(size, size), stroke='rgb(200,200,200)', stroke_width=5, fill='none')) for i in range(1, number_of_cells): offset = size * i / number_of_cells d.dwg.add(d.dwg.line(start=(position[0], position[1] + offset), end=(position[0] + size, position[1] + offset), stroke='rgb(200,200,200)', stroke_width=5)) d.dwg.add(d.dwg.line(start=(position[0] + offset, position[1]), end=(position[0] + offset, position[1] + size), stroke='rgb(200,200,200)', stroke_width=5)) return ct binary_index = [] for i in range(0, number_of_elements): binary_list = [] temp = i for element in range(0, number_of_index_bits): binary_list.append(temp % 2) temp //= 2 binary_list.reverse() gray_list = [binary_list[0]] + [abs(binary_list[j+1]-binary_list[j]) for j in range(number_of_index_bits-1)] print(binary_list) print(gray_list) print("---") x_bin = gray_list[0::2] y_bin = gray_list[1::2] x = 0 for bit in x_bin: x *= 2 x += bit y = 0 for bit in y_bin: y *= 2 y += bit binary_strings = {'index': i, 'binary': binary_list, 'gray': gray_list, 'x': x, 'x_bin': x_bin, 'y': y, 'y_bin': y_bin} binary_index.append(binary_strings) diagram = Diagram(1920*2, 1080*2) grid_coord_transform = draw_grid(diagram, 1900, pow(2, order), (x_offset, y_offset)) title = diagram.dwg.add( diagram.dwg.text( "Gray Code Indexing", insert=(x_offset + 2000, y_offset + 100), fill="rgb(200,200,200)", style="font-size:150px; font-family:Lucida Console; font-weight:bold")) attribution = diagram.dwg.add( diagram.dwg.text( "@GPTreb", insert=(x_offset + 3100, y_offset + 1900), fill="rgb(200,200,200)", style="font-size:100px; font-family:Lucida Console; font-weight:bold")) index_name = diagram.dwg.add( diagram.dwg.text( "Index", insert=(x_offset + 2000, y_offset + 450), fill="rgb(200,200,200)", style="font-size:150px; font-family:Lucida Console; font-weight:bold")) index_num = diagram.dwg.add( diagram.dwg.text( "", insert=(x_offset + 2000, y_offset + 650), fill="rgb(200,200,200)", style="font-size:150px; font-family:Lucida Console; font-weight:bold")) binary_name = diagram.dwg.add( diagram.dwg.text( "Gray code of Index", insert=(x_offset + 2000, y_offset + 1000), fill="rgb(200,200,200)", style="font-size:150px; font-family:Lucida Console; font-weight:bold")) binary_num = diagram.dwg.add( diagram.dwg.text( "0b", insert=(x_offset + 2000, y_offset + 1200), fill="rgb(200,200,200)", style="font-size:150px; font-family:Lucida Console; font-weight:bold")) x_name = diagram.dwg.add( diagram.dwg.text( "x=0b", insert=(x_offset + 2000, y_offset + 1500), fill="rgb(200,100,100)", style="font-size:150px; font-family:Lucida Console; font-weight:bold")) y_name = diagram.dwg.add( diagram.dwg.text( "y=0b", insert=(x_offset + 2000, y_offset + 1700), fill="rgb(100,100,200)", style="font-size:150px; font-family:Lucida Console; font-weight:bold")) circle = diagram.dwg.add(diagram.dwg.circle(r=30, fill="rgb(100,200,100)")) path = [] trajectory = diagram.dwg.add( diagram.dwg.polyline( points=[(0, 0)], stroke="rgb(100,200,100)", stroke_linejoin='round', stroke_width=15, fill='none')) frame = 0 index_bits = [] for i in range(0, number_of_index_bits): temp = diagram.dwg.add( diagram.dwg.text( "1", insert=(x_offset + 2220+i*110, y_offset + 1200), fill="rgb(200,200,200)", style="font-size:150px; font-family:Lucida Console; font-weight:bold")) index_bits.append(temp) for step in range(0, number_of_elements): digits = math.ceil(math.log10(number_of_elements)) format_string = '{0:0>' + str(digits) + '}' index_num.text = format_string.format(step) index_bit_list = binary_index[step]['gray'] for i in range(0, number_of_index_bits): index_bits[i].text = index_bit_list[i] if (i % 2) == 0: index_bits[i]['fill'] = "rgb(200,100,100)" else: index_bits[i]['fill'] = "rgb(100,100,200)" x_binary = binary_index[step]['x_bin'] x_dec = binary_index[step]['x'] y_binary = binary_index[step]['y_bin'] y_dec = binary_index[step]['y'] x_string = ''.join([str(e) for e in x_binary]) y_string = ''.join([str(e) for e in y_binary]) x_name.text = 'x=0b' + x_string y_name.text = 'y=0b' + y_string marker_coordinates = grid_coord_transform((x_dec, y_dec)) diagram.dwg.add(diagram.dwg.circle(center=marker_coordinates, r=30, fill="rgb(100,200,100)")) if step < number_of_elements-1: next_x_dec = binary_index[step+1]['x'] next_y_dec = binary_index[step+1]['y'] transition_steps = int(math.sqrt(pow((next_y_dec-y_dec), 2) + pow((next_x_dec-x_dec), 2))/0.1) for i in range(0, transition_steps): transitional_x = (transition_steps-i) * x_dec + i * next_x_dec transitional_y = (transition_steps-i) * y_dec + i * next_y_dec dot_coordinates = grid_coord_transform( (transitional_x / transition_steps, transitional_y / transition_steps)) coordinate_tuple = tuple(dot_coordinates) path.append(coordinate_tuple) trajectory.points = path circle['cx'] = dot_coordinates[0] circle['cy'] = dot_coordinates[1] diagram.dwg.filename = format(frame, '04') + '.svg' diagram.dwg.save() frame += 1 else: transitional_x = x_dec transitional_y = y_dec dot_coordinates = grid_coord_transform((x_dec, y_dec)) coordinate_tuple = tuple(dot_coordinates) path.append(coordinate_tuple) trajectory.points = path circle['cx'] = dot_coordinates[0] circle['cy'] = dot_coordinates[1] for end_frames in range(0, 20): diagram.dwg.filename = format(frame, '04') + '.svg' diagram.dwg.save() frame += 1