Skip to content

Commit a798d1c

Browse files
authored
Merge pull request dimforge#844 from dimforge/cast
@sebcrozet Add "cast" methods to cast the type component types
2 parents f282d02 + 4bb1eda commit a798d1c

11 files changed

+303
-26
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ documented here.
44

55
This project adheres to [Semantic Versioning](https://semver.org/).
66

7+
## [0.25.2] - WIP
8+
### Added
9+
- A `cast` method has been added to most types. This can be used to change the
10+
type of the components of a given entity. Example: `vector.cast::<f32>()`.
11+
712
## [0.25.1]
813
This release replaces the version 0.25.0 which has been yanked. The 0.25.0 version
914
added significant complication to build `nalgebra` targeting a `#[no-std]` platform

src/base/matrix.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer};
1616
#[cfg(feature = "abomonation-serialize")]
1717
use abomonation::Abomonation;
1818

19-
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, Field};
19+
use simba::scalar::{ClosedAdd, ClosedMul, ClosedSub, Field, SupersetOf};
2020
use simba::simd::SimdPartialOrd;
2121

2222
use crate::base::allocator::{Allocator, SameShapeAllocator, SameShapeC, SameShapeR};
@@ -610,6 +610,23 @@ impl<N: Scalar, R: Dim, C: Dim, S: Storage<N, R, C>> Matrix<N, R, C, S> {
610610
res
611611
}
612612

613+
/// Cast the components of `self` to another type.
614+
///
615+
/// # Example
616+
/// ```
617+
/// # use nalgebra::Vector3;
618+
/// let q = Vector3::new(1.0f64, 2.0, 3.0);
619+
/// let q2 = q.cast::<f32>();
620+
/// assert_eq!(q2, Vector3::new(1.0f32, 2.0, 3.0));
621+
/// ```
622+
pub fn cast<N2: Scalar>(self) -> MatrixMN<N2, R, C>
623+
where
624+
MatrixMN<N2, R, C>: SupersetOf<Self>,
625+
DefaultAllocator: Allocator<N2, R, C>,
626+
{
627+
crate::convert(self)
628+
}
629+
613630
/// Similar to `self.iter().fold(init, f)` except that `init` is replaced by a closure.
614631
///
615632
/// The initialization closure is given the first component of this matrix:

src/geometry/dual_quaternion_construction.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::{
55
use num::{One, Zero};
66
#[cfg(feature = "arbitrary")]
77
use quickcheck::{Arbitrary, Gen};
8+
use simba::scalar::SupersetOf;
89

910
impl<N: Scalar> DualQuaternion<N> {
1011
/// Creates a dual quaternion from its rotation and translation components.
@@ -49,6 +50,22 @@ impl<N: Scalar> DualQuaternion<N> {
4950
Quaternion::from_real(N::zero()),
5051
)
5152
}
53+
54+
/// Cast the components of `self` to another type.
55+
///
56+
/// # Example
57+
/// ```
58+
/// # use nalgebra::{Quaternion, DualQuaternion};
59+
/// let q = DualQuaternion::from_real(Quaternion::new(1.0f64, 2.0, 3.0, 4.0));
60+
/// let q2 = q.cast::<f32>();
61+
/// assert_eq!(q2, DualQuaternion::from_real(Quaternion::new(1.0f32, 2.0, 3.0, 4.0)));
62+
/// ```
63+
pub fn cast<To: Scalar>(self) -> DualQuaternion<To>
64+
where
65+
DualQuaternion<To>: SupersetOf<Self>,
66+
{
67+
crate::convert(self)
68+
}
5269
}
5370

5471
impl<N: SimdRealField> DualQuaternion<N>
@@ -129,6 +146,22 @@ impl<N: SimdRealField> UnitDualQuaternion<N> {
129146
pub fn identity() -> Self {
130147
Self::new_unchecked(DualQuaternion::identity())
131148
}
149+
150+
/// Cast the components of `self` to another type.
151+
///
152+
/// # Example
153+
/// ```
154+
/// # use nalgebra::UnitDualQuaternion;
155+
/// let q = UnitDualQuaternion::<f64>::identity();
156+
/// let q2 = q.cast::<f32>();
157+
/// assert_eq!(q2, UnitDualQuaternion::<f32>::identity());
158+
/// ```
159+
pub fn cast<To: Scalar>(self) -> UnitDualQuaternion<To>
160+
where
161+
UnitDualQuaternion<To>: SupersetOf<Self>,
162+
{
163+
crate::convert(self)
164+
}
132165
}
133166

134167
impl<N: SimdRealField> UnitDualQuaternion<N>

src/geometry/isometry_construction.rs

Lines changed: 67 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,16 @@ use rand::{
1010
Rng,
1111
};
1212

13+
use simba::scalar::SupersetOf;
1314
use simba::simd::SimdRealField;
1415

1516
use crate::base::allocator::Allocator;
1617
use crate::base::dimension::{DimName, U2};
1718
use crate::base::{DefaultAllocator, Vector2, Vector3};
1819

19-
use crate::geometry::{
20+
use crate::{
2021
AbstractRotation, Isometry, Isometry2, Isometry3, IsometryMatrix2, IsometryMatrix3, Point,
21-
Point3, Rotation, Rotation3, Translation, Translation2, Translation3, UnitComplex,
22+
Point3, Rotation, Rotation3, Scalar, Translation, Translation2, Translation3, UnitComplex,
2223
UnitQuaternion,
2324
};
2425

@@ -153,6 +154,22 @@ where
153154
pub fn rotation(angle: N) -> Self {
154155
Self::new(Vector2::zeros(), angle)
155156
}
157+
158+
/// Cast the components of `self` to another type.
159+
///
160+
/// # Example
161+
/// ```
162+
/// # use nalgebra::IsometryMatrix2;
163+
/// let iso = IsometryMatrix2::<f64>::identity();
164+
/// let iso2 = iso.cast::<f32>();
165+
/// assert_eq!(iso2, IsometryMatrix2::<f32>::identity());
166+
/// ```
167+
pub fn cast<To: Scalar>(self) -> IsometryMatrix2<To>
168+
where
169+
IsometryMatrix2<To>: SupersetOf<Self>,
170+
{
171+
crate::convert(self)
172+
}
156173
}
157174

158175
impl<N: SimdRealField> Isometry2<N>
@@ -191,6 +208,22 @@ where
191208
pub fn rotation(angle: N) -> Self {
192209
Self::new(Vector2::zeros(), angle)
193210
}
211+
212+
/// Cast the components of `self` to another type.
213+
///
214+
/// # Example
215+
/// ```
216+
/// # use nalgebra::Isometry2;
217+
/// let iso = Isometry2::<f64>::identity();
218+
/// let iso2 = iso.cast::<f32>();
219+
/// assert_eq!(iso2, Isometry2::<f32>::identity());
220+
/// ```
221+
pub fn cast<To: Scalar>(self) -> Isometry2<To>
222+
where
223+
Isometry2<To>: SupersetOf<Self>,
224+
{
225+
crate::convert(self)
226+
}
194227
}
195228

196229
// 3D rotation.
@@ -387,13 +420,45 @@ where
387420
N::Element: SimdRealField,
388421
{
389422
basic_isometry_construction_impl!(UnitQuaternion<N>);
423+
424+
/// Cast the components of `self` to another type.
425+
///
426+
/// # Example
427+
/// ```
428+
/// # use nalgebra::Isometry3;
429+
/// let iso = Isometry3::<f64>::identity();
430+
/// let iso2 = iso.cast::<f32>();
431+
/// assert_eq!(iso2, Isometry3::<f32>::identity());
432+
/// ```
433+
pub fn cast<To: Scalar>(self) -> Isometry3<To>
434+
where
435+
Isometry3<To>: SupersetOf<Self>,
436+
{
437+
crate::convert(self)
438+
}
390439
}
391440

392441
impl<N: SimdRealField> IsometryMatrix3<N>
393442
where
394443
N::Element: SimdRealField,
395444
{
396445
basic_isometry_construction_impl!(Rotation3<N>);
446+
447+
/// Cast the components of `self` to another type.
448+
///
449+
/// # Example
450+
/// ```
451+
/// # use nalgebra::IsometryMatrix3;
452+
/// let iso = IsometryMatrix3::<f64>::identity();
453+
/// let iso2 = iso.cast::<f32>();
454+
/// assert_eq!(iso2, IsometryMatrix3::<f32>::identity());
455+
/// ```
456+
pub fn cast<To: Scalar>(self) -> IsometryMatrix3<To>
457+
where
458+
IsometryMatrix3<To>: SupersetOf<Self>,
459+
{
460+
crate::convert(self)
461+
}
397462
}
398463

399464
/// # Construction from a 3D eye position and target point

src/geometry/point_construction.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use crate::{
1515
Point1, Point2, Point3, Point4, Point5, Point6, Vector1, Vector2, Vector3, Vector4, Vector5,
1616
Vector6,
1717
};
18-
use simba::scalar::ClosedDiv;
18+
use simba::scalar::{ClosedDiv, SupersetOf};
1919

2020
use crate::geometry::Point;
2121

@@ -119,6 +119,23 @@ where
119119
None
120120
}
121121
}
122+
123+
/// Cast the components of `self` to another type.
124+
///
125+
/// # Example
126+
/// ```
127+
/// # use nalgebra::Point2;
128+
/// let pt = Point2::new(1.0f64, 2.0);
129+
/// let pt2 = pt.cast::<f32>();
130+
/// assert_eq!(pt2, Point2::new(1.0f32, 2.0));
131+
/// ```
132+
pub fn cast<To: Scalar>(self) -> Point<To, D>
133+
where
134+
Point<To, D>: SupersetOf<Self>,
135+
DefaultAllocator: Allocator<To, D>,
136+
{
137+
crate::convert(self)
138+
}
122139
}
123140

124141
/*

src/geometry/quaternion_construction.rs

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use rand::{
1313

1414
use num::{One, Zero};
1515

16-
use simba::scalar::RealField;
16+
use simba::scalar::{RealField, SupersetOf};
1717
use simba::simd::SimdBool;
1818

1919
use crate::base::dimension::U3;
@@ -49,6 +49,22 @@ impl<N: Scalar> Quaternion<N> {
4949
pub fn new(w: N, i: N, j: N, k: N) -> Self {
5050
Self::from(Vector4::new(i, j, k, w))
5151
}
52+
53+
/// Cast the components of `self` to another type.
54+
///
55+
/// # Example
56+
/// ```
57+
/// # use nalgebra::Quaternion;
58+
/// let q = Quaternion::new(1.0f64, 2.0, 3.0, 4.0);
59+
/// let q2 = q.cast::<f32>();
60+
/// assert_eq!(q2, Quaternion::new(1.0f32, 2.0, 3.0, 4.0));
61+
/// ```
62+
pub fn cast<To: Scalar>(self) -> Quaternion<To>
63+
where
64+
To: SupersetOf<N>,
65+
{
66+
crate::convert(self)
67+
}
5268
}
5369

5470
impl<N: SimdRealField> Quaternion<N> {
@@ -199,6 +215,23 @@ where
199215
Self::new_unchecked(Quaternion::identity())
200216
}
201217

218+
/// Cast the components of `self` to another type.
219+
///
220+
/// # Example
221+
/// ```
222+
/// # use nalgebra::UnitQuaternion;
223+
/// # use approx::assert_relative_eq;
224+
/// let q = UnitQuaternion::from_euler_angles(1.0f64, 2.0, 3.0);
225+
/// let q2 = q.cast::<f32>();
226+
/// assert_relative_eq!(q2, UnitQuaternion::from_euler_angles(1.0f32, 2.0, 3.0), epsilon = 1.0e-6);
227+
/// ```
228+
pub fn cast<To: Scalar>(self) -> UnitQuaternion<To>
229+
where
230+
To: SupersetOf<N>,
231+
{
232+
crate::convert(self)
233+
}
234+
202235
/// Creates a new quaternion from a unit vector (the rotation axis) and an angle
203236
/// (the rotation angle).
204237
///

src/geometry/quaternion_conversion.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ use crate::geometry::{
3535

3636
impl<N1, N2> SubsetOf<Quaternion<N2>> for Quaternion<N1>
3737
where
38-
N1: SimdRealField,
39-
N2: SimdRealField + SupersetOf<N1>,
38+
N1: Scalar,
39+
N2: Scalar + SupersetOf<N1>,
4040
{
4141
#[inline]
4242
fn to_superset(&self) -> Quaternion<N2> {
@@ -58,8 +58,8 @@ where
5858

5959
impl<N1, N2> SubsetOf<UnitQuaternion<N2>> for UnitQuaternion<N1>
6060
where
61-
N1: SimdRealField,
62-
N2: SimdRealField + SupersetOf<N1>,
61+
N1: Scalar,
62+
N2: Scalar + SupersetOf<N1>,
6363
{
6464
#[inline]
6565
fn to_superset(&self) -> UnitQuaternion<N2> {

src/geometry/rotation_construction.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use num::{One, Zero};
22

3-
use simba::scalar::{ClosedAdd, ClosedMul};
3+
use simba::scalar::{ClosedAdd, ClosedMul, SupersetOf};
44

55
use crate::base::allocator::Allocator;
66
use crate::base::dimension::DimName;
@@ -31,6 +31,28 @@ where
3131
}
3232
}
3333

34+
impl<N: Scalar, D: DimName> Rotation<N, D>
35+
where
36+
DefaultAllocator: Allocator<N, D, D>,
37+
{
38+
/// Cast the components of `self` to another type.
39+
///
40+
/// # Example
41+
/// ```
42+
/// # use nalgebra::Rotation2;
43+
/// let rot = Rotation2::<f64>::identity();
44+
/// let rot2 = rot.cast::<f32>();
45+
/// assert_eq!(rot2, Rotation2::<f32>::identity());
46+
/// ```
47+
pub fn cast<To: Scalar>(self) -> Rotation<To, D>
48+
where
49+
Rotation<To, D>: SupersetOf<Self>,
50+
DefaultAllocator: Allocator<To, D, D>,
51+
{
52+
crate::convert(self)
53+
}
54+
}
55+
3456
impl<N, D: DimName> One for Rotation<N, D>
3557
where
3658
N: Scalar + Zero + One + ClosedAdd + ClosedMul,

0 commit comments

Comments
 (0)