Transform¶
A transform is a combination of some sequence of translations, rotations, and reflections in space. Hyperspeedcube uses motors from the Projective Geometric Algebra, but knowledge of geometric algebra is not required in order to use the API effectively.
The examples on this page assume 3D, but the same API works in other dimensions.
Why not matrices?¶
Although transforms are commonly represented using matrices, motors provide a few advantages:
- Fewer numbers to store (below 6D)
- Good for interpolation
- Can distinguish between 180-degree rotations in opposite directions, which is good for displaying correct animations
Constructors¶
All these constructors return a transform with the number of dimensions of the currently active space, and therefore can only be called in a context with a global number of dimensions (such as during the construction of a puzzle). They produce an error if it is called when there is not a global number of dimensions.
ident()¶
ident() constructs the identity transformation. It takes no arguments.
refl()¶
refl() constructs a transform representing a reflection or point reflection and can be called in any of several ways:
- No arguments. Calling
refl()with no arguments constructs a point reflection across the origin. - Point. Calling
refl()with a point constructs a point reflection across that point. For example,refl(point(0, -2))constructs a point reflection across the point \(\langle 0, -2, 0 \rangle\). - Vector. Calling
refl()with a vector constructs a reflection through that vector. The magnitude of the vector is ignored. For example,refl(point(0, -2))constructs a reflection across the plane \(y=0\). - Hyperplane. Calling
refl()with a hyperplane constructs a reflection across that hyperplane. The orientation of the plane is ignored. For example,refl(plane('z', 1/2))constructs a reflection across the plane \(z = 0.5\).
rot()¶
rot() constructs a transform representing a rotation fixing the origin and takes several named arguments as values in a table:
fromis a vector. The magnitude of the vector is ignored.tois the destination vector forfromonce the rotation has been applied. The magnitude of the vector is ignored.fixis a blade to keep fixed during the rotation.angleis the angle of the rotation in radians.
Any combination of these may be specified, subject to the following constraints:
fromandtoare mutually dependent; i.e., one cannot be specified without the other.- If
fromandtoare not specified, thenfixandangleare both required andfixmust be dual to a 2D plane. (1) fromandtomust not be opposite each other. (2)
If from and to are specified, then the rotation is constructed using these steps:
- If
fixis specified, thenfromandtoare orthogonally rejected fromfix. (3) - If
angleis specified, thentois minimally adjusted to have the angleanglewith respect tofrom. fromandtoare normalized.- A rotation is constructed that takes
fromtotoalong the shortest path.
If from and to are not specified, then a rotation of angle around fix is constructed. This method is not recommended because the direction of the rotation is unspecified and may change depending on the sign of fix.
- This is possible with antigrade 3 (if its bulk is zero) or antigrade 2 (if its bulk is nonzero). For example, in 3D,
fixmust be one of the following: - There are many 180-degree rotations that take any given vector to its opposite, so this case is disallowed due to ambiguity.
- This results in the component of each vector that is perpendicular to
fix.
-- 45-degree rotation in the XY plane
rot{from = 'x', to = vec(1, 1, 0)}
-- 180-degree rotation around the Z axis
rot{fix = 'z', angle = pi}
-- Jumbling rotation of the Curvy Copter puzzle
rot{fix = vec(1, 1, 0), angle = acos(1/3)}
-- 90-degree rotation around an edge of a cube
rot{fix = vec(1, 1, 0), from = 'x', to = 'z'}
Fields¶
Transforms have the following fields:
.ndimis the number of dimensions of the space containing the transform.is_identistrueif the transform is equivalent to the identity transform, orfalseotherwise.is_reflistrueif the transform is equivalent to an odd number of reflections, orfalseotherwise1.revis the reverse transform
Methods¶
Transforms have the following method:
:transform(object)returns the object transformed according to the transform:transform_oriented(transform2)returnstransform2transformed according to the transform, but reversed it if it was mirrored
Below is a list of all types that can be transformed:
Operations¶
Transforms support the following operations:
transform * transform(composition of transforms)transform ^ int(integer power of transform)transform == transform(uses approximate floating-point comparison)transform ~= transform(uses approximate floating-point comparison)type(transform)returns'transform'tostring(transform)
-
Note that in an even number of dimensions (2D, 4D, etc.) a point reflection contains an even number of reflections, so
refl().is_reflisfalsein those dimensions. ↩