Skip to content

Commit

Permalink
Simplify and standardise formatting of geometry types
Browse files Browse the repository at this point in the history
  • Loading branch information
owenbrooks committed Jun 15, 2022
1 parent f77f556 commit 807e4c1
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 94 deletions.
15 changes: 15 additions & 0 deletions src/base/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1968,6 +1968,21 @@ impl_fmt!(fmt::UpperHex, "{:X}", "{:1$X}");
impl_fmt!(fmt::Binary, "{:b}", "{:.1$b}");
impl_fmt!(fmt::Pointer, "{:p}", "{:.1$p}");

/// Displays a vector using commas as the delimiter
pub fn display_column_vec_as_row<T: Scalar + fmt::Display, D: crate::DimName>(vector: &OVector<T, D>, f: &mut fmt::Formatter<'_>) -> fmt::Result
where
DefaultAllocator: Allocator<T, D>,
{
write!(f, "[")?;
let mut it = vector.iter();
std::fmt::Display::fmt(it.next().unwrap(), f)?;
for comp in it {
write!(f, ", ")?;
std::fmt::Display::fmt(comp, f)?;
}
write!(f, "]")
}

#[cfg(test)]
mod tests {
#[test]
Expand Down
25 changes: 6 additions & 19 deletions src/geometry/dual_quaternion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -951,25 +951,12 @@ impl<T: RealField> Default for UnitDualQuaternion<T> {

impl<T: RealField + fmt::Display> fmt::Display for UnitDualQuaternion<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if let Some(axis) = self.rotation().axis() {
let axis = axis.into_inner();
write!(
f,
"UnitDualQuaternion translation: {} − angle: {} − axis: ({}, {}, {})",
self.translation().vector,
self.rotation().angle(),
axis[0],
axis[1],
axis[2]
)
} else {
write!(
f,
"UnitDualQuaternion translation: {} − angle: {} − axis: (undefined)",
self.translation().vector,
self.rotation().angle()
)
}
write!(f, "{{ translation: ")?;
crate::display_column_vec_as_row(&self.translation().vector, f)?;
write!(f, ", ")?;
write!(f, "rotation: ")?;
std::fmt::Display::fmt(&self.rotation(), f)?;
write!(f, " }}")
}
}

Expand Down
12 changes: 6 additions & 6 deletions src/geometry/isometry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,11 +548,11 @@ where
R: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let precision = f.precision().unwrap_or(3);

writeln!(f, "Isometry {{")?;
write!(f, "{:.*}", precision, self.translation)?;
write!(f, "{:.*}", precision, self.rotation)?;
writeln!(f, "}}")
write!(f, "{{ translation: ")?;
crate::display_column_vec_as_row(&self.translation.vector, f)?;
write!(f, ", ")?;
write!(f, "rotation: ")?;
std::fmt::Display::fmt(&self.rotation, f)?;
write!(f, " }}")
}
}
33 changes: 13 additions & 20 deletions src/geometry/point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ use std::mem::MaybeUninit;
/// may have some other methods, e.g., `isometry.inverse_transform_point(&point)`. See the documentation
/// of said transformations for details.
#[repr(C)]
#[derive(Clone)]
#[derive(Clone, Debug)]
#[cfg_attr(
feature = "rkyv-serialize-no-std",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
Expand All @@ -49,15 +49,6 @@ where
pub coords: OVector<T, D>,
}

impl<T: Scalar + fmt::Debug, D: DimName> fmt::Debug for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
self.coords.as_slice().fmt(formatter)
}
}

impl<T: Scalar + hash::Hash, D: DimName> hash::Hash for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
Expand Down Expand Up @@ -457,17 +448,19 @@ impl<T: Scalar + fmt::Display, D: DimName> fmt::Display for OPoint<T, D>
where
DefaultAllocator: Allocator<T, D>,
{
/// ```rust
/// # use nalgebra::Point3;
/// let point = Point3::new(1.12345678, 2.12345678, 3.12345678);
/// let rounded = format!("{:#.4}", point); // print point in compact representation
/// assert_eq!(rounded, "[1.1235, 2.1235, 3.1235]");
/// let vertical = format!("{}", point); // print point as a column
/// assert_eq!(vertical, "\n ┌ ┐\n │ 1.12345678 │\n │ 2.12345678 │\n │ 3.12345678 │\n └ ┘");
/// ```
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{{")?;

let mut it = self.coords.iter();

write!(f, "{}", *it.next().unwrap())?;

for comp in it {
write!(f, ", {}", *comp)?;
if f.alternate() {
crate::display_column_vec_as_row(&self.coords, f)
} else {
std::fmt::Display::fmt(&self.coords, f) // pretty-prints vector
}

write!(f, "}}")
}
}
48 changes: 29 additions & 19 deletions src/geometry/quaternion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,13 @@ pub struct Quaternion<T> {

impl<T: fmt::Debug> fmt::Debug for Quaternion<T> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
self.coords.as_slice().fmt(formatter)
formatter
.debug_struct("Quaternion")
.field("x", &self.coords[0])
.field("y", &self.coords[1])
.field("z", &self.coords[2])
.field("w", &self.coords[3])
.finish()
}
}

Expand Down Expand Up @@ -995,11 +1001,16 @@ impl<T: RealField + UlpsEq<Epsilon = T>> UlpsEq for Quaternion<T> {

impl<T: RealField + fmt::Display> fmt::Display for Quaternion<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"Quaternion {} − ({}, {}, {})",
self[3], self[0], self[1], self[2]
)
// Formatting of each item is forwarded to standard fmt display so that formatting
// flags are followed correctly.
std::fmt::Display::fmt(&self[0], f)?;
write!(f, " + ")?;
std::fmt::Display::fmt(&self[1], f)?;
write!(f, "i + ")?;
std::fmt::Display::fmt(&self[2], f)?;
write!(f, "j + ")?;
std::fmt::Display::fmt(&self[3], f)?;
write!(f, "k")
}
}

Expand Down Expand Up @@ -1636,23 +1647,22 @@ impl<T: RealField> Default for UnitQuaternion<T> {

impl<T: RealField + fmt::Display> fmt::Display for UnitQuaternion<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
// Formatting of each item is forwarded to standard fmt Display so that formatting
// flags are followed correctly.
write!(f, "{{ angle: ")?;
std::fmt::Display::fmt(&self.angle(), f)?;
write!(f, ", axis: (")?;
if let Some(axis) = self.axis() {
let axis = axis.into_inner();
write!(
f,
"UnitQuaternion angle: {} − axis: ({}, {}, {})",
self.angle(),
axis[0],
axis[1],
axis[2]
)
std::fmt::Display::fmt(&axis[0], f)?;
write!(f, ", ")?;
std::fmt::Display::fmt(&axis[1], f)?;
write!(f, ", ")?;
std::fmt::Display::fmt(&axis[2], f)?;
} else {
write!(
f,
"UnitQuaternion angle: {} − axis: (undefined)",
self.angle()
)
write!(f, "undefined")?;
}
write!(f, ") }}")
}
}

Expand Down
18 changes: 6 additions & 12 deletions src/geometry/scale.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,13 @@ use crate::geometry::Point;
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
)]
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub struct Scale<T, const D: usize> {
/// The scale coordinates, i.e., how much is multiplied to a point's coordinates when it is
/// scaled.
pub vector: SVector<T, D>,
}

impl<T: fmt::Debug, const D: usize> fmt::Debug for Scale<T, D> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
self.vector.as_slice().fmt(formatter)
}
}

impl<T: Scalar + hash::Hash, const D: usize> hash::Hash for Scale<T, D>
where
Owned<T, Const<D>>: hash::Hash,
Expand Down Expand Up @@ -369,10 +363,10 @@ where
*/
impl<T: Scalar + fmt::Display, const D: usize> fmt::Display for Scale<T, D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let precision = f.precision().unwrap_or(3);

writeln!(f, "Scale {{")?;
write!(f, "{:.*}", precision, self.vector)?;
writeln!(f, "}}")
if f.alternate() {
crate::display_column_vec_as_row(&self.vector, f)
} else {
std::fmt::Display::fmt(&self.vector, f) // pretty-prints vector
}
}
}
14 changes: 8 additions & 6 deletions src/geometry/similarity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,11 +397,13 @@ where
R: AbstractRotation<T, D> + fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let precision = f.precision().unwrap_or(3);

writeln!(f, "Similarity {{")?;
write!(f, "{:.*}", precision, self.isometry)?;
write!(f, "Scaling: {:.*}", precision, self.scaling)?;
writeln!(f, "}}")
write!(f, "{{ translation: ")?;
crate::display_column_vec_as_row(&self.isometry.translation.vector, f)?;
write!(f, ", ")?;
write!(f, "rotation: ")?;
std::fmt::Display::fmt(&self.isometry.rotation, f)?;
write!(f, ", scaling: ")?;
std::fmt::Display::fmt(&self.scaling, f)?;
write!(f, " }}")
}
}
18 changes: 6 additions & 12 deletions src/geometry/translation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,13 @@ use crate::geometry::Point;
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
)]
#[cfg_attr(feature = "cuda", derive(cust_core::DeviceCopy))]
#[derive(Copy, Clone)]
#[derive(Copy, Clone, Debug)]
pub struct Translation<T, const D: usize> {
/// The translation coordinates, i.e., how much is added to a point's coordinates when it is
/// translated.
pub vector: SVector<T, D>,
}

impl<T: fmt::Debug, const D: usize> fmt::Debug for Translation<T, D> {
fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
self.vector.as_slice().fmt(formatter)
}
}

impl<T: Scalar + hash::Hash, const D: usize> hash::Hash for Translation<T, D>
where
Owned<T, Const<D>>: hash::Hash,
Expand Down Expand Up @@ -284,10 +278,10 @@ where
*/
impl<T: Scalar + fmt::Display, const D: usize> fmt::Display for Translation<T, D> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let precision = f.precision().unwrap_or(3);

writeln!(f, "Translation {{")?;
write!(f, "{:.*}", precision, self.vector)?;
writeln!(f, "}}")
if f.alternate() {
crate::display_column_vec_as_row(&self.vector, f)
} else {
std::fmt::Display::fmt(&self.vector, f) // pretty-prints vector
}
}
}

0 comments on commit 807e4c1

Please sign in to comment.