File Exchange

image thumbnail

NURBS Toolbox by D.M. Spink

version 1.0.0.0 (42.9 KB) by Penguian
NURBS Toolbox by D.M. Spink re-uploaded. The previous link has broken.

59 Downloads

Updated 15 Jan 2010

View License

NURBS Toolbox official site is
http://www.aria.uklinux.net/nurbs.php3

% NURBS Toolbox.
% Version 1.0
%
% demos - NURBS demonstrations
%
% nrbmak - Construct a NURBS from control points and knots.
% nrbtform - Applying scaling, translation or rotation operators.
% nrbkntins - Knot insertion/refinement.
% nrbdegelev - Degree elevation.
% nrbderiv - NURBS representation of the derivative.
% nrbdeval - Evaluation of the NURBS derivative.
% nrbkntmult - Find the multiplilicity of a knot vector.
% nrbreverse - Reverse evaluation direction of the NURBS.
% nrbtransp - Swap U and V for NURBS surface.
% nrbline - Construct a straight line.
% nrbcirc - Construct a circular arc.
% nrbrect - Construct a rectangle.
% nrb4surf - Surface defined by 4 corner points.
% nrbeval - Evalution of NURBS curve or surface.
% nrbextrude - Extrude a NURBS curve along a vector.
% nrbrevolve - Construct surface by revolving a profile.
% nrbruled - Ruled surface between twp NURBS curves.
% nrbcoons - Construct Coons bilinearly blended surface patch.
% nrbplot - Plot NURBS curve or surface.
%
% bspeval - Evaluate a univariate B-Spline.
% bspderiv - B-Spline representation of the derivative
% bspkntins - Insert a knot or knots into a univariate B-Spline.
% bspdegelev - Degree elevation of a univariate B-Spline.
%
% vecnorm - Normalise the vectors.
% vecmag - Magnitaude of the vectors.
% vecmag2 - Squared Magnitude of the vectors.
% vecangle - Alternative to atan2 (0 <= angle <= 2*pi)
% vecdot - Dot product of two vectors.
% veccross - Cross product of two vectors.
% vecrotx - Rotation matrix around the x-axis.
% vecroty - Rotation matrix around the y-axis.
% vecrotz - Rotation matrix around the z-axis.
% vecscale - Scaling matrix.
% vectrans - Translation matrix.
%
% deg2rad - Convert degrees to radians.
% rad2deg - Convert radians to degrees.

Cite As

Penguian (2020). NURBS Toolbox by D.M. Spink (https://www.mathworks.com/matlabcentral/fileexchange/26390-nurbs-toolbox-by-d-m-spink), MATLAB Central File Exchange. Retrieved .

Comments and Ratings (50)

Penguian

I have again been contacted about this Toolbox. I have never known anything about it. If nobody offers to take it over by 31 December 2020, I *will* delete it. You have been warned.

There are alternatives. See for example:
https://octave.sourceforge.io/nurbs/index.html
http://runten.tripod.com/NURBS/
https://www.rhino3d.com/opennurbs

kaan cimen

How can I calculate the second derivative?

TIANRAN LIU

Penguian

Does anyone want to take over this toolbox? I really know nothing abouth this software and how it works.

ZR

Fantastic toolbox. However, is it limited to open knots only as i want to use general knot but its knot refinement function is not working for it?

Alex Martiner

Fantastic toolbox! I'm also searching for the second derivative.. does anyone got any solutions yet?

Raine Yeh

Is this really NURBS? This looks like NUBS to me (non-uniform B-spline, not rational B-spline).

SACHIN S ANAND

@hamid Alavi, I tried what you suggested, but the issue seems to still exist in findspan.

Hamid Alavi

a problem with degelev.m!
can anyone help me with this?
the problem is that when i create a bspline with unclamped uniform knot vector, an error occurs when i want to increase the degree of that bspilne using nrbdegelev.m.
for example suppose that we create a unclamped closed bspline with uniform knots such as:
p = 2; %degree
n = 7; %number of control points - 1
m = n+p+1; %number of knots - 1
U = linspace(0,1,m+1); %unclamped uniform knot vector
theta = (0:n+1-p-1)*2*pi/(n+1-p);
x = cos(theta);
y = sin(theta);
x = [x x(1:p)]; %wrapping the last p and the first p control points
y = [y y(1:p)]; %wrapping the last p and the first p control points
G = [x;y;zeros(1,n+1)]; %control points
w = ones(1,n+1); %weights
Gw = [G.*w;w]; %convert to homogenuous coordinates
crv = nrbmak(Gw,U); %creating bspline structure
crv_degelev = nrbdegelev(crv,1); %increase crv degree by 1

and here we get the ERROR:

Index exceeds matrix dimensions.

Error in bspdegelev (line 240)
bpts(ii+1,j+1) = c(ii+1,b-d+j+1); % bpts[j][ii] = ctrl[b-d+j][ii];

Error in nrbdegelev (line 92)
[coefs,knots] = bspdegelev(degree,nurbs.coefs,nurbs.knots,ntimes);

can anyone HELP to fix this error???

Hamid Alavi

infinite loop in find span fixed!!
i think the reason that the infinite loop occurs is that the domain of the bspline in the nrbplot.m is set to [0,1]!
this domain is not true for all bsplines! it is better to define the domain as [u(p),u(n+1)] so to fix the infinite loop issue, i suggest a modification in the nrbplot.m. copy and paste this code to fix infinite loop issue:
function nrbplot(nurbs,subd,p1,v1)
%
% Function Name:
%
% nrbplot - Plot a NURBS curve or surface.
%
% Calling Sequence:
%
% nrbplot(nrb,subd)
% nrbplot(nrb,subd,p,v)
%
% Parameters:
%
%
% nrb : NURBS curve or surface, see nrbmak.
%
% npnts : Number of evaluation points, for a surface a row vector
% with two elements for the number of points along the U and
% V directions respectively.
%
% [p,v] : property/value options
%
% Valid property/value pairs include:
%
% Property Value/{Default}
% -----------------------------------
% light {off} | true
% colormap {'copper'}
%
% Example:
%
% Plot the test surface with 20 points along the U direction
% and 30 along the V direction
%
% plot(nrbtestsrf, [20 30])

% D.M. Spink
% Copyright (c) 2000.

nargs = nargin;
if nargs < 2
error('Need a NURBS to plot and the number of subdivisions!');
elseif rem(nargs+2,2)
error('Param value pairs expected')
end

% Default values
light='off';
cmap='copper';

% Recover Param/Value pairs from argument list
for i=3:2:nargs
Param = eval(['p' int2str((i-3)/2 +1)]);
Value = eval(['v' int2str((i-3)/2 +1)]);
if ~isstr(Param)
error('Parameter must be a string')
elseif size(Param,1)~=1
error('Parameter must be a non-empty single row string.')
end
switch lower(Param)
case 'light'
light = lower(Value);
if ~isstr(light)
error('light must be a string.')
elseif ~(strcmp(light,'off') | strcmp(light,'on'))
error('light must be off | on')
end
case 'colormap'
if isstr(Value)
cmap = lower(Value);
elseif size(Value,2) ~= 3
error('colormap must be a string or have exactly three columns.')
else
cmap=Value;
end
otherwise
error(['Unknown parameter: ' Param])
end
end

colormap('default');

% convert the number of subdivisions in number of points
subd = subd+1;

% plot the curve or surface
if iscell(nurbs.knots)
% plot a NURBS surface
% p = nrbeval(nurbs,{linspace(0.0,1.0,subd(1)) linspace(0.0,1.0,subd(2))});
U = nurbs.knots{1};
V = nurbs.knots{2};
degree = nurbs.order-1;
p = nrbeval(nurbs,{linspace(U(degree(1)+1),U(nurbs.number(1)+1),subd(1)) linspace(V(degree(2)+1),V(nurbs.number(2)+1),subd(2))});
if strcmp(light,'on')
% light surface
surfl(squeeze(p(1,:,:)),squeeze(p(2,:,:)),squeeze(p(3,:,:)));
shading interp;
colormap(cmap);
else
surf(squeeze(p(1,:,:)),squeeze(p(2,:,:)),squeeze(p(3,:,:)));
shading faceted;
end
else
% plot a NURBS curve
% p = nrbeval(nurbs,linspace(0.0,1.0,subd));
U = nurbs.knots;
degree = nurbs.order-1;
p = nrbeval(nurbs,linspace(U(degree(1)+1),U(nurbs.number(1)+1),subd(1)));
if any(nurbs.coefs(3,:))
% 3D curve
plot3(p(1,:),p(2,:),p(3,:));
grid on;
else
% 2D curve
plot(p(1,:),p(2,:));
end
end
axis equal;

asasdasdasdadsadasd

Andrew Pidgeon

@DC Oops, my mistake you're correct it should have been a break.

David Crosby

@Andre Pidgeon But if we change the "continue" to "break" in your code then that seems to work. i.e.:
line 40 (old): mid = floor((low + high) / 2);
line 41 (new): if low == mid && high - mid <= 1
line 42 (new): break
line 43 (new): end
line 44 (old line 41): end

David Crosby

@Andrew Pidgeon I don't think that fixes the problem if specifying a parametric coordinate outside the range covered by the knot vector. Also the current modification proposed by you doesn't do anything - if the test condition is true then the loop repeats without doing anything else but as this statement is at the end of the loop anyway it doesn't make any difference. As long as the knot sequence is increasing I think my change works fine - although I always clamp my NURBS so I haven't tested with unclamped.

Andrew Pidgeon

It looks like the problem with FindSpan.m comes when the values of the variables "low", "mid" and "high" have the same values, or where "high" is larger by 1.

It looks like the infinite loop problem/condition can be fixed by adding the following escape between lines 40 and 41.
i.e.
mid = floor((low + high) / 2);
if low == mid && high - mid <= 1
continue
end
end

David Crosby

To stop the infinite loop with FindSpan you should just add some code to handle parametric coordinates at/beyond the end-points of the knot vector. E.g. add these lines at the start of the function.
if u >= U(n+2), s=n; return, end
if u <= U(1), s=p; return, end

Bradley Redlin

Has anyone corrected the infinite loop that occurs in FindSpan? Can not figure out how to correct it.

Sumanth Srinivasan

How can one ensure that two splines join with C2 continuity between them? I know that for C2 continuity, one has to make sure that the second derivative is zero at the end point. To do so, we need a function for calculating the second derivative right? Would finding the derivative of the first derivative do the job because its mathematically true. But I havent done extensive research on these mat files. I just started using this tool box. Can anyone help me with this problem?

Alexander Laut

Is there a way to export a given NURBS surface into a file that is recognized by CAD software. I'd imagine something like IGES or STEP would be sufficient but I can't seem to find any resource that illustrates how to do this.

From the examples, it become apparent how to export the evaluated surfaces as a mesh like STL and there are resources out there like stlwrite.m and stlread.m. that takes (x,y,z,con). Is there an equivlanet nurbs2iges.m that might take (ctrl, knots, order)

Suraj Pawar

Is there any way to extract the points on the Nurbs curve?

cuneyt haspolat

I want to add elements to pnts like that
pnts = [0.5 1.5 4.5 3.0 7.5 6.0 8.5 10 12 14 16;
3.0 5.5 5.5 1.5 1.5 4.0 4.5 5.5 6.5 7.5 8.5;
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0];
but I got errors which is
Subscript indices must either be real positive integers or logicals.

Error in nrbplot (line 132)
p = nrbeval (nurbs, linspace (nurbs.knots(order), nurbs.knots(end-order+1), subd));

Error in deneme (line 82)
nrbplot(crv,48);
Do you have any suggestion?
My code given below.
% crv = nrbtestcrv;
pnts = [0.5 1.5 4.5 3.0 7.5 6.0 8.5;
3.0 5.5 5.5 1.5 1.5 4.0 4.5;
0.0 0.0 0.0 0.0 0.0 0.0 0.0];
crv = nrbmak(pnts,[0 0 0 1/4 1/2 3/4 3/4 1 1 1]);


% plot the control points
plot(crv.coefs(1,:),crv.coefs(2,:),'ro');
title('Arbitrary Test 2D Curve.');
hold on;
plot(crv.coefs(1,:),crv.coefs(2,:),'r--');

% plot the nurbs curve
nrbplot(crv,48);
hold off;

crv.knots(3)=0.1;
figure
% plot the control points
plot(crv.coefs(1,:),crv.coefs(2,:),'ro');
title('Arbitrary Test 2D Curve.');
hold on;
plot(crv.coefs(1,:),crv.coefs(2,:),'r--');

% plot the nurbs curve
nrbplot(crv,48);
hold off;

Michele Galullo

great job.. thank you!!

zhao zhang

Thank you so much! This is very helpful for my research!

Zuowei Zhu

Great toolbox! Still learning it but it's of great help!

Giuliana Galaz

Second dérivatives of NURBS are missing

NURBS2Dders.m???

youhuo huang

Very useful toolbox, thank you very much!

Chung-Chan Hsu

Mi Chang

How to evaluate the disance between points and NURBS surface quickly?Is there a available function?Thanks a lot.

Raoul Herzog

There is a bug in findspan.m (infinite loop) if the evaluation point is at the end points with roundoff error.

Second dérivatives of NURBS are missing.

Is this project still active ?

Ocean

I can't find which function could plot NUBRS surface,and always get erroes warnings

Christoph Schemmann

Thanks for the great NURBS adaption.
For one project i missed global approximation so i added my own function:

function [ CP,KV ] = globalInterp( Q,deg )
%GLOBALINTERPH Global Curveinterpolation
A = zeros(size(Q,1),size(Q,1));

% Centripetal Parametrisation
ub = paramCentripetal(Q);

% Centripetal Knotvector
KV = setKVcentripetal(size(Q,1),deg,ub)';

% Initialize Basis Matrix A
for i=2:size(Q,1)-1
span = findspan(size(Q,1),deg,ub(i),KV);
N = basisfun(span,ub(i),deg,KV);
l = span-deg;
for k=1:deg
A(i,l+k) = N(k);
end
end
% Set first and last Matrix Value
A(1,1) = 1.0;
A(size(Q,1),size(Q,1)) = 1.0;

% Solve
tmp = A\Q;

% Save Control Points
CP = [tmp(:,1) tmp(:,2) tmp(:,3)]';
end

function [ KV ] = setKVcentripetal( n,p,u )
%SETKVCENTRIPETAL Generates a Knot Vektor matching parametrization u
KV = zeros(n+p,1);

for i=size(KV,1)-p:size(KV,1)
KV(i) = 1.0;
end

for j=1:size(u,1)-p
tmp = 0.0;
for i=j:j+p-1
tmp = tmp+u(i);
end
KV(j+p) = tmp/p;
end
end

function [ uc ] = paramCentripetal( points )
%PARAMCENTRIPETAL Centripetal parametrization for given points
uc = zeros(size(points,1),1);

uc(1) = 0.0;
d = 0.0;
for i=2:size(uc,1)
d = d + pdist([points(i,:);points(i-1,:)]);
end
for i=2:size(uc,1)-1
uc(i) = uc(i-1) + pdist([points(i,:);points(i-1,:)])/d;
end
uc(size(uc,1)) = 1.0;
end

Maybe someone else will find this useful.

Greetings Christoph

Malte

Hi Paul, this is great, thanks a lot! I am using it for several projects. However, for one application I would like to have the condition, that the 3D surface is tangential to every curve (contour). Is there such an option or where do I need to hook? Best regards!

Patrick

There is a bug in nrbcoons.m, at line 82. all 'u's should be replaced with 'v's - the ruled surfaces and bilinear surfaces generated are equivalent but not in directly-addable representations in the current code.

mirui wang

I think we need a document to explain all the function and how to use.

miodrag

miodrag

good works.thanks

Pourya Alinezhad

good work... thanks .

Erik

When running democurve.m, execution get stuck in an infinite loop in findspan.m.

Can I find the original c-files somewhere, before conversion of all files to m-files?

Axel L

Hello,

How to evaluate the second derivate of nurbs with this toolbox ?

Axel L

Hello,

Thank for this useful toolbox.
How to get the rational basis function of nurbs with this toolbox ?

faculaganymede

Daniel Lopes

There are bugs that make this toolbox uncompatible with the Nurbs2IGES
(http://www.mathworks.com/matlabcentral/fileexchange/12087-nurbs2iges).

Li

csg Chen

csg Chen

This toolbox is very useful. It can improve many problems in my applications. However, it seems some small bugs when I evaluate the derivative of nurbs curves/surfaces.
In the file "nrbderiv ":
this file call the function "bspderiv". If the weights of the original nurbs curve/surface are equal ( example: the weight = 1 at each vertex ), this weights of nurbs curve/surface vanish after call bspderiv in file nrbderiv.
Maybe, we should revise the file "nrbderiv" before calling the function "bspderiv" to preserve the original weights.

GAURAV

I have a set of points say 300 something following the outline of cerebral aneurysm. I want to smooth this curve using the NURBS tool box provided here. How do i use this ? Where do I give my input? I just need a Bspline fitting to the data I have i.e. effectively to smooth the outline of the trace I have. Help me out..
Thanks!

Evgeny Pr

Hello!
Where can I get C-implementation of this toolbox?

Oliver

Very useful toolbox, thank you very much! Also very well commented and good examples.

MATLAB Release Compatibility
Created with R14
Compatible with any release
Platform Compatibility
Windows macOS Linux
Acknowledgements

Inspired by: NURBS

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!