pub struct Triangle {
pub v0: Point3<f64>,
pub v1: Point3<f64>,
pub v2: Point3<f64>,
}Expand description
Triangle definition
Fields§
§v0: Point3<f64>§v1: Point3<f64>§v2: Point3<f64>Implementations§
Source§impl Triangle
impl Triangle
Sourcepub fn normal(&self) -> Vector3<f64>
pub fn normal(&self) -> Vector3<f64>
Calculate triangle normal.
Degenerate triangles get +Z, never NaN. A zero-area (collapsed or
exactly collinear) triangle has a zero-length cross product, and the
plain normalize() this used to call is v / |v| — i.e. 0.0 / 0.0,
which is NaN in every component. Those NaNs were written verbatim into
Mesh::normals by add_triangle_to_mesh (the only production caller of
this method, via ClippingProcessor::clip_mesh), and they SURVIVED the
mesh-hygiene pass: clean_degenerate / drop_thin_triangles rewrites
only indices, so the degenerate triangle’s vertices stay in
positions / normals as ORPHANS carrying NaN. Six of duplex.ifc’s
material-layer wall slices shipped 81 NaN normal components that way,
which the @ifc-lite/provenance node-hash domain check rightly rejects
(every NaN bit pattern collapses to one quiet NaN when serialized, so
accepting them would give distinct payloads the same hash).
+Z is this crate’s established convention for an undefined normal —
the same fallback csg::normals::calculate_normals and
mesh::weld_impl’s average-normals path already use — so a consumer
that meets one meets them all. It is stated in the KERNEL’s own Z-up
frame, like every other normal this crate writes, so a viewer that
converts to Y-up reads it back as +Y; that is the conversion doing its
job, not a second convention. The value is arbitrary but must be a FIXED
unit vector: a zero normal would just re-create the division by zero in
any shader or exporter that re-normalizes.
Non-degenerate triangles are unaffected, bit-for-bit: try_normalize(0.0)
returns Some(v.unscale(|v|)) for every |v| > 0, which is exactly what
normalize() computed. The extra is_finite check covers the
astronomically-unlikely underflow case where |v| rounds to zero from
non-zero components (division would yield ±Inf, also out of domain).
Sourcepub fn cross_product(&self) -> Vector3<f64>
pub fn cross_product(&self) -> Vector3<f64>
Calculate the cross product of edges, which is twice the area vector.
Returns a Vector3<f64> perpendicular to the triangle plane.
For degenerate/collinear triangles, returns the zero vector.
Use is_degenerate() or try_normalize() on the result if you need
to detect and handle degenerate cases.
Sourcepub fn is_degenerate(&self, epsilon: f64) -> bool
pub fn is_degenerate(&self, epsilon: f64) -> bool
Check if triangle is degenerate (zero area, collinear vertices).
Uses try_normalize on the cross product with the specified epsilon.
Returns true if the cross product cannot be normalized (i.e., degenerate).
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Triangle
impl RefUnwindSafe for Triangle
impl Send for Triangle
impl Sync for Triangle
impl Unpin for Triangle
impl UnsafeUnpin for Triangle
impl UnwindSafe for Triangle
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§impl<T> Pointable for T
impl<T> Pointable for T
Source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
Source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self from the equivalent element of its
superset. Read moreSource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self is actually part of its subset T (and can be converted to it).Source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset but without any property checks. Always succeeds.Source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self to the equivalent element of its superset.