Symmetry operations

How do you make two copies of a shape that are mirror images of each other, or three copies rotated 120&deg; around a point? If the shapes are not random then it is straight forward. If the shapes are random then each copy will be different. Symmetry operations allow exact duplication of the design with various translation, rotation, and reflection symmetry operations applied.

All or Nothing
The symmetry operations are applied to the whole design. Whatever is specified by your startshape will get the symmetry operations applied to it. But why not allow shape rules to specify symmetry operations for individual shape replacements? Because this would violate the context-free purity of Context Free/cfdg. There is no context-free grammar with separate parts that are random but identical. We get around this with symmetry operations by applying them to the entire design after the grammar is 'executed'. This is the same post-processing hack that is done with tiled rendering.

That said, there is still wiggle room if the design is explicitly impure (CF::Impure = 1). The clone statement allows designs to have localized symmetry.

=Two Dimensional Symmetry Operations= In two dimensions there are two symmetry operations: cyclic and dihedral. Cyclic symmetry is simply rotational symmetry, the design is rotated around a point. Dihedral symmetry adds mirror symmetry, so the design and its reflection are rotated around a point.

=One Dimensional Symmetry Operations= If your design has frieze symmetry then you can specify Frieze group symmetry: p11g, p11m, p1m1, p2, p2mg, and p2mm. Um, just go click that Wikipedia link to find out what those mean.

=Specifying Symmetry Operations= Symmetry operations are enabled by adding a CF::Symmetry configuration declaration and assigning it a list of symmetry specifications: A symmetry specification starts with the symmetry token (e.g., CF::Dihedral) followed by one or more configuration numbers, all separated by commas. There can be many symmetry specifications in the list, each separated by a comma. A shape adjustment can also be a symmetry specification.

Cyclic symmetry
Cyclic symmetry is specified with CF::Cyclic, followed the order and an optional center of rotation (one or three numbers). The order must be &ge;1.

Non-Integer Order
The order of cyclic symmetry need not be an integer. If the order is not an integer then it will be rounded down to determine how many copies of the design to draw. But the angle between them will be determined by the full value, not the rounded value. So if the order is 3.5 then 3 copies will be drawn at an angle of 360&deg;/3.5=102.86&deg;.

Be very careful with using an expression for symmetry order. If you intend to have four-fold symmetry but your order expression is 3.999999 then you will get 3 copies 89.99999&deg; apart. If your symmetry order is supposed to be an integer but it is not an integer constant then it is a good idea to round it to the nearest integer using the floor function.

Dihedral Symmetry
Dihedral symmetry is specified with CF::Dihedral, followed the order, an optional mirror angle and an optional center of rotation (one, two, three, or four numbers). The order must be &ge;1 and also need not be an integer.

CF::p11g, axis position &mdash; Step Symmetry
p11g symmetry is specified with CF::p11g, followed by the vertical or horizontal glide reflection axis position (one number). If the frieze symmetry is horizontal then the glide reflection axis is horizontal. Otherwise it is vertical. The axis position parameter is optional and defaults to 0.

CF::p11m, axis position &mdash; Jump Symmetry
p11m symmetry is specified with CF::p11m, followed by the vertical or horizontal mirror axis position (one number). If the frieze symmetry is horizontal then the mirror axis is horizontal. Otherwise it is vertical. The axis position parameter is optional and defaults to 0.

CF::p1m1, axis position &mdash; Sidle Symmetry
p1m1 symmetry is specified with CF::p1m1, followed by the vertical or horizontal mirror axis position (one number). If the frieze symmetry is horizontal then the mirror axis is vertical. Otherwise it is horizontal. The axis position parameter is optional and defaults to 0.

CF::p2, centre_x, centre_y &mdash; Spinning Hop Symmetry
p2 symmetry is specified with CF::p2, followed by the center of 180&deg; rotation (two numbers). The centre parameters are optional and default to (0,0).

CF::p2mg, centre_x, centre_y &mdash; Spinning Sidle Symmetry
p2mg symmetry is specified with CF::p2mg, followed by the center of 180&deg; rotation (two numbers). If the frieze symmetry is horizontal then the glide reflection axis is horizontal. Otherwise it is vertical. The centre parameters are optional and default to (0,0).

CF::p2mm, centre_x, centre_y &mdash; Spinning Jump Symmetry
p2mm symmetry is specified with CF::p2mm, followed by the center of 180&deg; rotation (two numbers). The centre parameters are optional and default to (0,0).

Wallpaper Group Symmetry
Designs with symmetry generated by one of the 17 Wallpaper groups can set CF::Symmetry and CF::Tile appropriately. All wallpaper group symmetries require that tiling be enabled. Most wallpaper groups have specific requirements for the symmetry of the tiling lattice, except for p1 and p2 group symmetry.

Groups with parallelogram tile: p1 and p2
Group p1 is implemented by setting the CF::Tile variable (skew is permitted), as the only elements of the symmetry group are translations.

Group p2, specified by setting the CF::Tile variable (as with p1) and setting CF::Symmetry to CF::p2. This gives the tiling a 180 degree rotation. Although it has the same symmetry name as the Frieze group p2 above, it differs from Frieze version in that the setting of the CF::Tile has definite width and height, and can be skewed.

CF::p2, centre_x, centre_y
The centre parameters in group p2 indicates the centre of the 2-fold rotation (the blue diamond). The centre parameters are optional and default to (0, 0).

Groups with arbitrary rectangular tile: pm, pg, pmm, pmg, pgg
Due to either having a reflection (mirror) or glide reflection (reflection plus translation parallel to the reflection axis) or a combination of two of these, the tile of these groups needs to be rectangular.

CF::pmg, mirror axis, centre_x, centre_y
The axis specification in groups pm, pg, and pmg indicate which axis (x, y, x=y, or x=-y) is the mirror axis (or glide axis for pg). The axis position parameter in groups pm and pg indicate the position of the mirror or glide axis. The axis position parameter is optional and defaults to 0. The centre parameters in groups pmm, pgg, and pmg indicate the point that the mirror and/or glide axes intersect. The centre parameters are optional and default to (0, 0).

45° Rotated Square Tiles
A diamond tile (see below) with 90° angles is considered a square tile and is thus also a rectangular tile. This tiling is eligible for the pm, pg, pmm, pgg, and pmg wallpaper groups. The x=y (axis 2) or x=-y (axis 3) axis specifications are used instead of the x or y axis (axis 0 and axis 1).

Groups with a diamond tile: cm, cmm
This figure illustrates a diamond tile, which is required for cm and cmm group symmetry:



The green rhombus indicates the unit cell of the diamond tile. However, Context Free only supports tiling lattices with at least one axis coincident with the x or y axis. So either the red or blue parallelogram must be used for the tiling lattice. The most straight-forward method for specifying this skewed tiling lattice is to use the six parameter form of the transform adjustment. For a diamond tile that is 3 units wide and 2 units high you would use one of these two: in general:

CF::cmm, centre_x, centre_y
The mirror axis specification in group cm indicates which axis (x, y, x=y, or x=-y) is the mirror axis. The axis position parameter in group cm indicates the position of mirror axis. The axis position parameter is optional and defaults to 0. The centre parameters in group cmm indicate the point that the mirror axes intersect. The centre parameters are optional and default to (0, 0).

45° Rotated Diamond Tiles
A plain square tiling grid can be considered to be a diamond tile that is rotated 45°. In this case the available mirror axes for cm group symmetry is x=y (axis 2) or x=-y (axis 3), instead of x or y. Wallpaper group cmm will also work on a plain square tiling grid: the mirror axes will be x=y and x=-y, instead of x and y.

Groups with a square tile: p4, p4m, p4g
As these groups have a 90&deg; centre of rotation, they require the tiling grid to be square.

CF::p4g, centre_x, centre_y
The centre parameters in groups p4, p4m, and p4g indicate the centre of the 4-fold rotation (the green squares). The centre parameters are optional and default to (0, 0).

45° Rotated Square Tiles
A diamond tile with 90° angles is considered a square tile and is eligible for the p4, p4m, and p4g wallpaper groups.

Groups with a hexagonal tile: p3, p3m1, p31m, p6, p6m
These symmetry groups require a tile that fits on a hexagonal grid. There are two permissible hexagonal grids in Context Free: horizontal and vertical.

CF::p6m, centre_x, centre_y
The centre parameters in groups p3, p3m1, and p31m indicate the centre of the 3-fold rotation (the red triangles). The centre parameters in groups p6 and p6m indicate the centre of the 6-fold rotation. The centre parameters are optional and default to (0, 0).

Shape Adjustments in CF::Symmetry
All of the symmetry specifications above are convenience functions for specifying the affine transforms for the one and two-dimensional symmetry groups. CF::Cyclic generates n transforms; CF::Dihedral generates 2n transforms, p11g, p11m, p1m1, and p2 generate 2 transforms; and p2mg and p2mm generate 4 transforms.

But affine transforms can be directly inserted into the symmetry transform list even if they are technically from symmetry groups: