///|
/// Generates a list of translation/rotation matrices for cyclic symmetry Cn
pub fn cyclic_symmetries(n : Int, cx : Double, cy : Double) -> Array[Matrix2D] {
let list = []
let step = 2.0 * @math.PI / n.to_double()
for i in 0.. Array[Matrix2D] {
let list = []
let step = 2.0 * @math.PI / n.to_double()
for i in 0.. Array[Matrix2D] {
let list = []
let cx = w / 2.0
let cy = h / 2.0
let ident = Matrix2D::identity()
let refl_x = Matrix2D::reflect(0.0) // y' = -y
// Translate to cell center, reflect, translate back
let cell_refl_x = Matrix2D::translate(cx, cy)
.multiply(refl_x)
.multiply(Matrix2D::translate(-cx, -cy))
let cell_refl_y = Matrix2D::translate(cx, cy)
.multiply(Matrix2D::reflect(@math.PI / 2.0)) // x' = -x
.multiply(Matrix2D::translate(-cx, -cy))
match group_name {
"p1" => list.push(ident)
"p2" => {
list.push(ident)
list.push(
Matrix2D::translate(cx, cy)
.multiply(Matrix2D::rotate(@math.PI))
.multiply(Matrix2D::translate(-cx, -cy)),
)
}
"pm" => {
list.push(ident)
list.push(cell_refl_x)
}
"pmm" => {
list.push(ident)
list.push(cell_refl_x)
list.push(cell_refl_y)
list.push(cell_refl_x.multiply(cell_refl_y))
}
"p4" =>
for i in 0..<=3 {
let angle = i.to_double() * (@math.PI / 2.0)
let r = Matrix2D::translate(cx, cy)
.multiply(Matrix2D::rotate(angle))
.multiply(Matrix2D::translate(-cx, -cy))
list.push(r)
}
"p4m" =>
for i in 0..<=3 {
let angle = i.to_double() * (@math.PI / 2.0)
let r = Matrix2D::translate(cx, cy)
.multiply(Matrix2D::rotate(angle))
.multiply(Matrix2D::translate(-cx, -cy))
list.push(r)
list.push(r.multiply(cell_refl_x))
}
"p6" =>
for i in 0..<=5 {
let angle = i.to_double() * (@math.PI / 3.0)
let r = Matrix2D::translate(cx, cy)
.multiply(Matrix2D::rotate(angle))
.multiply(Matrix2D::translate(-cx, -cy))
list.push(r)
}
"p6m" =>
for i in 0..<=5 {
let angle = i.to_double() * (@math.PI / 3.0)
let r = Matrix2D::translate(cx, cy)
.multiply(Matrix2D::rotate(angle))
.multiply(Matrix2D::translate(-cx, -cy))
list.push(r)
list.push(r.multiply(cell_refl_x))
}
_ => list.push(ident) // fallback to p1
}
list
}
///|
/// Generates a full tiled layout of matrices for the given wallpaper group
pub fn generate_wallpaper_transforms(
group_name : String,
width : Double,
height : Double,
cell_w : Double,
cell_h : Double,
) -> Array[Matrix2D] {
let list = []
let cell_syms = wallpaper_cell_symmetries(group_name, cell_w, cell_h)
let cols = (width / cell_w).ceil().to_int() + 1
let rows = (height / cell_h).ceil().to_int() + 1
let start_r = -1
let start_c = -1
for r in start_r..