Computes the nonvanishing basis functions based on Algorithm A2.2 in the NURBS Book 1.
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
Assuming is in the th span, , computation of the nonzero functions results in an inverted triangular scheme
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.
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
We introduce the notation
Piegl, L., and Tiller, W., (1995) The NURBS Book, Springer, Berlin, Heidelberg. ↩
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
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 |
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