pub struct NurbsSurface {
pub degree_u: usize,
pub degree_v: usize,
pub knots_u: Vec<f64>,
pub knots_v: Vec<f64>,
pub control_points: Vec<Vec<Vec4>>,
/* private fields */
}Fields§
§degree_u: usize§degree_v: usize§knots_u: Vec<f64>§knots_v: Vec<f64>§control_points: Vec<Vec<Vec4>>Implementations§
Source§impl NurbsSurface
impl NurbsSurface
Sourcepub fn extend_natural(
&self,
side: SurfaceSide,
delta_param: f64,
) -> Result<NurbsSurface, ExtendRefusal>
pub fn extend_natural( &self, side: SurfaceSide, delta_param: f64, ) -> Result<NurbsSurface, ExtendRefusal>
Continue this surface past one boundary of its parameter square by
delta_param, as the analytic continuation of its own terminal Bézier
span. See the module comment for the construction and for what survives
of the input (everything, over the original domain).
Source§impl NurbsSurface
impl NurbsSurface
pub fn new( degree_u: usize, degree_v: usize, knots_u: Vec<f64>, knots_v: Vec<f64>, control_points: Vec<Vec<Vec4>>, ) -> Result<Self, String>
Sourcepub fn closed_directions(&self) -> Result<(bool, bool), String>
pub fn closed_directions(&self) -> Result<(bool, bool), String>
Whether the surface joins itself along u (first) and v (second):
opposite domain edges coincide at three sampled fractions. The 1e-6
threshold matches the historical LINEAR_TOLERANCE * 10 used by the
projection and curve×surface intersection modules.
pub fn domain_u(&self) -> Result<[f64; 2], String>
pub fn domain_v(&self) -> Result<[f64; 2], String>
Sourcepub fn analytic(&self) -> Option<&AnalyticSurface>
pub fn analytic(&self) -> Option<&AnalyticSurface>
The recognized analytic carrier, if this exact rational patch is a plane or a full revolution quadric/torus. Computed once per instance.
pub fn evaluate_homogeneous(&self, u: f64, v: f64) -> Result<Vec4, String>
pub fn evaluate(&self, u: f64, v: f64) -> Result<Vec3, String>
Sourcepub fn evaluate_extended(&self, u: f64, v: f64) -> Result<Vec3, String>
pub fn evaluate_extended(&self, u: f64, v: f64) -> Result<Vec3, String>
Value beyond the domain (Golovanov §3.15): closed directions wrap cyclically; open directions extend along the boundary tangent plane, with the bilinear corner form when both parameters are outside. Intersection and projection algorithms probe outside the domain, so this is a required capability of every surface.
Sourcepub fn derivatives_extended(
&self,
u: f64,
v: f64,
derivative_count: usize,
) -> Result<Vec<Vec<Vec3>>, String>
pub fn derivatives_extended( &self, u: f64, v: f64, derivative_count: usize, ) -> Result<Vec<Vec<Vec3>>, String>
Derivatives beyond the domain (§3.15). The extension is C¹: first derivatives follow the ruled/bilinear extension, second derivatives are taken at the boundary anchor (zero across an extended direction).
pub fn derivatives( &self, u: f64, v: f64, derivative_count: usize, ) -> Result<Vec<Vec<Vec3>>, String>
pub fn normal(&self, u: f64, v: f64) -> Result<Vec3, String>
Sourcepub fn principal_curvatures(&self, u: f64, v: f64) -> Result<(f64, f64), String>
pub fn principal_curvatures(&self, u: f64, v: f64) -> Result<(f64, f64), String>
Principal curvatures (κ_min, κ_max) at (u, v), signed with respect to the parametrization normal n = Su × Sv / |Su × Sv| via the shape operator I⁻¹·II. Convention check: a cylinder of radius R whose normal points AWAY from the axis has κ = −1/R along the circular direction, so an offset’s regularity factor 1 − d·κ vanishes exactly when an inward offset (d = −R) reaches the axis.
Sourcepub fn is_affine(&self) -> Result<bool, String>
pub fn is_affine(&self) -> Result<bool, String>
Whether this is a genuinely affine degree-1 by degree-1 patch.
A tapered bilinear patch is planar but not affine, so degree alone is insufficient for exact inverse-parameter and integration shortcuts.