Skip to article frontmatterSkip to article content

Rot2

A gtsam.Rot2 represents rotation in 2D space. It models a 2D rotation in the Special Orthogonal Group SO(2)\text{SO}(2).

Open In Colab

%pip install --quiet gtsam-develop
from gtsam import Rot2, Point2
import numpy as np

Initialization and properties

A Rot2 can be initialized with no arguments, which yields the identity rotation, or it can be constructed from an angle in radians, degrees, cos-sin form, or the bearing or arctangent of a 2D point. Rot2 uses radians to communicate angle by default.

# The identity rotation has theta = 0.
identity = Rot2()
print("Identities:")
print(identity.theta())
print(Rot2.Identity().theta())

# The constructor uses radians, so it is identical to Rot2.fromAngle(r).
rads = Rot2(np.pi / 2)
also_rads = Rot2.fromAngle(np.pi / 2)
print("Radians:")
print(rads.theta())
print(also_rads.theta())

# Rot2.fromDegrees(d) constructs from degrees.
degs = Rot2.fromDegrees(90)
print("Degrees:")
print(degs.theta())

# Rot2 can also be constructed using cosine and sine values, if you have them lying around.
c = np.cos(np.pi / 6)
s = np.sin(np.pi / 6)
cs = Rot2.fromCosSin(c, s)
print("Cos-Sin:")
print(cs.theta())

# Construct with bearing to point from theta = 0.
p = Point2(2, 2)
bear = Rot2.relativeBearing(p)
print("Bearing:")
print(bear.theta())
# Or with atan2(y, x), which accomplishes the same thing.
atan = Rot2.atan2(p[1], p[0])
print(atan.theta())
Identities:
0.0
0.0
Radians:
1.5707963267948966
1.5707963267948966
Degrees:
1.5707963267948966
Cos-Sin:
0.5235987755982988
Bearing:
0.7853981633974483
0.7853981633974483

The following properties are available from the standard interface:

  • theta() (in radians)
  • degrees()
  • c() (the cosine value, precalculated)
  • s() (the sine value, precalculated)
  • matrix() (the 2x2 rotation matrix: [cosθsinθsinθcosθ]\begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix})
example_rot = Rot2(3 * np.pi / 4)

# The default print statement includes 'theta: ' and a newline at the end.
print(example_rot)

print(f"Radians: {example_rot.theta()}")
print(f"Degrees: {example_rot.degrees()}")
print(f"Cosine: {example_rot.c()}")
print(f"Sine: {example_rot.s()}")
print(f"Matrix:\n{example_rot.matrix()}")
theta: 2.35619

Radians: 2.356194490192345
Degrees: 135.0
Cosine: -0.7071067811865475
Sine: 0.7071067811865476
Matrix:
[[-0.70710678 -0.70710678]
 [ 0.70710678 -0.70710678]]

Basic operations

For basic use, a Rot2 can rotate and unrotate a point.

rot = Rot2.fromDegrees(45)
p = Point2(-2, 2)

# Rotate the point at (-2, 2) 45 degrees to the -x axis.
rotated = rot.rotate(p)
print(f"Rotated: {rotated}")
# Perform the inverse rotation with unrotate()
print(f"Unrotated: {rot.unrotate(rotated)}")
# Of course, unrotating a point you didn't rotate just rotates it backwards.
print(f"Unrotated again: {rot.unrotate(p)}")
Rotated: [-2.82842712e+00  2.22044605e-16]
Unrotated: [-2.  2.]
Unrotated again: [-2.22044605e-16  2.82842712e+00]

Also, the equals() function allows for comparison of two Rot2 objects with a tolerance.

eq_rads = Rot2(np.pi / 4)
eq_degs = Rot2.fromDegrees(45)

print(eq_rads.equals(eq_degs, 1e-8))

# Direct comparison does not work for Rot2.
print(eq_rads == eq_degs)
True
False

Lie group SO(2)\text{SO}(2)

Group operations

Rot2 implements the group operations inverse, compose, between and identity. For more information on groups and their use here, see GTSAM concepts.

a = Rot2(np.pi / 6)
b = Rot2(np.pi / 3)

# The inverse of a Rot2 is just the negative of its angle.
print("Inverse:")
print(a.inverse())

# The composition of two Rot2 objects is their angles added together.
# The operator for compose is *, but make no mistake, this does not multiply the angles.
print("Compose:")
print(a * b)
print(a.compose(b))

# Between gives the difference between the two angles.
print("Between:")
print(a.between(b))

# The identity is theta = 0, as above.
print("Identity:")
print(Rot2.Identity())
Inverse:
theta: -0.523599

Compose:
theta: 1.5708

theta: 1.5708

Between:
theta: 0.523599

Identity:
theta: 0

Lie group operations

Rot2 implements the Lie group operations for exponential mapping and log mapping. For more information on Lie groups and their use here, see GTSAM concepts.

r = Rot2(np.pi / 2)
w = Rot2(np.pi / 4)
v = [np.pi / 2]

# The exponential map transforms a 1-dimensional vector representing an angle
# into its Rot2 equivalent.
print(Rot2.Expmap(v))
# The retract function takes the exponential map of the supplied 1D vector and
# composes it with the calling Rot2.
print(r.retract(v))

# The static log map transforms a Rot2 into its 1D vector equivalent.
print(Rot2.Logmap(r))
# The member log map transforms a Rot2 into its 1D vector equivalent relative to
# the Rot2 calling the function.
print(r.logmap(w))
# logmap is the same as calculating the coordinate of the second Rot2 in the
# local frame of the first, which localCoordinates (inherited from LieGroup) does.
print(r.localCoordinates(w))
theta: 1.5708

theta: 3.14159

[1.57079633]
[-0.78539816]
[-0.78539816]