1function inurbs = nrbkntins(nurbs,iknots) 2% 3% NRBKNTINS: Insert a single or multiple knots into a NURBS curve, 4% surface or volume. 5% 6% Calling Sequence: 7% 8% icrv = nrbkntins(crv,iuknots); 9% isrf = nrbkntins(srf,{iuknots ivknots}); 10% ivol = nrbkntins(vol,{iuknots ivknots iwknots}); 11% 12% INPUT: 13% 14% crv : NURBS curve, see nrbmak. 15% 16% srf : NURBS surface, see nrbmak. 17% 18% srf : NURBS volume, see nrbmak. 19% 20% iuknots : Knots to be inserted along U direction. 21% 22% ivknots : Knots to be inserted along V direction. 23% 24% iwknots : Knots to be inserted along W direction. 25% 26% OUTPUT: 27% 28% icrv : new NURBS structure for a curve with knots inserted. 29% 30% isrf : new NURBS structure for a surface with knots inserted. 31% 32% ivol : new NURBS structure for a volume with knots inserted. 33% 34% Description: 35% 36% Inserts knots into the NURBS data structure, these can be knots at 37% new positions or at the location of existing knots to increase the 38% multiplicity. The knot multiplicity can be increased up to the order of 39% the spline. Any further increase of the multiplicity will generate zero 40% basis functions, but not cause any error in the code. 41% This function use the B-Spline function bspkntins, which interfaces to 42% an internal 'C' routine. 43% 44% Examples: 45% 46% Insert two knots into a curve, one at 0.3 and another 47% twice at 0.4 48% 49% icrv = nrbkntins(crv, [0.3 0.4 0.4]) 50% 51% Insert into a surface two knots as (1) into the U knot 52% sequence and one knot into the V knot sequence at 0.5. 53% 54% isrf = nrbkntins(srf, {[0.3 0.4 0.4] [0.5]}) 55% 56% See also: 57% 58% bspkntins 59% 60% Note: 61% 62% The knot multiplicty can be increased beyond the order of the spline 63% without causing errors, but the added basis functions will be equal to 64% zero. 65% 66% Copyright (C) 2000 Mark Spink, 2010 Rafael Vazquez 67% 68% This program is free software: you can redistribute it and/or modify 69% it under the terms of the GNU General Public License as published by 70% the Free Software Foundation, either version 3 of the License, or 71% (at your option) any later version. 72 73% This program is distributed in the hope that it will be useful, 74% but WITHOUT ANY WARRANTY; without even the implied warranty of 75% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 76% GNU General Public License for more details. 77% 78% You should have received a copy of the GNU General Public License 79% along with this program. If not, see <http://www.gnu.org/licenses/>. 80 81if nargin < 2 82 error('Input argument must include the NURBS and knots to be inserted'); 83end 84 85if ~isstruct(nurbs) 86 error('NURBS representation is not structure!'); 87end 88 89if ~strcmp(nurbs.form,'B-NURBS') 90 error('Not a recognised NURBS representation'); 91end 92 93degree = nurbs.order-1; 94 95if iscell(nurbs.knots) 96 fmax = @(x,y) any (y > max(x)); fmin = @(x,y) any (y < min(x)); 97 if (any(cellfun(fmax, nurbs.knots, iknots)) || any(cellfun(fmin, nurbs.knots, iknots))) 98 error ('Trying to insert a knot outside the interval of definition') 99 end 100 101 if size(nurbs.knots,2)==3 102 % NURBS represents a volume 103 num1 = nurbs.number(1); 104 num2 = nurbs.number(2); 105 num3 = nurbs.number(3); 106 107 % Insert knots along the w direction 108 if isempty(iknots{3}) 109 coefs = nurbs.coefs; 110 knots{3} = nurbs.knots{3}; 111 else 112 coefs = reshape(nurbs.coefs,4*num1*num2,num3); 113 [coefs,knots{3}] = bspkntins(degree(3),coefs,nurbs.knots{3},iknots{3}); 114 num3 = size(coefs,2); 115 coefs = reshape(coefs,[4 num1 num2 num3]); 116 end 117 118 % Insert knots along the v direction 119 if isempty(iknots{2}) 120 knots{2} = nurbs.knots{2}; 121 else 122 coefs = permute(coefs,[1 2 4 3]); 123 coefs = reshape(coefs,4*num1*num3,num2); 124 [coefs,knots{2}] = bspkntins(degree(2),coefs,nurbs.knots{2},iknots{2}); 125 num2 = size(coefs,2); 126 coefs = reshape(coefs,[4 num1 num3 num2]); 127 coefs = permute(coefs,[1 2 4 3]); 128 end 129 130 % Insert knots along the u direction 131 if isempty(iknots{1}) 132 knots{1} = nurbs.knots{1}; 133 else 134 coefs = permute(coefs,[1 3 4 2]); 135 coefs = reshape(coefs,4*num2*num3,num1); 136 [coefs,knots{1}] = bspkntins(degree(1),coefs,nurbs.knots{1},iknots{1}); 137 coefs = reshape(coefs,[4 num2 num3 size(coefs,2)]); 138 coefs = permute(coefs,[1 4 2 3]); 139 end 140 141 elseif size(nurbs.knots,2)==2 142 % NURBS represents a surface 143 num1 = nurbs.number(1); 144 num2 = nurbs.number(2); 145 146 % Insert knots along the v direction 147 if isempty(iknots{2}) 148 coefs = nurbs.coefs; 149 knots{2} = nurbs.knots{2}; 150 else 151 coefs = reshape(nurbs.coefs,4*num1,num2); 152 [coefs,knots{2}] = bspkntins(degree(2),coefs,nurbs.knots{2},iknots{2}); 153 num2 = size(coefs,2); 154 coefs = reshape(coefs,[4 num1 num2]); 155 end 156 157 % Insert knots along the u direction 158 if isempty(iknots{1}) 159 knots{1} = nurbs.knots{1}; 160 else 161 coefs = permute(coefs,[1 3 2]); 162 coefs = reshape(coefs,4*num2,num1); 163 [coefs,knots{1}] = bspkntins(degree(1),coefs,nurbs.knots{1},iknots{1}); 164 coefs = reshape(coefs,[4 num2 size(coefs,2)]); 165 coefs = permute(coefs,[1 3 2]); 166 end 167 end 168else 169 170 if (any(iknots > max(nurbs.knots)) || any(iknots < min(nurbs.knots))) 171 error ('Trying to insert a knot outside the interval of definition') 172 end 173 % NURBS represents a curve 174 if isempty(iknots) 175 coefs = nurbs.coefs; 176 knots = nurbs.knots; 177 else 178 [coefs,knots] = bspkntins(degree,nurbs.coefs,nurbs.knots,iknots); 179 end 180 181end 182 183% construct new NURBS 184inurbs = nrbmak(coefs,knots); 185 186end 187 188%!demo 189%! crv = nrbtestcrv; 190%! plot(crv.coefs(1,:),crv.coefs(2,:),'bo') 191%! title('Knot insertion along test curve: curve and control polygons.'); 192%! hold on; 193%! plot(crv.coefs(1,:),crv.coefs(2,:),'b--'); 194%! 195%! nrbplot(crv,48); 196%! 197%! icrv = nrbkntins(crv,[0.125 0.375 0.625 0.875] ); 198%! plot(icrv.coefs(1,:),icrv.coefs(2,:),'ro') 199%! plot(icrv.coefs(1,:),icrv.coefs(2,:),'r--'); 200%! hold off