kaka.farm

Unnamed repository; edit this file 'description' to name the repository.
git clone https://kaka.farm/~git/kaka.farm
Log | Files | Refs | README

dragon_curve.py (3288B)


      1 __version__ = '0.1.0'
      2 
      3 
      4 from typing import List, Tuple
      5 
      6 
      7 PathType = List[Tuple[int, int]]
      8 
      9 
     10 def ccw(p: Tuple[int, int]) -> Tuple[int, int]:
     11     return [-p[1], p[0]]
     12 
     13 
     14 def dragon_curve(generation_number: int) -> PathType:
     15     l = [[0, 0], [1, 0]] 
     16 
     17     for i in range(generation_number):
     18         new_portion = [ccw(n) for n in l[1:]]
     19         new_pivot = new_portion[-1]
     20         l = new_portion[::-1] + l
     21         l = [
     22                 [n[0] - new_pivot[0],
     23                     n[1] - new_pivot[1]]
     24                 for n in l]
     25 
     26     return l
     27 
     28 
     29 def write_matplotlib_png(dragon_curve_path: PathType):
     30     import matplotlib.pyplot as plt
     31 
     32     plt.scatter(
     33             [n[0] for n in dragon_curve_path],
     34             [n[1] for n in dragon_curve_path])
     35     plt.show()
     36     plt.savefig('dragon-curve.png')
     37 
     38 
     39 def transform(values, low, high):
     40     min_value = min(values)
     41     max_value = max(values)
     42     old_difference = max_value - min_value
     43     new_difference = high - low
     44     # values = [n - min_value for n in values] # [0, max-min = old_difference]
     45     # values = [n / old_difference for n in values] # [0, 1]
     46     # values = [n * new_difference for n in values] # [0, new_difference = high - low]
     47     # values = [n + low for n in values] # [low, high]
     48     return [(n - min_value) * new_difference / old_difference + low
     49             for n in values]
     50 
     51 
     52 def path_to_svg_file_content(
     53         path: PathType,
     54         image_width=500,
     55         image_height=500,
     56         left_border=50,
     57         right_border=50,
     58         bottom_border=50,
     59         top_border=50,
     60     ) -> str:
     61     path = list(zip(
     62         transform([p[0] for p in path], left_border, image_width - right_border),
     63         transform([p[1] for p in path], top_border, image_width - bottom_border)))
     64 
     65     svg_path = ''.join(f'L{p[0]} {p[1]}' for p in path)
     66 
     67     return f'''
     68 <svg width="{image_width}" height="{image_height}" fill="white" xmlns="http://www.w3.org/2000/svg">
     69 
     70   <path fill="none" stroke="black" stroke-linejoin="round" stroke-width="0.7" d="M{path[0][0]} {path[0][1]}{svg_path}"/>
     71 
     72 </svg>
     73     '''.strip()
     74 
     75 
     76 def path_to_curvy_svg_no_clue(
     77         path: PathType,
     78         image_width=500,
     79         image_height=500,
     80         left_border=50,
     81         right_border=50,
     82         bottom_border=50,
     83         top_border=50,
     84     ) -> str:
     85     '''
     86     path = list(zip(
     87         transform([p[0] for p in path], left_border, image_width - right_border),
     88         transform([p[1] for p in path], top_border, image_width - bottom_border)))
     89     '''
     90 
     91     min_x = min(p[0] for p in path)
     92     min_y = min(p[1] for p in path)
     93     max_x = max(p[0] for p in path)
     94     max_y = max(p[1] for p in path)
     95 
     96     stroke_width = (max_x - min_x) * 0.01
     97 
     98     consecutives = list(zip(path[:-1], path[1:]))
     99 
    100     svg_path = ''.join(f'L{p[0]} {p[1]}' for p in path)
    101 
    102     svg_path += (
    103         ''.join(
    104             f'M{pair[0][0]} {pair[0][1]}'
    105             f'A2 2 0 0 0 {pair[1][0]} {pair[1][1]}'
    106             for pair in consecutives))
    107 
    108     return f'''
    109 <svg width="{image_width}" height="{image_height}" viewBox="{min_x-1} {min_y-1} {max_x-min_x+1} {max_y-min_y+1}" fill="white" xmlns="http://www.w3.org/2000/svg">
    110 
    111   <path fill="none" stroke="black" stroke-linejoin="round" stroke-width="{stroke_width}" d="M{path[0][0]} {path[0][1]}{svg_path}"/>
    112 
    113 </svg>
    114     '''.strip()