fix Vec3::with_mag to return an Option

and thereby simplify it into just one method.
This commit is contained in:
2022-07-29 21:45:25 -07:00
parent ba6ef3c5c2
commit 349e01ba16
4 changed files with 23 additions and 39 deletions

View File

@@ -87,7 +87,7 @@ impl Region for Torus {
// 2. Find the point `q` on the circle which is nearest to `p`.
// 3. Consider the distance from `p` to `q`.
let rel_p = *p - *self.center;
let p_on_plane = rel_p - self.normal.with_mag(self.normal.dot(rel_p));
let p_on_plane = rel_p - self.normal.with_mag(self.normal.dot(rel_p)).unwrap();
let q = if p_on_plane == Vec3::zero() {
// avoid division by zero.
// The point is precisely on the axis of the torus.
@@ -95,9 +95,9 @@ impl Region for Torus {
// and they all give the same answer.
// Such a point is given by rotating the normal axis by 90 degrees in ANY DIRECTION
let off_axis = self.normal.arbitrary_orthogonal_vector();
off_axis.with_mag(self.major_rad)
off_axis.with_mag(self.major_rad).unwrap()
} else {
p_on_plane.with_mag(self.major_rad)
p_on_plane.with_mag(self.major_rad).unwrap()
};
let distance_to_circle_sq = rel_p.distance_sq(q);
distance_to_circle_sq < self.minor_rad * self.minor_rad

View File

@@ -54,7 +54,7 @@ fn scale_unsigned_to_u8(x: f32, typ: f32) -> u8 {
/// Scale a vector to have magnitude between [0, 1).
fn scale_vector(x: Vec2<f32>, typical_mag: f32) -> Vec2<f32> {
let new_mag = scale_unsigned(x.mag(), typical_mag);
x.with_mag(new_mag)
x.with_mag(new_mag).unwrap_or_default()
}
fn im_size<S: AbstractSim>(state: &S, max_w: u32, max_h: u32) -> (u32, u32) {

View File

@@ -151,8 +151,8 @@ impl<R: Region + Sync, T: TimeVarying1 + Sync> AbstractStimulus for CurlStimulus
let (amt_e, amt_h) = self.stim.at(t_sec);
let from_center_to_point = *pos - *self.center;
let rotational = from_center_to_point.cross(*self.axis);
let impulse_e = rotational.with_mag_or_zero(amt_e.cast());
let impulse_h = rotational.with_mag_or_zero(amt_h.cast());
let impulse_e = rotational.with_mag(amt_e.cast()).unwrap_or_default();
let impulse_h = rotational.with_mag(amt_h.cast()).unwrap_or_default();
(impulse_e, impulse_h)
} else {
Fields::default()

View File

@@ -124,25 +124,17 @@ impl<R: Real> Vec2<R> {
self.mag_sq().sqrt()
}
pub fn with_mag(&self, new_mag: R) -> Self {
pub fn with_mag(&self, new_mag: R) -> Option<Self> {
if new_mag.is_zero() {
// avoid div-by-zero if self.mag() == 0 and new_mag == 0
Self::zero()
Some(Self::zero())
} else {
// TODO: remove this assert: allow R to guard this
debug_assert!(!self.mag().is_zero()); // division by zero
let scale = new_mag / self.mag();
*self * scale
}
}
pub fn with_mag_or_zero(&self, new_mag: R) -> Self {
let old_mag = self.mag();
if old_mag.is_zero() || new_mag.is_zero() {
// avoid div-by-zero
Self::zero()
} else {
*self * (new_mag / old_mag)
let old_mag = self.mag();
if old_mag.is_zero() {
None
} else {
Some(*self * (new_mag / old_mag))
}
}
}
@@ -341,25 +333,17 @@ impl<R: Real> Vec3<R> {
Self::new(self.x().exp(), self.y().exp(), self.z().exp())
}
pub fn with_mag(&self, new_mag: R) -> Self {
pub fn with_mag(&self, new_mag: R) -> Option<Self> {
if new_mag.is_zero() {
// avoid div-by-zero if self.mag() == 0 and new_mag == 0
Self::zero()
Some(Self::zero())
} else {
// TODO: remove this assert: allow R to guard this
debug_assert!(!self.mag().is_zero()); // division by zero
let scale = new_mag / self.mag();
*self * scale
}
}
pub fn with_mag_or_zero(&self, new_mag: R) -> Self {
let old_mag = self.mag();
if old_mag.is_zero() || new_mag.is_zero() {
// avoid div-by-zero
Self::zero()
} else {
*self * (new_mag / old_mag)
let old_mag = self.mag();
if old_mag.is_zero() {
None
} else {
Some(*self * (new_mag / old_mag))
}
}
}
@@ -368,7 +352,7 @@ impl<R: Real> Vec3<R> {
if *self == Self::zero() {
*self
} else {
self.with_mag(R::one())
self.with_mag(R::one()).unwrap()
}
}
pub fn round(&self) -> Self {