pygplates.FiniteRotation

class pygplates.FiniteRotation

Bases: Boost.Python.instance

Represents the motion of plates on the surface of the globe.

Note

For general information on composing finite rotations in various plate tectonic scenarios see Working with finite rotations.

A finite rotation is a rotation about an Euler pole by an angular distance. An Euler pole is represented by a point on the surface of the globe where a rotation vector (radially extending from the centre of the globe) intersects the surface of the (unit radius) globe.

An Euler pole is specified by a point on the surface of the globe.

A rotation angle is specified in radians, with the usual sense of rotation:

  • a positive angle represents an anti-clockwise rotation around the rotation vector,

  • a negative angle corresponds to a clockwise rotation.

A finite rotation can be created:

  • explicitly from an Euler pole and an angle, or

  • from two points (rotates one point to the other along great circle arc), or

  • as an identity rotation (no rotation).

The Euler pole and angle can be retrieved using:

Multiplication operations can be used to rotate various geometry types:

Operation

Result

fr * vector

Rotates Vector3D vector using finite rotation fr

fr * point

Rotates PointOnSphere point using finite rotation fr

fr * multi_point

Rotates MultiPointOnSphere multi_point using finite rotation fr

fr * polyline

Rotates PolylineOnSphere polyline using finite rotation fr

fr * polygon

Rotates PolygonOnSphere polygon using finite rotation fr

fr * great_circle_arc

Rotates GreatCircleArc great_circle_arc using finite rotation fr

For example, the rotation of a PolylineOnSphere:

polyline = pygplates.PolylineOnSphere(...)
finite_rotation = pygplates.FiniteRotation(pole, angle)
rotated_polyline = finite_rotation * polyline

The distance that a point is rotated along its small circle rotation arc can be found using get_rotation_distance().

Two finite rotations can be composed in either of the following equivalent ways:

  • composed_finite_rotation = finite_rotation1 * finite_rotation2

  • composed_finite_rotation = pygplates.FiniteRotation.compose(finite_rotation1, finite_rotation2)

The latter technique uses compose(). Note that rotation composition is not commutative (\(A \times B \neq B \times A\)).

The reverse, or inverse, of a finite rotation can be found using get_inverse().

Two finite rotations can be interpolated using interpolate():

interpolated_rotation = pygplates.FiniteRotation.interpolate(finite_rotation1, finite_rotation2, time1, time2, target_time)

Finite rotations are equality (==, !=) comparable (but not hashable - cannot be used as a key in a dict).

Finite rotations can also be compared using are_equivalent() to detect equivalent rotations (that rotate a geometry to the same final position but might rotate in opposite directions around the globe). A finite rotation can be tested to see if it is an identity rotation (no rotation).

__init__(...)

A FiniteRotation object can be constructed in more than one way…

__init__(pole, angle_radians)

Create a finite rotation from an Euler pole and a rotation angle (in radians).

param pole

the Euler pole.

type pole

PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)

param angle_radians

the rotation angle (in radians).

type angle_radians

float

raises

InvalidLatLonError if latitude or longitude is invalid

raises

ViolatedUnitVectorInvariantError if (x,y,z) is not unit magnitude

The following example shows a few different ways to use this method:

finite_rotation = pygplates.FiniteRotation(pygplates.PointOnSphere(x,y,z), angle_radians)
finite_rotation = pygplates.FiniteRotation((x,y,z), math.radians(angle_degrees))
finite_rotation = pygplates.FiniteRotation([x,y,z], angle_radians)
finite_rotation = pygplates.FiniteRotation(numpy.array([x,y,z]), angle_radians)
finite_rotation = pygplates.FiniteRotation(pygplates.LatLonPoint(latitude,longitude), angle_radians)
finite_rotation = pygplates.FiniteRotation((latitude,longitude), angle_radians)
finite_rotation = pygplates.FiniteRotation([latitude,longitude], math.radians(angle_degrees))
finite_rotation = pygplates.FiniteRotation(numpy.array([latitude,longitude]), angle_radians)
__init__(from_point, to_point)

Create a finite rotation that rotates one point to another along the great circle arc connecting them.

param from_point

the point to rotate from

type from_point

PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)

param to_point

the point to rotate to

type to_point

PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)

raises

InvalidLatLonError if latitude or longitude is invalid

raises

ViolatedUnitVectorInvariantError if (x,y,z) is not unit magnitude

If from_point and to_point are the same or antipodal (opposite sides of globe) then an arbitrary rotation axis (among the infinite possible choices) is selected.

finite_rotation = pygplates.FiniteRotation(from_point, to_point)
# assert(to_point == finite_rotation * from_point)
__init__()

Creates a finite rotation that does not rotate (it maps a vector onto the same vector).

Equivalent to create_identity_rotation().

identity_finite_rotation = pygplates.FiniteRotation()

Methods

__init__(...)

A FiniteRotation object can be constructed in more than one way...

are_equal(finite_rotation1, ...)

[staticmethod] Return whether two finite rotations have equal pole latitude, longitude and angle to within a threshold in degrees.

are_equivalent(finite_rotation1, ...)

[staticmethod] Return whether two finite rotations represent equivalent rotations.

compose(finite_rotation1, finite_rotation2)

[staticmethod] Composes two finite rotations and returns the composed finite rotation.

create_great_circle_point_rotation(...)

[staticmethod] Create a finite rotation that rotates one point to another along the great circle arc connecting them.

create_identity_rotation()

[staticmethod] Creates a finite rotation that does not rotate (it maps a vector onto the same vector).

create_segment_rotation(from_segment_start, ...)

[staticmethod] Create a finite rotation that rotates the from line segment to the to line segment.

create_small_circle_point_rotation(...)

[staticmethod] Create a finite rotation, using the specified rotation pole, that rotates from_point to to_point.

get_euler_pole_and_angle(...)

Return the (pole, angle) representing finite rotation.

get_inverse()

Return the inverse of this finite rotation.

get_lat_lon_euler_pole_and_angle_degrees(...)

Return the finite rotation as a tuple of pole latitude, pole longitude and angle (all in degrees).

get_rotation_distance(point)

Return the distance that a point rotates along its small circle rotation arc (in radians).

interpolate(finite_rotation1, ...)

[staticmethod] Calculate the finite rotation which is the interpolation of two finite rotations.

represents_identity_rotation()

Return whether this finite rotation represents an identity rotation (a rotation which maps a vector onto the same vector).

static are_equal(finite_rotation1, finite_rotation2[, threshold_degrees])

[staticmethod] Return whether two finite rotations have equal pole latitude, longitude and angle to within a threshold in degrees.

Parameters
  • finite_rotation1 (FiniteRotation) – the first finite rotation

  • finite_rotation2 (FiniteRotation) – the second finite rotation

  • threshold_degrees (float) – optional closeness threshold in degrees

Return type

bool

If threshold_degrees is not specified then this function is the same as equality comparison (==).

If threshold_degrees is specified then finite_rotation1 and finite_rotation2 compare equal if both pole latitudes and both pole longitudes and both angles are within threshold_degrees degrees of each other.

Using a threshold in latitude/longitude coordinates is subject to longitude compression at the North and South poles. However these coordinates are useful when comparing finite rotations loaded from a text file that stores rotations using these coordinates (such as PLATES rotation format) and that typically stores values with limited precision.

# Are two finite rotations equal to within 0.01 degrees.
# This is useful when the rotations were loaded from a PLATES rotation file
# that stored rotation lat/lon/angle to 2 decimal places accuracy.
if pygplates.FiniteRotation.are_equal(finite_rotation1, finite_rotation2, 0.01):
    ....
static are_equivalent(finite_rotation1, finite_rotation2)

[staticmethod] Return whether two finite rotations represent equivalent rotations.

Parameters
Return type

bool

Two rotations are equivalent if they rotate a geometry to the same final location. This includes rotating in opposite directions around the globe.

Some examples of equivalent rotations:

  1. Negating a finite rotation’s Euler pole (making it antipodal) and negating its angle.

  2. Negating a finite rotation’s Euler pole (making it antipodal) and setting its angle to ‘360 - angle’ degrees (making the rotation go the other way around the globe).

  3. Setting a finite rotation’s angle to ‘angle - 360’ degrees (making the rotation go the other way around the globe).

Note that in (1) the finite rotations also compare equal (==), even though they were created with a different pole/angle, whereas in (2) and (3) the finite rotations compare unequal (!=). This is because (1) generates the exact same rotation whereas (2) and (3) generate rotations that go the opposite direction around the globe. Note however that all three rotations are still equivalent.

if pygplates.FiniteRotation.are_equivalent(finite_rotation1, finite_rotation2):
    ....
static compose(finite_rotation1, finite_rotation2)

[staticmethod] Composes two finite rotations and returns the composed finite rotation.

Parameters
  • finite_rotation1 (FiniteRotation) – the left-hand-side finite rotation

  • finite_rotation2 (FiniteRotation) – the right-hand-side finite rotation

Return type

FiniteRotation

This method does the same as finite_rotation1 * finite_rotation2.

See Working with finite rotations for more details on composing finite rotations.

composed_rotation = pygplates.FiniteRotation.compose(finite_rotation1, finite_rotation2)
#...or...
composed_rotation = finite_rotation1 * finite_rotation2
static create_great_circle_point_rotation(from_point, to_point)

[staticmethod] Create a finite rotation that rotates one point to another along the great circle arc connecting them.

Parameters
  • from_point (PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the point to rotate from

  • to_point (PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the point to rotate to

Raises

InvalidLatLonError if latitude or longitude is invalid

Raises

ViolatedUnitVectorInvariantError if (x,y,z) is not unit magnitude

If from_point and to_point are the same or antipodal (opposite sides of globe) then an arbitrary rotation axis (among the infinite possible choices) is selected.

finite_rotation = pygplates.FiniteRotation.create_great_circle_point_rotation(from_point, to_point)
# assert(to_point == finite_rotation * from_point)

New in version 0.29.

static create_identity_rotation()

[staticmethod] Creates a finite rotation that does not rotate (it maps a vector onto the same vector).

Return type

FiniteRotation

To determine if a finite rotation is an identity rotation use represents_identity_rotation().

identity_finite_rotation = pygplates.FiniteRotation.create_identity_rotation()
# assert(identity_finite_rotation.represents_identity_rotation())

# The rotated point and original point are at the same position.
rotated_point = identity_finite_rotation * point

An alternative way to create an identity rotation is with any Euler pole and a zero angle:

identity_finite_rotation = pygplates.FiniteRotation(any_euler_pole, 0)
static create_segment_rotation(from_segment_start, from_segment_end, to_segment_start, to_segment_end)

[staticmethod] Create a finite rotation that rotates the from line segment to the to line segment.

Parameters
  • from_segment_start (PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the start point of the segment to rotate from

  • from_segment_end (PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the end point of the segment to rotate from

  • to_segment_start (PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the start point of the segment to rotate to

  • to_segment_end (PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the end point of the segment to rotate to

Raises

InvalidLatLonError if latitude or longitude is invalid

Raises

ViolatedUnitVectorInvariantError if (x,y,z) is not unit magnitude

This is useful if you have the same geometry but at two different positions/orientations on the globe and you want to determine the rotation that maps one onto the other. In this case you can choose two non-coincident points of the geometry (at two different positions/orientations) and pass those four points to this function. For example, you might have a geometry that’s been reconstructed to two different times but you don’t have those two reconstruction rotations (you only have the two reconstructed geometries) - you can then use this function to find the rotation from one reconstruction time to the other.

finite_rotation = pygplates.FiniteRotation.create_segment_rotation(
    from_segment_start, from_segment_end,
    to_segment_start, to_segment_end)

Note

The from and to segments do not actually have to be the same (arc) length. In this case, while from_segment_start is always rotated onto to_segment_start, from_segment_end is not rotated onto to_segment_end. Instead from_segment_end is rotated such that it is on the great circle containing the to segment. In this way the from segment is rotated such that its orientation matches the to segment (as well as having matching start points).

Note

If either segment is zero length then the returned rotation reduces to one that rotates from_segment_start to to_segment_start along the great circle arc between those two points. This is because one (or both) segments has no orientation (so all we can match are the start points).

Note

It’s fine for the start points of both from and to segments to coincide (and it’s also fine for the end points of both segments to coincide for that matter).

New in version 0.29.

static create_small_circle_point_rotation(rotation_pole, from_point, to_point)

[staticmethod] Create a finite rotation, using the specified rotation pole, that rotates from_point to to_point.

Parameters
  • rotation_pole (PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the rotation pole to rotate around

  • from_point (PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the point to rotate from

  • to_point (PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the point to rotate to

Raises

InvalidLatLonError if latitude or longitude is invalid

Raises

ViolatedUnitVectorInvariantError if (x,y,z) is not unit magnitude

Note

from_point doesn’t actually have to rotate onto to_point. Imagine rotation_pole is the North Pole, then the returned rotation will rotate such that the longitude matches but not necessarily the latitude.

Note

If either from_point or to_point coincides with rotation_pole then the identity rotation is returned.

finite_rotation = pygplates.FiniteRotation.create_small_circle_point_rotation(rotation_pole, from_point, to_point)

New in version 0.29.

get_euler_pole_and_angle([use_north_pole_for_identity=True])

Return the (pole, angle) representing finite rotation.

Note

The returned angle is in radians.

Parameters

use_north_pole_for_identity (bool) – whether to return the north pole axis (and zero angle) for an identity rotation or raise IndeterminateResultError (default is to return north pole axis)

Returns

the tuple of (pole, angle_radians)

Return type

tuple (PointOnSphere, float)

Raises

IndeterminateResultError if use_north_pole_for_identity is False and this finite rotation represents the identity rotation

If represents_identity_rotation() returns True then this method will return the north pole axis (and zero angle) if use_north_pole_for_identity is True, otherwise IndeterminateResultError is raised.

Alternatively get_lat_lon_euler_pole_and_angle_degrees() can be used to return the euler pole as latitude/longitude and angle (all in degrees).

Note that (pole, angle) and (-pole, -angle) represent equivalent rotations (see are_equivalent()) and either could be returned. However, if this finite rotation was created with __init__(pole, angle) then the same pole and angle will be returned here.

finite_rotation = pygplates.FiniteRotation(pole, angle_radians)
pole, angle_radians = finite_rotation.get_euler_pole_and_angle()
get_inverse()

Return the inverse of this finite rotation.

Return type

FiniteRotation

The inverse represents the reverse rotation as the following code demonstrates:

rotated_point = finite_rotation * point
original_point = finite_rotation.get_inverse() * rotated_point
get_lat_lon_euler_pole_and_angle_degrees([use_north_pole_for_identity=True])

Return the finite rotation as a tuple of pole latitude, pole longitude and angle (all in degrees).

Note

The returned angle is in degrees (as are the latitude and longitude).

Parameters

use_north_pole_for_identity (bool) – whether to return the north pole axis (and zero angle) for an identity rotation or raise IndeterminateResultError (default is to return north pole axis)

Returns

the tuple of (pole_latitude, pole_longitude, angle_degrees) all in degrees

Return type

tuple (float, float, float)

Raises

IndeterminateResultError if use_north_pole_for_identity is False and this finite rotation represents the identity rotation

If represents_identity_rotation() returns True then this method will return the north pole axis (and zero angle) if use_north_pole_for_identity is True, otherwise IndeterminateResultError is raised.

Note that (latitude, longitude, angle) and (-latitude, longitude-180, -angle) represent equivalent rotations (see are_equivalent()) and either could be returned. However, if this finite rotation was created with __init__(pole, angle) then the same pole and angle will be returned here.

finite_rotation = pygplates.FiniteRotation(pole, angle_radians)
pole_latitude, pole_longitude, angle_degrees = finite_rotation.get_lat_lon_euler_pole_and_angle_degrees()
get_rotation_distance(point)

Return the distance that a point rotates along its small circle rotation arc (in radians).

Parameters

point (PointOnSphere or LatLonPoint or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the point being rotated (the start point of the rotation arc)

Return type

float

Returns the distance along the (small circle) rotation arc from the start point point to the end point finite_rotation * point. Note that the returned distance is not the angle of rotation - it is the actual distance on the unit radius sphere (hence radians). To convert to distance on the Earth’s surface multiply by the Earth radius (see Earth).

rotated_distance_radians = finite_rotation.get_rotation_distance(point)
static interpolate(finite_rotation1, finite_rotation2, time1, time2, target_time)

[staticmethod] Calculate the finite rotation which is the interpolation of two finite rotations.

Parameters
  • finite_rotation1 (FiniteRotation) – the left-hand-side finite rotation

  • finite_rotation2 (FiniteRotation) – the right-hand-side finite rotation

  • time1 (float or GeoTimeInstant) – the time associated with the left-hand-side finite rotation

  • time2 (float or GeoTimeInstant) – the time associated with the right-hand-side finite rotation

  • target_time (float or GeoTimeInstant) – the time associated with the result of the interpolation

Return type

FiniteRotation

Raises

InterpolationError if any time value is distant past or distant future

The finite rotations finite_rotation1 and finite_rotation2 are associated with times time1 and time2, respectively. The result of the interpolation is associated with target_time. The interpolated finite rotation is generated using Spherical Linear intERPolation (SLERP) with the interpolation factor (target_time - time1) / (time2 - time1).

target_time can be any time - it does not have to be between time1 and time2.

If time1 and time2 are equal then finite_rotation1 is returned.

interpolated_rotation = pygplates.FiniteRotation.interpolate(finite_rotation1, finite_rotation2, time1, time2, target_time)
represents_identity_rotation()

Return whether this finite rotation represents an identity rotation (a rotation which maps a vector onto the same vector).

Return type

bool

# Create an identity rotation using zero angle and any pole location.
identity_finite_rotation = pygplates.FiniteRotation(any_pole, 0)
# assert(identity_finite_rotation.represents_identity_rotation())