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:
get_euler_pole_and_angle()
as a tuple of Euler pole and angle (radians), orget_lat_lon_euler_pole_and_angle_degrees()
as a tuple of Euler pole latitude and longitude and angle (all in degrees).
Multiplication operations can be used to rotate various geometry types:
Operation
Result
fr * vector
Rotates
Vector3D
vector using finite rotation frfr * point
Rotates
PointOnSphere
point using finite rotation frfr * multi_point
Rotates
MultiPointOnSphere
multi_point using finite rotation frfr * polyline
Rotates
PolylineOnSphere
polyline using finite rotation frfr * polygon
Rotates
PolygonOnSphere
polygon using finite rotation frfr * great_circle_arc
Rotates
GreatCircleArc
great_circle_arc using finite rotation frFor 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 adict
).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 anidentity
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
orLatLonPoint
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
orLatLonPoint
or tuple (latitude,longitude), in degrees, or tuple (x,y,z)- param to_point
the point to rotate to
- type to_point
PointOnSphere
orLatLonPoint
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)
See also
- __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.
[staticmethod] Create a finite rotation that rotates one point to another along the great circle arc connecting them.
[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.
[staticmethod] Create a finite rotation, using the specified rotation pole, that rotates from_point to to_point.
Return the (pole, angle) representing finite rotation.
Return the inverse of this finite rotation.
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.
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 rotationfinite_rotation2 (
FiniteRotation
) – the second finite rotationthreshold_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
finite_rotation1 (
FiniteRotation
) – the first finite rotationfinite_rotation2 (
FiniteRotation
) – the second finite rotation
- 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:
Negating a finite rotation’s Euler pole (making it antipodal) and negating its angle.
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).
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 rotationfinite_rotation2 (
FiniteRotation
) – the right-hand-side finite rotation
- Return type
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
orLatLonPoint
or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the point to rotate fromto_point (
PointOnSphere
orLatLonPoint
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
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
orLatLonPoint
or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the start point of the segment to rotate fromfrom_segment_end (
PointOnSphere
orLatLonPoint
or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the end point of the segment to rotate fromto_segment_start (
PointOnSphere
orLatLonPoint
or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the start point of the segment to rotate toto_segment_end (
PointOnSphere
orLatLonPoint
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
orLatLonPoint
or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the rotation pole to rotate aroundfrom_point (
PointOnSphere
orLatLonPoint
or tuple (latitude,longitude), in degrees, or tuple (x,y,z)) – the point to rotate fromto_point (
PointOnSphere
orLatLonPoint
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()
returnsTrue
then this method will return the north pole axis (and zero angle) if use_north_pole_for_identity isTrue
, 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
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()
returnsTrue
then this method will return the north pole axis (and zero angle) if use_north_pole_for_identity isTrue
, 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
orLatLonPoint
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 (seeEarth
).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 rotationfinite_rotation2 (
FiniteRotation
) – the right-hand-side finite rotationtime1 (float or
GeoTimeInstant
) – the time associated with the left-hand-side finite rotationtime2 (float or
GeoTimeInstant
) – the time associated with the right-hand-side finite rotationtarget_time (float or
GeoTimeInstant
) – the time associated with the result of the interpolation
- Return type
- Raises
InterpolationError if any time value is
distant past
ordistant 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())