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 [ ]: