BSplineCurve3dBase Class

Base class for BSplineCurve3d and BSplineCurve3dH.

  • A B-spline curve consists of an array of knots, an array of poles, and a degree.
  • The knot array is a non-decreasing sequence of numbers. It is also called a "knot vector".
    • The curve is a parametric function whose domain is a sub-range of its knots.
    • The API sometimes refers to a domain parameter u as a "knot", even if u is not actually an entry in the knot array.
  • The curve loosely "follows" the line string formed by the poles, aka the "control polygon".
  • The curve is a chain of polynomial segments, aka "spans" or "fragments". B-spline theory identifies these as Bezier curves.
  • The polynomial spans all have same degree.
  • Each span is controlled by order = degree + 1 contiguous points in the pole array.
  • There is a strict relationship between knot and poles counts: `numPoles + order = numKnots + 2'.
  • The number of spans is numSpan = numPoles - degree.
  • For a span with index spanIndex:
    • The order relevant poles begin at pole index spanIndex.
    • The 2*degree relevant knots begin at knot index spanIndex.
    • The span domain is the knot range [knot[spanIndex+degree-1], knot[spanIndex+degree]].
  • The curve domain is the knot range [knot[degree-1], knot[numSpan+degree-1]], or equivalently [knot[degree-1], knot[numPoles-1]]. The API refers to this domain as the "active knot interval" of the curve.

Nearly all B-spline curves are "clamped".

  • This means that in the knots array, the first degree knots are equal, and the last degree knots are equal. We say the smallest knot and the largest knot have multiplicity degree.

  • Clamping make the curve pass through its first and last poles, with tangents directed along the first and last edges of the control polygon.

  • For instance, a cubic B-spline curve with knot vector [0,0,0,1,2,3,3,3]

    • can be evaluated at parameter values in the range [0, 3]
    • has 3 spans, with domains [0, 1], [1, 2], and [2, 3]
    • has 6 poles
    • passes through its first and last poles.
  • The create methods may allow the classic convention that has an extra knot at the beginning and end of the knot vector.

    • These two extra knots are not actually needed to define the B-spline curve.
    • When the create methods recognize the classic setup (numPoles + order = numKnots), the extra knots are not saved with the BSplineCurve3dBase knots.
  • The weighted variant BSplineCurve3dH has the problem that CurvePrimitive 3D typing does not allow the undefined result where a homogeneous pole has zero weight; the convention in this case is to return 000.

  • Note the class relationships:

    • BSpline1dNd knows the definitional B-spline recurrence relation with no physical interpretation for the poles.
    • BsplineCurve3dBase owns a protected BSpline1dNd.
    • BsplineCurve3dBase is derived from CurvePrimitive, which creates obligation to act as a 3D curve, e.g.,
      • evaluate fraction to point and derivatives wrt fraction.
      • compute intersection with plane.
    • BSplineCurve3d and BSplineCurve3dH have variant logic driven by whether or not there are "weights" on the poles.
      • For BSplineCurve3d, the xyz value of pole calculations are "final" values for 3d evaluation.
      • For BSplineCurve3dH, various BSpline1dNd results with xyzw have to be normalized back to xyz.
  • These classes do not support "periodic" variants.

    • Periodic curves historically have carried a flag (e.g., "closed") indicating that certain un-stored leading/trailing knots and poles are understood to wrap around periodically.
    • Instead, these classes carry no such flag. They represent such curves with explicitly wrapped knots/poles.
  • Visualization can be found at https://www.itwinjs.org/sandbox/SaeedTorabi/BSpline/

Extends

Extended by

Methods

Name Description
constructor(poleDimension: number, numPoles: number, order: number, knots: KnotVector): BSplineCurve3dBase Protected    
appendPlaneIntersectionPoints(plane: PlaneAltitudeEvaluator, result: CurveLocationDetail[]): number Implement CurvePrimitive.appendPlaneIntersections to compute intersections of the curve with a plane.  
clone(): BSplineCurve3dBase Abstract Return a deep clone.  
clonePartialCurve(fractionA: number, fractionB: number): BSplineCurve3dBase Return a curve primitive which is a portion of this curve.  
cloneTransformed(transform: Transform): BSplineCurve3dBase Return a transformed deep clone.  
closestPoint(spacePoint: Point3d, _extend: VariantCurveExtendParameter, result?: CurveLocationDetail): undefined | CurveLocationDetail Search for the curve point that is closest to the spacePoint.  
collectBezierSpans(prefer3dH: boolean): BezierCurveBase[] Return an array with this curve's Bezier fragments.  
constructOffsetXY(offsetDistanceOrOptions: number | OffsetOptions): undefined | BSplineCurve3d Construct an offset of the instance curve as viewed in the xy-plane (ignoring z).  
copyKnots(includeExtraEndKnot: boolean): number[] Return a simple array form of the knots.  
endPoint(): Point3d Return the end point of the curve.  
evaluatePointAndDerivativeInSpan(spanIndex: number, spanFraction: number, result?: Ray3d): Ray3d Abstract Evaluate the curve and derivative at a fractional position within a given span.  
evaluatePointInSpan(spanIndex: number, spanFraction: number, result?: Point3d): Point3d Abstract Evaluate the curve at a fractional position within a given span.  
fractionToPoint(fraction: number, result?: Point3d): Point3d Evaluate the curve point at the given fractional parameter.  
fractionToPointAnd2Derivatives(fraction: number, result?: Plane3dByOriginAndVectors): Plane3dByOriginAndVectors Evaluate the curve and two derivatives at the given fractional parameter.  
fractionToPointAndDerivative(fraction: number, result?: Ray3d): Ray3d Evaluate the curve and derivative at the given fractional parameter.  
getPolePoint3d(poleIndex: number, result?: Point3d): undefined | Point3d Abstract Return a specified pole as a Point3d.  
getPolePoint4d(poleIndex: number, result?: Point4d): undefined | Point4d Abstract Return a specified pole as a Point4d.  
getSaturatedBezierSpan3dOr3dH(spanIndex: number, prefer3dH: boolean, result?: BezierCurveBase): undefined | BezierCurveBase Abstract Return the Bezier fragment corresponding to the given span of this curve.  
getWrappable(): BSplineWrapMode Get the flag indicating the curve might be suitable for having wrapped "closed" interpretation.  
knotToPoint(knot: number, result?: Point3d): Point3d Abstract Evaluate the curve at the given parameter.  
knotToPointAnd2Derivatives(knot: number, result?: Plane3dByOriginAndVectors): Plane3dByOriginAndVectors Abstract Evaluate the curve and two derivatives at the given parameter.  
knotToPointAndDerivative(knot: number, result?: Ray3d): Ray3d Abstract Evaluate the curve and derivative at the given parameter.  
poleIndexToDataIndex(poleIndex: number): undefined | number Given a pole index, return the starting index for the contiguous array.  
projectedParameterRange(ray: Vector3d | Ray3d, lowHigh?: Range1d): undefined | Range1d Project instance geometry (via dispatch) onto the given ray, and return the extreme fractional parameters  
reverseInPlace(): void Reverse the curve in place.  
setWrappable(value: BSplineWrapMode): void Set the flag indicating the curve might be suitable for having wrapped "closed" interpretation.  
startPoint(): Point3d Return the start point of the curve.  

Inherited methods

Name Inherited from Description
addMappedStrokesToLineString3D(map: StrokeCountMap, linestring: LineString3d): number Inherited CurvePrimitive Evaluate strokes at fractions indicated in a StrokeCountMap.
announceClipIntervals(_clipper: Clipper, _announce?: AnnounceNumberNumberCurvePrimitive): boolean Inherited CurvePrimitive Find intervals of this curvePrimitive that are interior to a clipper
collectCurvePrimitives(collectorArray?: CurvePrimitive[], smallestPossiblePrimitives: booleanfalse, explodeLinestrings: booleanfalse): CurvePrimitive[] Inherited CurvePrimitive Return an array containing only the curve primitives.
collectCurvePrimitivesGo(collectorArray: CurvePrimitive[], _smallestPossiblePrimitives: boolean, _explodeLinestrings: booleanfalse): void Inherited CurvePrimitive Return an array containing only the curve primitives.
computeAndAttachRecursiveStrokeCounts(options?: StrokeOptions, parentMap?: StrokeCountMap): void Inherited CurvePrimitive Attach StrokeCountMap structure to this primitive (and recursively to any children)
computeStrokeCountForOptions(options?: StrokeOptions): number Abstract Inherited CurvePrimitive Return the stroke count required for given options.
curveLength(): number Inherited CurvePrimitive Return the length of the curve.
curveLengthBetweenFractions(fraction0: number, fraction1: number): number Inherited CurvePrimitive Returns a (high accuracy) length of the curve between fractional positions.
curveLengthWithFixedIntervalCountQuadrature(fraction0: number, fraction1: number, numInterval: number, numGauss: number5): number Inherited CurvePrimitive Run an integration (with a default Gaussian quadrature) with a fixed fractional step
dispatchToGeometryHandler(handler: GeometryHandler): any Abstract Inherited CurvePrimitive Double Dispatch call pattern.
emitStrokableParts(dest: IStrokeHandler, options?: StrokeOptions): void Abstract Inherited CurvePrimitive Ask the curve to announce points and simple subcurve fragments for stroking.
emitStrokes(dest: LineString3d, options?: StrokeOptions): void Abstract Inherited CurvePrimitive Add strokes to caller-supplied linestring (function updates dest)
extendRange(rangeToExtend: Range3d, transform?: Transform): void Abstract Inherited CurvePrimitive Extend rangeToExtend by the range of this geometry multiplied by the transform.
fractionAndDistanceToPointOnTangent(fraction: number, distance: number): Point3d Inherited CurvePrimitive Construct a point extrapolated along tangent at fraction.
fractionToCurvature(fraction: number): undefined | number Inherited CurvePrimitive Returns the (absolute) curvature magnitude.
fractionToFrenetFrame(fraction: number, result?: Transform): undefined | Transform Inherited CurvePrimitive Construct a frenet frame:
fractionToPointAndUnitTangent(fraction: number, result?: Ray3d): Ray3d Inherited CurvePrimitive Returns a ray whose origin is the curve point and direction is the unit tangent.
fractionToSignedXYRadiusOfCurvature(fraction: number): number Inherited CurvePrimitive Construct signed distance from a point on the planar curve to its center of curvature (in xy only).
getFractionToDistanceScale(): undefined | number Inherited CurvePrimitive If the curve primitive has distance-along-curve strictly proportional to curve fraction, return the scale factor.
isAlmostEqual(other: GeometryQuery): boolean Inherited CurvePrimitive Test for exact structure and nearly identical geometry.
isInPlane(plane: Plane3dByOriginAndUnitNormal): boolean Abstract Inherited CurvePrimitive Ask if the curve is within tolerance of a plane.
isSameGeometryClass(other: GeometryQuery): boolean Abstract Inherited CurvePrimitive Test if (other instanceof this.Type).
moveSignedDistanceFromFraction(startFraction: number, signedDistance: number, allowExtension: boolean, result?: CurveLocationDetail): CurveLocationDetail Inherited CurvePrimitive (Attempt to) find a position on the curve at a signed distance from start fraction.
moveSignedDistanceFromFractionGeneric(startFraction: number, signedDistance: number, allowExtension: boolean, result?: CurveLocationDetail): CurveLocationDetail Protected Inherited CurvePrimitive Generic algorithm to search for point at signed distance from a fractional startPoint.
quickLength(): number Abstract Inherited CurvePrimitive Compute a length for curve which may be a fast approximation to the true length.
range(transform?: Transform, result?: Range3d): Range3d Inherited CurvePrimitive Return the range of the entire GeometryQuery tree.
rangeBetweenFractions(fraction0: number, fraction1: number, transform?: Transform): Range3d Inherited CurvePrimitive Returns the range of the curve between fractional positions.
rangeBetweenFractionsByClone(fraction0: number, fraction1: number, transform?: Transform): Range3d Inherited CurvePrimitive Returns a high accuracy range of the curve between fractional positions using clonePartialCurve.
rangeBetweenFractionsByCount(fraction0: number, fraction1: number, count: number, transform?: Transform, extrapolationFactor: number0.0): Range3d Inherited CurvePrimitive Returns an approximate range based on a fixed number of evaluations.
tryTransformInPlace(transform: Transform): boolean Abstract Inherited CurvePrimitive Attempt to transform in place.
tryTranslateInPlace(dx: number, dy: number0.0, dz: number0.0): boolean Inherited CurvePrimitive Try to move the geometry by dx,dy,dz.
areAlmostEqual(a: GeometryQuery, b: GeometryQuery): boolean Static Inherited CurvePrimitive Apply instance method isAlmostEqual if both are defined.
installStrokeCountMap(curve: CurvePrimitive, curveMap: StrokeCountMap, parentMap?: StrokeCountMap): void Static Inherited CurvePrimitive Final install step to save curveMap in curve.

Properties

Name Type Description
_bcurve Protected BSpline1dNd The underlying blocked-pole spline, with simple x,y,z poles.  
curvePrimitiveType Readonly "bsplineCurve" String name for schema properties.  
definitionData Accessor any    
degree Accessor ReadOnly number Return the degree (one less than the order) of the curve.  
isClosableCurve Accessor ReadOnly BSplineWrapMode Test knots and poles to determine if it is possible to close (aka "wrap") the curve.  
knotsRef Accessor ReadOnly Float64Array Return live reference to the knots of the curve.  
numPoles Accessor ReadOnly number Return the number of poles.  
numSpan Accessor ReadOnly number Return the number of Bezier spans in the curve.  
order Accessor ReadOnly number Return the order (one more than degree) of the curve.  
poleDimension Accessor ReadOnly number Number of components per pole, e.g.,  
polesRef Accessor ReadOnly Float64Array Return live reference to the poles of the curve.  

Inherited properties

Name Type Inherited from Description
children Accessor Inherited ReadOnly undefined | GeometryQuery[] CurvePrimitive Return GeometryQuery children for recursive queries.
* leaf classes do not need to implement.
geometryCategory Readonly Inherited "curvePrimitive" CurvePrimitive String name for schema properties
isExtensibleFractionSpace Accessor Inherited ReadOnly boolean CurvePrimitive * Returns true if the curve can be easily extended past its start/end point (i.e., beyond the usual
fraction space [0,1]). Otherwise, returns false.
* Base class default implementation returns false.
* These classes (and perhaps others in the future) will return true:
* LineSegment3d
* LineString3d
* Arc3d
parent Inherited any | undefined CurvePrimitive Data attached by various algorithms (e.g.
strokeData Inherited StrokeCountMap | undefined CurvePrimitive Data attached during stroking for facets.

Defined in

Last Updated: 21 February, 2025