#!/usr/bin/env python # coding: utf-8 # This is a supplementary material to the submission **Computing animations of linkages with rotational symmetry** # to *Computational Geometry: Media Exposition - Zürich, Switzerland - June 23-26, 2020* # by Sean Dewar, Georg Grasegger and Jan Legerský. # # The submission contains a video of rotationally symmetric motions of bar-and-joint frameworks and this notebook. # We illustrate how such motions can be created using ``SageMath`` package ``FlexRiLog`` (https://github.com/Legersky/flexrilog, https://doi.org/10.5281/zenodo.3078757 ). # # A cell is executed with ``Shift+Enter`` or pressing Run button. # In[ ]: import sys sys.path.insert(0, "..") #this is necessary if flexrilog is not installed, only downloaded from flexrilog import CnSymmetricFlexRiGraph, FlexRiGraph, GraphMotion, CnSymmetricNACcoloring # # A 5-fold rotationally symmetric graph # We consider the graph given by the following list of edges: # In[ ]: edges = [(0, 1), (0, 2), (0, 4), (0, 14), (1, 2), (1, 11), (1, 12), (1, 15), (1, 18), (1, 23), (1, 24), (2, 3), (2, 7), (3, 4), (3, 5), (3, 7), (4, 5), (4, 14), (4, 15), (4, 16), (4, 17), (4, 20), (5, 6), (5, 10), (6, 7), (6, 8), (6, 10), (7, 8), (7, 17), (7, 18), (7, 19), (7, 22), (8, 9), (8, 13), (9, 10), (9, 11), (9, 13), (10, 11), (10, 19), (10, 20), (10, 21), (10, 24), (11, 12), (12, 13), (12, 14), (13, 14), (13, 16), (13, 21), (13, 22), (13, 23), (15, 16), (15, 18), (16, 23), (17, 18), (17, 20), (19, 20), (19, 22), (21, 22), (21, 24), (23, 24)] G5 = Graph(edges); G5.plot() # The graph `G5` is $C_n$-symmetric for $n=5$: # In[ ]: omega5 = [[(0, 3, 6, 9, 12), (1, 4, 7, 10, 13), (2, 5, 8, 11, 14), (15, 17, 19, 21, 23), (16, 18, 20, 22, 24)]] G5 = CnSymmetricFlexRiGraph(G5, PermutationGroup(omega5), pos={ 0:[1,0], 1:[2.5,0], 2:[4,1.5], 15:[4,5], 16:[6,2] } ) G5.plot() # The graph `G5` has three $C_5$-symmetric NAC-colorings: # In[ ]: G5.show_all_NAC_colorings(ncols=1) # We consider the last NAC-coloring: # In[ ]: delta5 = G5.NAC_colorings()[-1] delta5.plot() # The construction in Theorem 2 yields a $C_5$-symmetric motion: # In[ ]: M5 = GraphMotion.CnSymmetricGridConstruction(G5, delta5) M5.animation_SVG(edge_partition='NAC', fileName='AnimationPentaRotation', totalTime=20, vertex_labels=False) # One can play with the choice of $a_i$'s and $b_j$'. There is only one orbit of red components and one orbit of blue components (and no partially invariant ones), so $a_i$'s and $b_j$' are determined each by one point: # In[ ]: M5ab = GraphMotion.CnSymmetricGridConstruction(G5, delta5, a_base=[[2,2]], # a different point can be chosen here b_base=[[1,0]] # or here ) M5ab.animation_SVG(edge_partition='NAC', fileName='AnimationPentaRotation_different_a_b', totalTime=20, vertex_labels=False) # # A 3-fold rotationally symmetric graph # We consider the graph given by the following list of edges: # In[ ]: edges3 = [(0, 1), (0, 2), (0, 3), (0, 4), (1, 2), (1, 5), (1, 6), (2, 7), (2, 8), (3, 4), (3, 9), (3, 10), (4, 11), (4, 12), (5, 6), (5, 7), (5, 13), (6, 14), (6, 15), (7, 8), (7, 13), (8, 16), (8, 17), (9, 10), (9, 14), (9, 18), (10, 12), (10, 20), (11, 12), (11, 16), (11, 19), (12, 20), (13, 21), (13, 22), (14, 15), (14, 18), (15, 23), (15, 24), (16, 17), (16, 19), (17, 25), (17, 26), (18, 23), (18, 27), (19, 25), (19, 28), (20, 29), (20, 30), (21, 22), (21, 24), (21, 31), (22, 26), (22, 32), (23, 24), (23, 27), (24, 31), (25, 26), (25, 28), (26, 32), (27, 29), (27, 33), (28, 30), (28, 34), (29, 30), (29, 33), (30, 34), (31, 32), (31, 35), (32, 35), (33, 34), (33, 35), (34, 35)] G3 = Graph(edges3); G3.plot() # The graph `G3` is $C_n$-symmetric for $n=3$: # In[ ]: omega3 = [[(0, 6, 9), (1, 14, 3), (2, 15, 10), (4, 5, 18), (7, 23, 12), (8, 24, 20), (13, 27, 11), (16, 21, 29), (19, 22, 33), (17, 31, 30), (25, 32, 34), (26, 35, 28)]] G3 = CnSymmetricFlexRiGraph(G3, PermutationGroup(omega3), pos={ 0:[5,7], 1:[4,0], 2:[7,5], 4:[6,-3], 7:[8,8], 8:[10,-2], 13:[12,12], 16:[14,5], 19:[14,-12], 17:[18,1], 25:[20,-5], 26:[22,3], } ) G3.plot() # The graph ``G3`` has 21 $C_3$-symmetric NAC-colorings: # In[ ]: print(len(G3.NAC_colorings())) # We pick this one: # In[ ]: delta3 = CnSymmetricNACcoloring(G3, [[{5, 7}, {26, 22}, {5, 13}, {1, 2}, {27, 23}, {18, 27}, {29, 30}, {24, 31}, {33, 35}, {9, 10}, {9, 3}, {13, 7}, {11, 4}, {10, 3}, {20, 30}, {32, 22}, {11, 12}, {24, 21}, {0, 2}, {33, 34}, {14, 15}, {20, 29}, {0, 1}, {21, 31}, {19, 28}, {4, 12}, {25, 28}, {18, 23}, {6, 15}, {8, 16}, {25, 19}, {34, 35}, {6, 14}, {8, 17}, {32, 26}, {16, 17}], [{17, 25}, {5, 6}, {1, 5}, {8, 2}, {33, 27}, {13, 22}, {18, 14}, {12, 20}, {8, 7}, {34, 28}, {35, 31}, {16, 19}, {3, 4}, {1, 6}, {13, 21}, {28, 30}, {10, 12}, {33, 29}, {9, 14}, {10, 20}, {0, 4}, {15, 23}, {25, 26}, {27, 29}, {32, 35}, {2, 7}, {16, 11}, {11, 19}, {32, 31}, {21, 22}, {34, 30}, {24, 23}, {9, 18}, {24, 15}, {17, 26}, {0, 3}]]) delta3.plot() # The construction in Theorem 2 yields a $C_3$-symmetric motion: # In[ ]: M3 = GraphMotion.CnSymmetricGridConstruction(G3, delta3) M3.animation_SVG(edge_partition='NAC', fileName='AnimationTruncatedOctahedralLineGraph_FlexRiLoG', totalTime=20, vertex_labels=False) # One can play with the choice of $a_i$'s and $b_j$'. There are four orbits of red components and four orbits of blue components (and no partially invariant ones), so $a_i$'s and $b_j$' are determined each by four points: # In[ ]: M3ab = GraphMotion.CnSymmetricGridConstruction(G3, delta3, a_base=[[0,1],[0,2],[3,0],[4,0]], # different points can be chosen here b_base=[[2,0], [3,1], [1,0], [4,0]] # or here ) M3ab.animation_SVG(edge_partition='NAC', fileName='AnimationTruncatedOctahedralLineGraph_FlexRiLoG_different_a_b', totalTime=20, vertex_labels=False) # Taking another NAC-coloring of ``G3``, we obtain a different motion: # In[ ]: delta3b = CnSymmetricNACcoloring(G3, [[{5, 7}, {17, 25}, {1, 2}, {27, 23}, {18, 27}, {33, 27}, {13, 22}, {34, 30}, {9, 10}, {5, 13}, {11, 12}, {13, 7}, {11, 4}, {35, 31}, {10, 3}, {16, 19}, {9, 3}, {17, 26}, {0, 2}, {13, 21}, {14, 15}, {0, 1}, {33, 29}, {4, 12}, {25, 26}, {27, 29}, {32, 35}, {18, 23}, {6, 15}, {16, 11}, {11, 19}, {32, 31}, {21, 22}, {34, 28}, {28, 30}, {6, 14}], [{26, 22}, {5, 6}, {1, 5}, {8, 2}, {9, 18}, {18, 14}, {20, 29}, {33, 35}, {29, 30}, {24, 31}, {12, 20}, {24, 23}, {20, 30}, {10, 20}, {32, 22}, {3, 4}, {24, 21}, {1, 6}, {33, 34}, {10, 12}, {9, 14}, {21, 31}, {19, 28}, {0, 4}, {15, 23}, {25, 28}, {0, 3}, {2, 7}, {8, 16}, {24, 15}, {25, 19}, {8, 7}, {34, 35}, {8, 17}, {32, 26}, {16, 17}] ]) M3anotherNAC = GraphMotion.CnSymmetricGridConstruction(G3, delta3b) M3anotherNAC.animation_SVG(edge_partition='NAC', fileName='AnimationTruncatedOctahedralLineGraph_FlexRiLoG_anotherNAC', totalTime=20, vertex_labels=False) # In[ ]: