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:
from
is a vector. The magnitude of the vector is ignored.to
is the destination vector forfrom
once the rotation has been applied. The magnitude of the vector is ignored.fix
is a blade to keep fixed during the rotation.angle
is the angle of the rotation in radians.
Any combination of these may be specified, subject to the following constraints:
from
andto
are mutually dependent; i.e., one cannot be specified without the other.- If
from
andto
are not specified, thenfix
andangle
are both required andfix
must be dual to a 2D plane. (1) from
andto
must not be opposite each other. (2)
If from
and to
are specified, then the rotation is constructed using these steps:
- If
fix
is specified, thenfrom
andto
are orthogonally rejected fromfix
. (3) - If
angle
is specified, thento
is minimally adjusted to have the angleangle
with respect tofrom
. from
andto
are normalized.- A rotation is constructed that takes
from
toto
along 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,
fix
must 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:
.ndim
is the number of dimensions of the space containing the transform.is_ident
istrue
if the transform is equivalent to the identity transform, orfalse
otherwise.is_refl
istrue
if the transform is equivalent to an odd number of reflections, orfalse
otherwise1.rev
is the reverse transform
Methods¶
Transforms have the following method:
:transform(object)
returns the object transformed according to the transform:transform_oriented(transform2)
returnstransform2
transformed 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 == 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_refl
isfalse
in those dimensions. ↩