Struct QuaternionWrapper

Source
pub struct QuaternionWrapper<T>(pub Quaternion<T>);

Tuple Fields§

§0: Quaternion<T>

Implementations§

Source§

impl<T: Float + FloatConst> QuaternionWrapper<T>

Source

pub fn new(q: Quaternion<T>) -> Self

Create a new Quaternion.

§Examples
let q = QuaternionWrapper::new( (1.0, [0.0; 3]) );
 
// Or it could be written like this
let q = QuaternionWrapper( (1.0, [0.0; 3]) );
Source

pub fn new_identity() -> Self

Create a new Identity Quaternion

§Examples
let q: QuaternionWrapper<f64> = QuaternionWrapper::new_identity();
 
let p: QuaternionWrapper<f64> = QuaternionWrapper::new((1.0, [0.0; 3]));
 
assert_eq!(q.unwrap(), p.unwrap());
Source

pub fn unwrap(self) -> Quaternion<T>

Returns the Quaternion<T>.

Source

pub fn get_scalar_part(self) -> ScalarWrapper<T>

Returns the scalar part of a quaternion.

Source

pub fn get_vector_part(self) -> Vector3Wrapper<T>

Returns the vector part of a quaternion.

Source

pub fn from_axis_angle(axis: Vector3<T>, angle: T) -> Self

Generate Versor by specifying rotation angle[rad] and axis vector.

The axis vector does not have to be a unit vector.

If you enter a zero vector, it returns an identity quaternion.

§Examples
// Generates a quaternion representing the
// rotation of π/2[rad] around the y-axis.
let q = QuaternionWrapper::from_axis_angle([0.0, 1.0, 0.0], PI/2.0);
 
// Rotate the point.
let r = q.point_rotation( Vector3Wrapper([2.0, 2.0, 0.0]) );
 
// Check if the calculation is correct.
let diff = Vector3Wrapper([0.0, 2.0, -2.0]) - r;
for val in diff.unwrap() {
    assert!( val.abs() < 1e-12 );
}
Source

pub fn from_dcm(m: DCM<T>) -> Self

Convert a DCM to a Versor representing the q v q* rotation (Point Rotation - Frame Fixed).

When convert to a DCM representing q* v q rotation (Frame Rotation - Point Fixed) to a Versor, do the following:

let q = QuaternionWrapper::from_dcm(dcm).conj();
§Examples
// Make these as you like.
let v = Vector3Wrapper([1.0, 0.5, -8.0]);
let q = QuaternionWrapper::from_axis_angle([0.2, 1.0, -2.0], PI/4.0);
 
// --- Point rotation --- //
{
    let m = q.to_dcm();
    let q_check = QuaternionWrapper::from_dcm(m);
     
    let diff = (q - q_check).unwrap();
    assert!( diff.0.abs() < 1e-12 );
    assert!( diff.1[0].abs() < 1e-12 );
    assert!( diff.1[1].abs() < 1e-12 );
    assert!( diff.1[2].abs() < 1e-12 );
}
 
// --- Frame rotation --- //
{
    let m = q.conj().to_dcm();
    let q_check = QuaternionWrapper::from_dcm(m).conj();
     
    let diff = (q - q_check).unwrap();
    assert!( diff.0.abs() < 1e-12 );
    assert!( diff.1[0].abs() < 1e-12 );
    assert!( diff.1[1].abs() < 1e-12 );
    assert!( diff.1[2].abs() < 1e-12 );
}
Source

pub fn from_euler_angles( rt: RotationType, rs: RotationSequence, angles: Vector3<T>, ) -> Self

Convert Euler angles to Versor.

The type of rotation (Intrinsic or Extrinsic) is specified by RotationType enum, and the rotation sequence (XZX, XYZ, …) is specified by RotationSequence enum.

Each element of angles should be specified in the range: [-2π, 2π].

Sequences: angles[0] —> angles[1] —> angles[2]

§Examples
use quaternion_core::{RotationType::*, RotationSequence::XYZ};
 
let angles = [PI/6.0, 1.6*PI, -PI/4.0];
let v = Vector3Wrapper([1.0, 0.5, -0.4]);
 
// Quaternions representing rotation around each axis.
let x = QuaternionWrapper::from_axis_angle([1.0, 0.0, 0.0], angles[0]);
let y = QuaternionWrapper::from_axis_angle([0.0, 1.0, 0.0], angles[1]);
let z = QuaternionWrapper::from_axis_angle([0.0, 0.0, 1.0], angles[2]);
 
// ---- Intrinsic (X-Y-Z) ---- //
// These represent the same rotation.
let q_in = x * y * z;
let e2q_in = QuaternionWrapper::from_euler_angles(Intrinsic, XYZ, angles);
// Confirmation
let a_in = q_in.point_rotation(v);
let b_in = e2q_in.point_rotation(v);
let diff_in = (a_in - b_in).unwrap();
assert!( diff_in[0].abs() < 1e-12 );
assert!( diff_in[1].abs() < 1e-12 );
assert!( diff_in[2].abs() < 1e-12 );
 
// ---- Extrinsic (X-Y-Z) ---- //
// These represent the same rotation.
let q_ex = z * y * x;
let e2q_ex = QuaternionWrapper::from_euler_angles(Extrinsic, XYZ, angles);
// Confirmation
let a_ex = q_ex.point_rotation(v);
let b_ex = e2q_ex.point_rotation(v);
let diff_ex = (a_ex - b_ex).unwrap();
assert!( diff_ex[0].abs() < 1e-12 );
assert!( diff_ex[1].abs() < 1e-12 );
assert!( diff_ex[2].abs() < 1e-12 );
Source

pub fn to_axis_angle(self) -> (Vector3Wrapper<T>, ScalarWrapper<T>)

Calculate the rotation axis (unit vector) and the rotation angle[rad] around the axis from the Versor.

If identity quaternion is entered, angle returns zero and the axis returns a zero vector.

Range of angle: (-π, π]

Source

pub fn to_dcm(self) -> DCM<T>

Convert a Versor to a DCM representing the q v q* rotation (Point Rotation - Frame Fixed).

When convert to a DCM representing the q* v q rotation (Frame Rotation - Point Fixed), do the following:

let dcm = q.conj().to_dcm();
§Examples
// Make these as you like.
let v = Vector3Wrapper([1.0, 0.5, -8.0]);
let q = QuaternionWrapper::from_axis_angle([0.2, 1.0, -2.0], PI/4.0);
 
// --- Point rotation --- //
{
    let m = q.to_dcm();
 
    let rm = v.matrix_product(m);
    let rq = q.point_rotation(v);
    let diff = (rm - rq).unwrap();
    assert!( diff[0].abs() < 1e-12 );
    assert!( diff[1].abs() < 1e-12 );
    assert!( diff[2].abs() < 1e-12 );
}
 
// --- Frame rotation --- //
{
    let m = q.conj().to_dcm();
 
    let rm = v.matrix_product(m);
    let rq = q.frame_rotation(v);
    let diff = (rm - rq).unwrap();
    assert!( diff[0].abs() < 1e-12 );
    assert!( diff[1].abs() < 1e-12 );
    assert!( diff[2].abs() < 1e-12 );
}
Source

pub fn to_euler_angles( self, rt: RotationType, rs: RotationSequence, ) -> Vector3Wrapper<T>

Convert Versor to Euler angles.

The type of rotation (Intrinsic or Extrinsic) is specified by RotationType enum, and the rotation sequence (XZX, XYZ, …) is specified by RotationSequence enum.

let angles = q.to_euler_angles(Intrinsic, XYZ);

Sequences: angles[0] —> angles[1] —> angles[2]

§Singularity
§RotationType::Intrinsic

For Proper Euler angles (ZXZ, XYX, YZY, ZYZ, XZX, YXY), the singularity is reached when the sine of the second rotation angle is 0 (angle = 0, ±π, …), and for Tait-Bryan angles (XYZ, YZX, ZXY, XZY, ZYX, YXZ), the singularity is reached when the cosine of the second rotation angle is 0 (angle = ±π/2).

At the singularity, the third rotation angle is set to 0[rad].

§RotationType::Extrinsic

As in the case of Intrinsic rotation, for Proper Euler angles, the singularity occurs when the sine of the second rotation angle is 0 (angle = 0, ±π, …), and for Tait-Bryan angles, the singularity occurs when the cosine of the second rotation angle is 0 (angle = ±π/2).

At the singularity, the first rotation angle is set to 0[rad].

§Examples

Depending on the rotation angle of each axis, it may not be possible to recover the same rotation angle as the original. However, they represent the same rotation in 3D space.

use quaternion_wrapper::{RotationType::*, RotationSequence::XYZ};
 
let angles = Vector3Wrapper([PI/6.0, PI/4.0, PI/3.0]);
 
// ---- Intrinsic (X-Y-Z) ---- //
let q_in = QuaternionWrapper::from_euler_angles(Intrinsic, XYZ, angles.unwrap());
let e_in = q_in.to_euler_angles(Intrinsic, XYZ);
let diff = (angles - e_in).unwrap();
assert!( diff[0].abs() < 1e-12 );
assert!( diff[1].abs() < 1e-12 );
assert!( diff[2].abs() < 1e-12 );
 
// ---- Extrinsic (X-Y-Z) ---- //
let q_ex = QuaternionWrapper::from_euler_angles(Extrinsic, XYZ, angles.unwrap());
let e_ex = q_ex.to_euler_angles(Extrinsic, XYZ);
let diff = (angles - e_ex).unwrap();
assert!( diff[0].abs() < 1e-12 );
assert!( diff[1].abs() < 1e-12 );
assert!( diff[2].abs() < 1e-12 );
Source

pub fn rotate_a_to_b(a: Vector3Wrapper<T>, b: Vector3Wrapper<T>) -> Option<Self>

Calculate the versor to rotate from vector a to vector b (Without singularity!).

This function calculates q satisfying b = q.point_rotation(a) when a.norm() = b.norm(). If a.norm() > 0 and b.norm() > 0, then q can be calculated with good accuracy no matter what the positional relationship between a and b is.

If you enter a zero vector either a or b, it returns None.

§Example
let a = Vector3Wrapper::<f64>::new([1.5, -0.5, 0.2]);
let b = Vector3Wrapper::<f64>::new([0.1, 0.6, 1.0]);
 
let q = QuaternionWrapper::rotate_a_to_b(a, b).unwrap();
let b_check = q.point_rotation(a);
 
let cross = b.cross(b_check).unwrap();
assert!( cross[0].abs() < 1e-12 );
assert!( cross[1].abs() < 1e-12 );
assert!( cross[2].abs() < 1e-12 );
Source

pub fn rotate_a_to_b_shortest( a: Vector3Wrapper<T>, b: Vector3Wrapper<T>, t: T, ) -> Option<Self>

Calculate the versor to rotate from vector a to vector b by the shortest path.

The parameter t adjusts the amount of movement from a to b. When t = 1, a moves completely to position b.

The algorithm used in this function is less accurate when a and b are parallel. Therefore, it is better to use the rotate_a_to_b(a, b) function when t = 1 and the rotation axis is not important.

If you enter a zero vector either a or b, it returns None.

Source

pub fn sum(self) -> ScalarWrapper<T>

Calculate the sum of each element of Quaternion.

§Examples
let q = QuaternionWrapper::<f64>::new( (1.0, [2.0, 3.0, 4.0]) );
 
assert!( (10.0 - q.sum().unwrap()).abs() < 1e-12 );
Source

pub fn scale_add(self, s: ScalarWrapper<T>, b: QuaternionWrapper<T>) -> Self

Calculate s*self + b

If the fma feature is enabled, the FMA calculation is performed using the mul_add method. If not enabled, it’s computed by unfused multiply-add (s*a + b).

Source

pub fn hadamard(self, other: QuaternionWrapper<T>) -> Self

Hadamard product of Quaternion.

Calculate self ∘ other

Source

pub fn hadamard_add( self, b: QuaternionWrapper<T>, c: QuaternionWrapper<T>, ) -> Self

Hadamard product and Addiction of Quaternion.

Calculate a ∘ b + c

If the fma feature is enabled, the FMA calculation is performed using the mul_add method. If not enabled, it’s computed by unfused multiply-add (s*a + b).

Source

pub fn dot(self, other: QuaternionWrapper<T>) -> ScalarWrapper<T>

Dot product of the quaternion.

Source

pub fn norm(self) -> ScalarWrapper<T>

Calcurate the L2 norm of the quaternion.

Source

pub fn normalize(self) -> Self

Normalization of quaternion.

§Examples
// This norm is not 1.
let q = QuaternionWrapper::<f64>::new( (1.0, [2.0, 3.0, 4.0]) );
assert!( (1.0 - q.norm().unwrap()).abs() > 1e-12 );
 
// Now that normalized, this norm is 1!
let q_n = q.normalize();
assert!( (1.0 - q_n.norm().unwrap()).abs() < 1e-12 );
Source

pub fn conj(self) -> Self

Returns the conjugate of quaternion.

Source

pub fn inv(self) -> Self

Calculate the inverse of quaternion.

§Examples
let q = QuaternionWrapper::<f64>::new( (1.0, [2.0, 3.0, 4.0]) );
 
// Identity quaternion
let id = (q * q.inv()).unwrap();  // = (q.inv() * q).unwrap()
 
assert!( (id.0 - 1.0).abs() < 1e-12 );
assert!( id.1[0].abs() < 1e-12 );
assert!( id.1[1].abs() < 1e-12 );
assert!( id.1[2].abs() < 1e-12 );
Source

pub fn exp(self) -> Self

Exponential function of quaternion

Source

pub fn ln(self) -> Self

Natural logarithm of quaternion.

Source

pub fn ln_versor(self) -> Vector3Wrapper<T>

Natural logarithm of versor.

If it is guaranteed to be a versor, it is less computationally expensive than the .ln() method.

Only the vector part is returned since the real part is always zero.

Source

pub fn pow(self, t: T) -> Self

Power function of quaternion.

Source

pub fn pow_versor(self, t: T) -> Self

Power function of versor.

If it is guaranteed to be a versor, it is less computationally expensive than the .pow() method.

Source

pub fn point_rotation(self, v: Vector3Wrapper<T>) -> Vector3Wrapper<T>

Rotation of vector (Point Rotation - Frame Fixed) Rotation of point (Point Rotation - Frame Fixed)

q v q* (||q|| = 1)

Since it is implemented with an optimized formula, it can be calculated with the amount of operations shown in the table below:

OperationNum
Multiply18
Add/Subtract12
§Example
// Make these as you like.
let v = Vector3Wrapper([1.0, 0.5, -8.0]);
let q = QuaternionWrapper::from_axis_angle([0.2, 1.0, -2.0], PI);
 
let r = q.point_rotation(v);
 
// This makes a lot of wasted calculations.
let r_check = (q * v * q.conj()).get_vector_part();
 
let diff = (r - r_check).unwrap();
assert!( diff[0].abs() < 1e-12 );
assert!( diff[1].abs() < 1e-12 );
assert!( diff[2].abs() < 1e-12 );
Source

pub fn frame_rotation(self, v: Vector3Wrapper<T>) -> Vector3Wrapper<T>

Rotation of frame (Frame Rotation - Point Fixed)

q* v q (||q|| = 1)

Since it is implemented with an optimized formula, it can be calculated with the amount of operations shown in the table below:

OperationNum
Multiply18
Add/Subtract12
§Example
// Make these as you like.
let v = Vector3Wrapper([1.0, 0.5, -8.0]);
let q = QuaternionWrapper::from_axis_angle([0.2, 1.0, -2.0], PI);
 
let r = q.frame_rotation(v);
 
// This makes a lot of wasted calculations.
let r_check = (q.conj() * v * q).get_vector_part();
 
let diff = (r - r_check).unwrap();
assert!( diff[0].abs() < 1e-12 );
assert!( diff[1].abs() < 1e-12 );
assert!( diff[2].abs() < 1e-12 );
Source

pub fn lerp(self, other: QuaternionWrapper<T>, t: T) -> Self

Lerp (Linear interpolation)

Generate a quaternion that interpolate the shortest path from self to other (The norm of self and other must be 1). The argument t (0 <= t <= 1) is the interpolation parameter.

Normalization is not performed internally because it increases the computational complexity.

Source

pub fn slerp(self, other: QuaternionWrapper<T>, t: T) -> Self

Slerp (Spherical linear interpolation)

Generate a quaternion that interpolate the shortest path from self to other. The argument t(0 <= t <= 1) is the interpolation parameter.

The norm of self and other must be 1 (Versor).

Trait Implementations§

Source§

impl<T: Float> Add<QuaternionWrapper<T>> for ScalarWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the + operator.
Source§

fn add(self, other: QuaternionWrapper<T>) -> QuaternionWrapper<T>

Performs the + operation. Read more
Source§

impl<T: Float> Add<QuaternionWrapper<T>> for Vector3Wrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the + operator.
Source§

fn add(self, other: QuaternionWrapper<T>) -> QuaternionWrapper<T>

Performs the + operation. Read more
Source§

impl<T: Float> Add<ScalarWrapper<T>> for QuaternionWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the + operator.
Source§

fn add(self, other: ScalarWrapper<T>) -> Self

Performs the + operation. Read more
Source§

impl<T: Float> Add<Vector3Wrapper<T>> for QuaternionWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the + operator.
Source§

fn add(self, other: Vector3Wrapper<T>) -> Self

Performs the + operation. Read more
Source§

impl<T: Float> Add for QuaternionWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the + operator.
Source§

fn add(self, other: QuaternionWrapper<T>) -> Self

Performs the + operation. Read more
Source§

impl<T: Float + Copy> AddAssign for QuaternionWrapper<T>

Source§

fn add_assign(&mut self, other: QuaternionWrapper<T>)

Performs the += operation. Read more
Source§

impl<T: Clone> Clone for QuaternionWrapper<T>

Source§

fn clone(&self) -> QuaternionWrapper<T>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T: Debug> Debug for QuaternionWrapper<T>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T: Float> Div<ScalarWrapper<T>> for QuaternionWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the / operator.
Source§

fn div(self, other: ScalarWrapper<T>) -> Self

Performs the / operation. Read more
Source§

impl<T: Float> Mul<QuaternionWrapper<T>> for ScalarWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the * operator.
Source§

fn mul(self, other: QuaternionWrapper<T>) -> QuaternionWrapper<T>

Performs the * operation. Read more
Source§

impl<T: Float> Mul<QuaternionWrapper<T>> for Vector3Wrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the * operator.
Source§

fn mul(self, other: QuaternionWrapper<T>) -> QuaternionWrapper<T>

Performs the * operation. Read more
Source§

impl<T: Float> Mul<ScalarWrapper<T>> for QuaternionWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the * operator.
Source§

fn mul(self, other: ScalarWrapper<T>) -> Self

Performs the * operation. Read more
Source§

impl<T: Float> Mul<Vector3Wrapper<T>> for QuaternionWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the * operator.
Source§

fn mul(self, other: Vector3Wrapper<T>) -> Self

Performs the * operation. Read more
Source§

impl<T: Float> Mul for QuaternionWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the * operator.
Source§

fn mul(self, other: QuaternionWrapper<T>) -> Self

Performs the * operation. Read more
Source§

impl<T: Float> MulAssign for QuaternionWrapper<T>

Source§

fn mul_assign(&mut self, other: QuaternionWrapper<T>)

Performs the *= operation. Read more
Source§

impl<T: Float> Neg for QuaternionWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the - operator.
Source§

fn neg(self) -> Self

Performs the unary - operation. Read more
Source§

impl<T: Float> Sub<QuaternionWrapper<T>> for ScalarWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the - operator.
Source§

fn sub(self, other: QuaternionWrapper<T>) -> QuaternionWrapper<T>

Performs the - operation. Read more
Source§

impl<T: Float> Sub<QuaternionWrapper<T>> for Vector3Wrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the - operator.
Source§

fn sub(self, other: QuaternionWrapper<T>) -> QuaternionWrapper<T>

Performs the - operation. Read more
Source§

impl<T: Float> Sub<ScalarWrapper<T>> for QuaternionWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the - operator.
Source§

fn sub(self, other: ScalarWrapper<T>) -> Self

Performs the - operation. Read more
Source§

impl<T: Float> Sub<Vector3Wrapper<T>> for QuaternionWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the - operator.
Source§

fn sub(self, other: Vector3Wrapper<T>) -> Self

Performs the - operation. Read more
Source§

impl<T: Float> Sub for QuaternionWrapper<T>

Source§

type Output = QuaternionWrapper<T>

The resulting type after applying the - operator.
Source§

fn sub(self, other: QuaternionWrapper<T>) -> Self

Performs the - operation. Read more
Source§

impl<T: Float + Copy> SubAssign for QuaternionWrapper<T>

Source§

fn sub_assign(&mut self, other: QuaternionWrapper<T>)

Performs the -= operation. Read more
Source§

impl<T: Copy> Copy for QuaternionWrapper<T>

Auto Trait Implementations§

§

impl<T> Freeze for QuaternionWrapper<T>
where T: Freeze,

§

impl<T> RefUnwindSafe for QuaternionWrapper<T>
where T: RefUnwindSafe,

§

impl<T> Send for QuaternionWrapper<T>
where T: Send,

§

impl<T> Sync for QuaternionWrapper<T>
where T: Sync,

§

impl<T> Unpin for QuaternionWrapper<T>
where T: Unpin,

§

impl<T> UnwindSafe for QuaternionWrapper<T>
where T: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.