pub struct Pose<T: Number = Scalar> { /* private fields */ }Expand description
A rigid motion — where a body sits: a point p of it is at
R p + position, with R the rotation of a quaternion, which need not
be unit (see Pose::apply) — in the
number type T. Held as the two themselves, so that what is stored is
exactly what was set, and a pose read and written again is written
exactly as it was read.
Serialized as {"position": [x, y, z], "rotation": [w, x, y, z]}, each
number its value’s midpoint; a rotation read is kept as read, sharp —
a hair off unit as a midpoint is, as a solver’s step leaves one too —
so that reading what was written gives back what was read before
(see Pose::saved). Angles are
for showing a pose to people only (Pose::euler_degrees,
Pose::from_euler).
Implementations§
Source§impl<T: Number> Pose<T>
impl<T: Number> Pose<T>
pub fn identity() -> Self
Sourcepub fn new(position: Vector3<T>, rotation: Quaternion<T>) -> GeopResult<Self>
pub fn new(position: Vector3<T>, rotation: Quaternion<T>) -> GeopResult<Self>
Turning by rotation — any quaternion definitely not zero,
normalized here — then moving to position.
Sourcepub fn from_euler(position: Vector3<T>, degrees: [T; 3]) -> GeopResult<Self>
pub fn from_euler(position: Vector3<T>, degrees: [T; 3]) -> GeopResult<Self>
Moving to position, turned by degrees about x, then y, then
z — the world’s axes — as a dialog shows a pose.
Sourcepub fn saved(&self) -> GeopResult<Self>
pub fn saved(&self) -> GeopResult<Self>
The pose a file holds of this one: written, and read back (see
Pose’s serialization). Reading it and writing it again gives it
back exactly.
Sourcepub fn rotation(&self) -> Quaternion<T>
pub fn rotation(&self) -> Quaternion<T>
Its rotation’s quaternion: unit as Pose::new makes it, as read
from a file otherwise — a quaternion of any norm but zero stands for
the rotation it divides out (see Pose::apply).
Sourcepub fn map<U: Number>(&self, f: impl Fn(T) -> U) -> Pose<U>
pub fn map<U: Number>(&self, f: impl Fn(T) -> U) -> Pose<U>
Every component mapped by f — into dual numbers, say.
Sourcepub fn euler_degrees(&self) -> [f64; 3]
pub fn euler_degrees(&self) -> [f64; 3]
Its rotation as angles in degrees about x, then y, then z (see
Pose::from_euler) — for showing it to people, and so read off
its midpoint. At gimbal lock (the second at ±90°) only the sum or
difference of the other two is determined; the split is arbitrary
but exact.
Sourcepub fn with_position(&self, position: Vector3<T>) -> Pose<T>
pub fn with_position(&self, position: Vector3<T>) -> Pose<T>
The same rotation, moved to position.
Sourcepub fn compose(&self, inner: &Pose<T>) -> Pose<T>
pub fn compose(&self, inner: &Pose<T>) -> Pose<T>
This pose after inner: a point is moved by inner first.
Sourcepub fn inverse(&self) -> Pose<T>
pub fn inverse(&self) -> Pose<T>
The pose that undoes this one. Its rotation is the inverse
quaternion, q̄ / |q|², so that a pose composed with its inverse is
the identity whatever q’s norm — and norms do not grow along a
chain of poses undone and done again.
Sourcepub fn exp(omega: &Vector3<T>, v: &Vector3<T>) -> GeopResult<Self>
pub fn exp(omega: &Vector3<T>, v: &Vector3<T>) -> GeopResult<Self>
The rigid motion of the twist (ω, v) — turning at ω while moving
at v, for unit time: the exponential map of ξ̂ = ω + ε v as a
unit dual quaternion, exp(ξ̂ / 2). Its rotation turns by |ω|
radians about ω; it is a screw motion along that axis. Zero is the
identity, and to first order it is (1, ω / 2) + ε (0, v / 2).
With φ = |ω| / 2, it is (cos φ, s ω) + ε (−s (ω·v) / 2, s v + c (ω·v) ω), where s = sin φ / (2φ) and c = (cos φ − sin φ / φ) / (8φ²). Near φ = 0 both are summed as their series in φ², which
are polynomials: smooth through zero, where the closed forms are
0 / 0 — so the map can be differentiated there with dual numbers,
as a solver does to linearize a pose. The series are enclosed with
what they leave out, so the map is an enclosure for a twist that is
a box around zero too, and so are its derivatives.
Its rotation is the real part; its position, the translation 2 d r*
of the dual part d and the rotation r, multiplied out:
2 s cos φ v + (s² + 2 c cos φ) (ω·v) ω + 2 s² ω × v.
Sourcepub fn apply(&self, p: &Vector3<T>) -> Vector3<T>
pub fn apply(&self, p: &Vector3<T>) -> Vector3<T>
The point p moved by the pose: turned by the rotation its
quaternion stands for, q p q̄ / |q|², then moved.
Sourcepub fn rotation_about(
point: &Vector3<T>,
direction: &Vector3<T>,
radians: T,
) -> GeopResult<Self>
pub fn rotation_about( point: &Vector3<T>, direction: &Vector3<T>, radians: T, ) -> GeopResult<Self>
Turning by radians about the line through point along the unit
vector direction — counter-clockwise, looking against direction
— as a pose: the rotation (cos ½θ, sin ½θ d), and the position
that keeps point where it is. That quaternion is unit already,
within its enclosure, and kept as it is: normalized again, honestly,
it came out four times as wide, and so did everything the pose turned.
Source§impl Pose
impl Pose
Sourcepub fn exp_differential(
omega: &Vector3,
v: &Vector3,
) -> GeopResult<[[Scalar; 6]; 6]>
pub fn exp_differential( omega: &Vector3, v: &Vector3, ) -> GeopResult<[[Scalar; 6]; 6]>
The differential of Pose::exp in the frame it leads to — the
right Jacobian of the exponential map: the matrix J with
exp(ξ + dξ) = exp(ξ) ∘ exp(J dξ) to first order, for the twist
ξ = (ω, v), rows and columns a turn’s three numbers, then a move’s.
An enclosure for every twist in the boxes omega and v, made by
differentiating the map — enclosed with what its series leave out —
with dual numbers: column k is the twist exp(ξ)⁻¹ ∂ₖ exp(ξ), its
turn 2 r̄ ∂ₖr and its move Rᵀ ∂ₖt for the rotation r and the
position t.
Source§impl Pose<Dual<6>>
A pose steps by a twist (ω, v) in its own frame — turning about its
own origin, and moving along its own axes — by the exponential map:
pose ∘ exp(ω, v).
impl Pose<Dual<6>>
A pose steps by a twist (ω, v) in its own frame — turning about its
own origin, and moving along its own axes — by the exponential map:
pose ∘ exp(ω, v).
Sourcepub fn exp_with_derivatives(omega: &Vector3, v: &Vector3) -> GeopResult<Self>
pub fn exp_with_derivatives(omega: &Vector3, v: &Vector3) -> GeopResult<Self>
The pose of the twist (omega, v) (see Pose::exp), with its
derivatives by the twist’s six numbers — a turn’s three, then a
move’s: at a twist of zero, the step of a pose by its own six
variables, in its own frame.
At a twist of zero — what every constraint a solve makes is differentiated by, many thousand times a drag — it is made once per thread: the same value every time.
Trait Implementations§
impl<T: Copy + Number> Copy for Pose<T>
Source§impl<'de, T> Deserialize<'de> for Pose<T>where
T: Number,
impl<'de, T> Deserialize<'de> for Pose<T>where
T: Number,
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl Exact for Pose
Its position and its rotation’s quaternion, each component exactly —
the quaternion as it is, not normalized: what a value kept to be read
again holds (crate::exact).
impl Exact for Pose
Its position and its rotation’s quaternion, each component exactly —
the quaternion as it is, not normalized: what a value kept to be read
again holds (crate::exact).
impl<T: PartialEq + Number> StructuralPartialEq for Pose<T>
Source§impl Variable for Pose
impl Variable for Pose
Source§fn retract_over(&self, step: &[Scalar]) -> GeopResult<Self>
fn retract_over(&self, step: &[Scalar]) -> GeopResult<Self>
Of a rigid motion: its rotation a unit quaternion. One that a step sharpened is a hair off unit, and turning a point by it scales it by its norm squared — a hair off every rigid motion, so off the true solution too. So it is made unit first, honestly: an enclosure of the rotation it stands for.
Source§fn differential(&self, step: &[Scalar]) -> GeopResult<Option<Vec<Vec<Scalar>>>>
fn differential(&self, step: &[Scalar]) -> GeopResult<Option<Vec<Vec<Scalar>>>>
The right Jacobian of the exponential map (Pose::exp_differential);
the identity, exactly, for a step of exact zeros.
Source§fn stay(&self, at: &Self, scale: Scalar) -> GeopResult<Rows>
fn stay(&self, at: &Self, scale: Scalar) -> GeopResult<Rows>
Its position’s difference from at‘s, and its rotation’s as the
unit quaternions’ difference — of the two quaternions of at’s
rotation, the nearer — times scale, so that a turn counts as the
distance it moves a point scale from its axis.
Source§fn carried(&self, from: &Self, to: &Self) -> Option<Self>
fn carried(&self, from: &Self, to: &Self) -> Option<Self>
Moved as from moved to to: to ∘ from⁻¹ ∘ self.
Source§fn dimension(&self) -> usize
fn dimension(&self) -> usize
Source§fn retract(&self, step: &[Scalar]) -> GeopResult<Self>
fn retract(&self, step: &[Scalar]) -> GeopResult<Self>
step — Variable::dimension numbers — takes it: the value
a solver tries next, a free choice, so sharp.