Rotation and Symmetry
Module: cutoop.rotation
.
You can add CUTOOP_STRICT_MODE=1
to environment to enable a strict value assertion
before calculating rotation error.
SymLabel
Bases: object
Symmetry labels for real-world objects.
Axis rotation details:
- any : arbitrary rotation around this axis is ok
- half : rotate 180 degrees along this axis (central symmetry)
- quarter : rotate 90 degrees along this axis (like square)
>>> from cutoop.rotation import SymLabel
>>> sym = SymLabel(any=False, x='any', y='none', z='none')
>>> str(sym)
'x-cone'
>>> sym = SymLabel(any=False, x='any', y='any', z='none') # two any produces 'any'
>>> str(sym)
'any'
>>> sym = SymLabel(any=False, x='half', y='half', z='half')
>>> str(sym)
'box'
Whether arbitrary rotation is allowed
axis rotation for x
axis rotation for y
axis rotation for z
For human readability, rotations are divided into the following types (names):
any
: arbitrary rotation is ok;cube
: the same symmetry as a cube;box
: the same symmetry as a box (flipping along x, y, and z axis);none
: no symmetry is provided;{x,y,z}-flip
: flip along a single axis;{x,y,z}-square-tube
: the same symmetry as a square tube alone the axis;{x,y,z}-square-pyramid
: the same symmetry as a pyramid alone the axis;{x,y,z}-cylinder
: the same symmetry as a cylinder the axis;{x,y,z}-cone
: the same symmetry as a cone the axis.
Construct symmetry from string.
Note
See also STANDARD_SYMMETRY .
Get the only axis marked with the tag. If multiple or none is find, return None
.
Rotation Manipulation
Find the optimal rotation rot
that minimize theta(rA, rB @ rot)
.
Parameters:
- rA_3x3 – often the ground truth rotation.
- rB_3x3 – often the predicted rotation.
- sym – symmetry label.
- split – see rots_of_sym() .
- return_theta – if enabled, a tuple of the
rot
and its theta will both be returned.
Returns:
the optimal rot
Get a list of rotation group corresponding to the sym label.
Parameters:
split – Set the snap of rotation to 2 * pi / split
for continuous
symmetry.
Returns: ndarray of shape ?, 3, 3 containing a set of rotation matrix.
Rotation Error Computation
compute the difference angle where rotation aroud axis is ignored.
Parameters: axis – One of ax .
compute the difference angle (rotation error) with regard of symmetry.
This function use analytic method to calculate the difference angle, which is more accurate than rot_canonical_sym() .
Returns: the difference angle.
Compute the difference angle of one rotation with a series of rotations.
Note that since arccos gets quite steep around 0, the computational loss is somehow inevitable (around 1e-4).
Returns: theta (unit: radius) array of length N.
compute the difference angle of two sequences of rotations pointwisely.
Returns: theta (unit: radius) array of length N
Prelude Rotations
All standard symmetries.
>>> for name, sym in cutoop.rotation.STANDARD_SYMMETRY.items():
... assert str(sym) == name, f"name: {name}, sym: {repr(sym)}"
All 24 rotations of a cube (Sym(4)).
The correctness of this implementation lies in:
cube_flip_group
is a normal subgroup of alternating group- alternating group Alt(4) is a normal subgroup of Sym(4)
Thus we can construct Sym(4) by enumerating all cosets of Alt(4),
which is construct by enumerating all cosets of cube_flip_group
.
One can check validity of it by
>>> from cutoop.rotation import cube_group
>>> for i in range(24):
... for j in range(24):
... if i < j:
... diff = cube_group[i] @ cube_group[j].T
... assert np.linalg.norm(diff - np.eye(3)) > 0.1
All 4 rotations of a box, as 3x3 matrices. That is rotating 180 degrees around x y z, respectively (abelian group).
All transformations composed by 90-degree rotations along each axis.
Normalized axis vectors.
90-degree rotation along each axis.
flipping along each axis