Define a Torus
region.
I mean, actual core memories are usually toroids, so...
This commit is contained in:
@@ -213,3 +213,46 @@ impl Display for CylinderZ {
|
|||||||
write!(f, "d({:.1e}, {:.1e}) <= {:.1e}", self.center.x(), self.center.y(), self.radius)
|
write!(f, "d({:.1e}, {:.1e}) <= {:.1e}", self.center.x(), self.center.y(), self.radius)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Copy, Clone, Serialize, Deserialize)]
|
||||||
|
pub struct Torus {
|
||||||
|
center: Meters,
|
||||||
|
/// Unit-length vector describing the axis of the torus
|
||||||
|
normal: Meters,
|
||||||
|
/// Distance from origin to the "center" of the solid part of the torus
|
||||||
|
major_rad: Real,
|
||||||
|
/// Distance from a center-point of the torus to its surface
|
||||||
|
minor_rad: Real,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Torus {
|
||||||
|
pub fn new(center: Meters, normal: Meters, major_rad: Flt, minor_rad: Flt) -> Self {
|
||||||
|
Self {
|
||||||
|
center,
|
||||||
|
normal,
|
||||||
|
major_rad: Real::from_inner(major_rad),
|
||||||
|
minor_rad: Real::from_inner(minor_rad),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn new_xy(center: Meters, major_rad: Flt, minor_rad: Flt) -> Self {
|
||||||
|
Self::new(center, Meters(Vec3::new(0.0, 0.0, 1.0)), major_rad, minor_rad)
|
||||||
|
}
|
||||||
|
pub fn new_xz(center: Meters, major_rad: Flt, minor_rad: Flt) -> Self {
|
||||||
|
Self::new(center, Meters(Vec3::new(0.0, 1.0, 0.0)), major_rad, minor_rad)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Region for Torus {
|
||||||
|
fn contains(&self, p: Meters) -> bool {
|
||||||
|
// a torus is the set of all points < distance `r` from the circle of radius `R`,
|
||||||
|
// where `r`= minor_rad, `R` = major_rad, and `center` and `normal` define the center and
|
||||||
|
// plane of the circle.
|
||||||
|
// 1. Project `p` onto the plane of the circle.
|
||||||
|
// 2. Find the point `q` on the circle which is nearest to `p`.
|
||||||
|
// 3. Consider the distance from `p` to `q`.
|
||||||
|
let p_on_plane = *p - self.normal.with_mag(self.normal.dot(*p));
|
||||||
|
let q = (p_on_plane - *self.center).with_mag(self.major_rad.into_inner());
|
||||||
|
let distance_to_circle = (*p - q).mag();
|
||||||
|
distance_to_circle < self.minor_rad.into_inner()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -179,6 +179,16 @@ impl Vec3 {
|
|||||||
z: self.z / other.z,
|
z: self.z / other.z,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn with_mag(&self, new_mag: Flt) -> Vec3 {
|
||||||
|
if new_mag == 0.0 {
|
||||||
|
// avoid div-by-zero if self.mag() == 0 and new_mag == 0
|
||||||
|
Self::zero()
|
||||||
|
} else {
|
||||||
|
let scale = Real::from_inner(new_mag) / self.mag();
|
||||||
|
self.clone() * scale.into_inner()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<(Flt, Flt, Flt)> for Vec3 {
|
impl Into<(Flt, Flt, Flt)> for Vec3 {
|
||||||
|
Reference in New Issue
Block a user