BasisFuns Subroutine

private pure subroutine BasisFuns(me, u, N, span)

Computes the nonvanishing basis functions based on Algorithm A2.2 in the NURBS Book 1.

Implementation Details of Algorithm A2.2

Let be a nondecreasing sequence of real numbers, i.e., , . The are called knots, and is the knot vector. The th B-spline basis function of -degree (order ), denoted by , is defined by Cox-de Boor recursion formula.

Note that

  • is a step function, equal to zero everywhere except on the half-open interval ;
  • for , is a linear combination of two ()-degree basis functions
  • computation of a set of basis functions requires specification of a knot vector, , and the degree, ;
  • Equation (2.5) can yield the quotient ; we define this quotient to be zero
  • the half-open interval, , is called the th knot span; it can have zero length, since knots need not be distinct

Assuming is in the th span, , computation of the nonzero functions results in an inverted triangular scheme

Algorithm 2.2

Algorithm computes all of the non-vanishing basis functions in an efficient way, see example, and return them in the array N(0:p). There is no risk of division by zero as we can encounter in Cox-de Boor recursion formula.

Note: This algorithm applies to rational basis functions.

Ex2.3 Nonvanishing Basis Functions

There is a great deal of redundant computation inherent in Cox-de Boor recursion formula. For example, writing out the second-degree functions in general terms, we have

Note that

  • the first term of Eq. (2.14) and the last term of Eq. (2.16) are not computed, since ;
  • the expression which appears in the second term of Eq. (2.14) appears in the first term of Eq. (2.15); a similar statement holds for the second term of Eq. (2.15) and the first term of Eq. (2.16).

We introduce the notation

Eq. (2.15-2.16) are then



  1. Piegl, L., and Tiller, W., (1995) The NURBS Book, Springer, Berlin, Heidelberg. 

Arguments

Type IntentOptional AttributesName
class(basis), intent(in) :: me
real(kind=wp), intent(in) :: u

Given value

real(kind=wp), intent(out) :: N(0:me%p)

integer, intent(in), optional :: span

Knot span where lies on


Calls

proc~~basisfuns~~CallsGraph proc~basisfuns BasisFuns ui ui proc~basisfuns->ui

Contents

Source Code


Source Code

        pure subroutine BasisFuns(me,u,N,span)
            class(basis), intent(in)                :: me
            real(wp),       intent(in)              :: u            !< Given \( u \) value
            integer,        intent(in), optional    :: span         !< Knot span where \( u \) lies on
            real(wp),       intent(out)             :: N(0:me%p)    !< \( =  \{ N_{i-p,p}(u) \ldots N_{i,p}(u)\} \)
            !locals
            integer     :: i    !< Knot span index
            integer     :: j, r
            real(wp)    :: left(me%p), right(me%p), saved, temp!, w
            
            associate( p => me%p, Ui => me%kv ) !get rid of % signs
                
            ! set the knot span
            if(present(span))then
                i = span
            else
                i = me%FindSpan(u)
            end if

            N = 0.0_wp; right=0.0_wp; left=0.0_wp
            
            N(0) = 1.0_wp
            do j = 1, p
            left(j)  = u - Ui(i+1-j)
            right(j) = Ui(i+j) - u
            saved = 0.0_wp
            do r = 0, j-1
                temp = N(r) / (right(r+1) + left(j-r))
                N(r) = saved + right(r+1) * temp
                saved = left(j-r) * temp
            end do
            N(j) = saved
            end do

            ! if(me%rational)then
            !     w = sum(N(:)*me%w(i-p:i))
            !     do j = 0, me%p
            !         N(j) = N(j)*me%w(j) / w
            !     end do
            ! end if
                
            end associate
            
        end subroutine BasisFuns