mate2code

full octahedral group - SVG script

Aug 11th, 2019
472
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.50 KB | None | 0 0
  1. import numpy as np
  2. from math import log, ceil
  3.  
  4. from misc.bin2svg import bin2svg       # https://pastebin.com/y8rY5Vj4
  5.  
  6. from octahedral_permutations import *  # https://pastebin.com/JBx0TSsC
  7. from store_svg import *                # https://pastebin.com/FaBF6k7E
  8.  
  9.  
  10. def number_to_reverse_binary_list(n, length):
  11.     bin_str = "{0:b}".format(n).zfill(length)[::-1]
  12.     return [int(digit) for digit in bin_str]
  13.  
  14.  
  15. def perm_to_bin_mat(perm):
  16.     long = len(perm)
  17.     high = ceil(log(max(perm), 2))
  18.     mat = np.zeros([high, long], dtype=bool)
  19.     for i, e in enumerate(perm):
  20.         mat[:, i] = number_to_reverse_binary_list(e, high)
  21.     return mat
  22.  
  23.  
  24. def perm_to_svg_path(perm):
  25.     mat = perm_to_bin_mat(perm)
  26.     return bin2svg(mat)
  27.  
  28.  
  29. conjugacy_class_to_color = {
  30.     'A': 'white',  'B': 'white',  'C': 'white',  'D': 'green', 'E': 'orange',
  31.     'a': 'yellow', 'b': 'yellow', 'c': 'yellow', 'd': 'blue',  'e': 'red'
  32. }
  33.  
  34.  
  35. gray_cube_coordinates = [(0, 3), (0, 1), (1, 2), (1, 0), (2, 3), (2, 1), (3, 2), (3, 0)]
  36. arrow_cube_coordinates = [(0, 3), (0, 1), (.6, 2.2), (.6, .2), (2, 3), (2, 1), (2.6, 2.2), (2.6, .2)]
  37.  
  38. for filenum in range(6):
  39.  
  40.     footer_perm_formulas = ''
  41.     footer_perm_matrix = ''
  42.     footer_invperm_formulas = ''
  43.     footer_invperm_matrix = ''
  44.  
  45.     filename = 'test %s.svg' % filenum
  46.  
  47.     rectangles_svg = ''
  48.     gray_matrix_text_svg = ''
  49.  
  50.     for rectnum in range(8):
  51.  
  52.         permdict = octahedral_permutations[(rectnum, filenum)]
  53.         invpermdict = octahedral_permutations[permdict['inverse']]
  54.         perm, invperm = permdict['perm'], invpermdict['perm']
  55.  
  56.         # background and cube colors
  57.         rectbeige = 'f6e6d2' if permdict['parity'] else 'fcf9f0'  # light if parity 0
  58.         (bottomgray, topgray) = ('ddd', '888') if rectnum in [0, 3, 5, 6] else ('888', 'ddd')
  59.         if rectnum == 0:
  60.             (bottombeige, topbeige) = ('f6e6d2', 'fcf9f0') if permdict['parity'] else ('fcf9f0', 'f6e6d2')
  61.  
  62.         # conjugacy class colors
  63.         conjug_letter = permdict['conjug']
  64.         conjug_color_name = conjugacy_class_to_color[conjug_letter]
  65.         conjug_color = {
  66.             'white':  'ffffff', 'green': '33d42a', 'orange': 'ffa200',
  67.             'yellow': 'ffff7f', 'blue':  '3375ff', 'red':    'ef2500'
  68.         }[conjug_color_name]
  69.  
  70.         # permutation IDs (0..23, 0'..23')
  71.         int24 = permdict['int'] % 24
  72.         apostrophe = permdict['int'] >= 24
  73.         bold = int24 in [0, 7, 16, 23]
  74.         perm_id = str(int24) + apostrophe*"'"
  75.  
  76.         perm_id_circle_svg = '<circle cx="0" cy="0" r="18" stroke="black" stroke-width="%s" fill="#%s" />' \
  77.                              '<g style="text-anchor: middle;" font-family="sans-serif" font-size="16px" font-weight="%s">' \
  78.                              '<text x="0" y="6">%s</text></g>' \
  79.                              % ('3' if bold else '1.5', conjug_color, 'bold' if bold else 'normal', perm_id)
  80.  
  81.         # arrows
  82.         arrows_svg = ''
  83.         for i, p in enumerate(perm):
  84.             if i != p:
  85.                 c1 = arrow_cube_coordinates[i]
  86.                 c2 = arrow_cube_coordinates[p]
  87.                 diff = np.array(c2) - np.array(c1)
  88.                 diff_length = np.sqrt(diff[0] ** 2 + diff[1] ** 2)
  89.                 diff_short = diff * .32 / diff_length  # .32 is the approximate length of the arrow end before scaling by 30
  90.                 if perm[p] == i:  # if this is a transposition, make one double arrow
  91.                     if i < p:
  92.                         c1_short = c1 + diff_short
  93.                         c2_short = c2 - diff_short
  94.                         coordinates = (
  95.                             round(c1_short[0], 3), round(c1_short[1], 3), round(c2_short[0], 3), round(c2_short[1], 3)
  96.                         )
  97.                         arrows_svg += '<g opacity=".7">' \
  98.                                       '<line x1="%s" y1="%s" x2="%s" y2="%s" ' \
  99.                                       'marker-start="url(#backward)" marker-end="url(#foreward)" />' \
  100.                                       '</g>' % coordinates
  101.                 else:  # if no transposition
  102.                     c2_short = c2 - diff_short
  103.                     coordinates = (c1[0], c1[1], round(c2_short[0], 3), round(c2_short[1], 3))
  104.                     arrows_svg += '<g opacity=".7">' \
  105.                                   '<line x1="%s" y1="%s" x2="%s" y2="%s" marker-end="url(#foreward)" />' \
  106.                                   '</g>' % coordinates
  107.  
  108.         # permuted numbers
  109.         perm_vector = '<text x="0" y="0">%s</text><text x="15" y="0">%s</text>' \
  110.                       '<text x="30" y="0">%s</text><text x="45" y="0">%s</text>' \
  111.                       '<text x="67" y="0">%s</text><text x="82" y="0">%s</text>' \
  112.                       '<text x="97" y="0">%s</text><text x="112" y="0">%s</text>' % perm
  113.  
  114.         invperm_vector = '<text x="0" y="0">%s</text><text x="24" y="0">%s</text>' \
  115.                          '<text x="48" y="0">%s</text><text x="72" y="0">%s</text>' \
  116.                          '<text x="96" y="0">%s</text><text x="120" y="0">%s</text>' \
  117.                          '<text x="144" y="0">%s</text><text x="168" y="0">%s</text>' % invperm
  118.  
  119.         invperm_cube = '<text x="0" y="90">%s</text><text x="0" y="30">%s</text>' \
  120.                        '<text x="30" y="60">%s</text><text x="30" y="0">%s</text>' \
  121.                        '<text x="60" y="90">%s</text><text x="60" y="30">%s</text>' \
  122.                        '<text x="90" y="60">%s</text><text x="90" y="0">%s</text>' % invperm
  123.  
  124.         # letters
  125.         perm_letters = '<use xlink:href="#%s" transform="translate(0)"/>' \
  126.                        '<use xlink:href="#%s" transform="translate(28)"/>' \
  127.                        '<use xlink:href="#%s" transform="translate(56)"/>' % permdict['letters']
  128.  
  129.         invperm_letters = '<use xlink:href="#%s" transform="translate(0)"/>' \
  130.                           '<use xlink:href="#%s" transform="translate(28)"/>' \
  131.                           '<use xlink:href="#%s" transform="translate(56)"/>' % invpermdict['letters']
  132.  
  133.         # negators
  134.         perm_negators = ''
  135.         for i, d in enumerate(permdict['negators']):
  136.             if d:
  137.                 perm_negators += '<rect x="%s" y="31" width="16" height="2.5"/>' % (101 + i * 28)
  138.  
  139.         invperm_negators = ''
  140.         for i, d in enumerate(invpermdict['negators']):
  141.             if d:
  142.                 invperm_negators += '<rect x="%s" y="31" width="16" height="2.5"/>' % (101 + i * 28)
  143.  
  144.         # formulas (letters with negators)
  145.         perm_formula = formula_svg_store.format(letters=perm_letters, negators=perm_negators)
  146.         invperm_formula = formula_svg_store.format(letters=invperm_letters, negators=invperm_negators)
  147.  
  148.         # SVG matrices
  149.         perm_mat = perm_to_svg_path(perm)
  150.         invperm_mat = perm_to_svg_path(invperm)
  151.  
  152.         # where to move the rectangle
  153.         (rectx, recty) = (gray_cube_coordinates[rectnum][0] * 200, gray_cube_coordinates[rectnum][1] * 200)
  154.  
  155.         # append to ``rectangles_svg``
  156.         rectangles_svg += rectangle_svg_store.format(rectx=rectx, recty=recty,
  157.                                                      idcircle=perm_id_circle_svg,
  158.                                                      pmat=perm_mat, ipmat=invperm_mat,
  159.                                                      pform=perm_formula, ipform=invperm_formula,
  160.                                                      arrows=arrows_svg,
  161.                                                      cubenums=invperm_cube, pvect=perm_vector, ipvect=invperm_vector,
  162.                                                      bottomgray=bottomgray, topgray=topgray, beige=rectbeige)
  163.         # append to footer variables
  164.         footer_perm_formulas += '<g transform="translate(0, {y}) scale(.8, .8)">{f}</g>'.format(y=rectnum*24, f=perm_formula)
  165.         footer_perm_matrix += '<g transform="translate(0, {y})">{v}</g>'.format(y=rectnum*24, v=perm_vector)
  166.         footer_invperm_formulas += '<g transform="translate(0, {y}) scale(.8, .8)">{f}</g>'.format(y=rectnum*24, f=invperm_formula)
  167.         footer_invperm_matrix += '<g transform="translate(0, {y})">{v}</g>'.format(y=rectnum*24, v=invperm_vector)
  168.  
  169.     # create SVG
  170.     svg_string = svg_string_store.format(
  171.         rectangles=rectangles_svg,
  172.         pf=footer_perm_formulas,
  173.         pm=footer_perm_matrix,
  174.         ipf=footer_invperm_formulas,
  175.         ipm=footer_invperm_matrix,
  176.         bottombeige=bottombeige,
  177.         topbeige=topbeige
  178.     )
  179.  
  180.     svg_file = open(filename, 'w')
  181.     svg_file.write(svg_string)
Add Comment
Please, Sign In to add comment