PageRenderTime 29ms CodeModel.GetById 9ms RepoModel.GetById 1ms app.codeStats 0ms

/tags/R2009-05-08/extra/nurbs/inst/bspdegelev.m

#
Objective C | 294 lines | 282 code | 12 blank | 0 comment | 96 complexity | f55f26beebbc99ca5d95183b3e23944f MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause, LGPL-2.1, GPL-3.0, LGPL-3.0
  1. %% Copyright (C) 2003 Mark Spink, 2007 Daniel Claxton
  2. %%
  3. %% This program is free software; you can redistribute it and/or modify
  4. %% it under the terms of the GNU General Public License as published by
  5. %% the Free Software Foundation; either version 2 of the License, or
  6. %% (at your option) any later version.
  7. %%
  8. %% This program is distributed in the hope that it will be useful,
  9. %% but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. %% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. %% GNU General Public License for more details.
  12. %%
  13. %% You should have received a copy of the GNU General Public License
  14. %% along with this program; if not, see <http://www.gnu.org/licenses/>.
  15. function [ic,ik] = bspdegelev(d,c,k,t)
  16. % BSPDEGELEV: Degree elevate a univariate B-Spline.
  17. %
  18. % Calling Sequence:
  19. %
  20. % [ic,ik] = bspdegelev(d,c,k,t)
  21. %
  22. % Parameters:
  23. %
  24. % d - Degree of the B-Spline.
  25. % c - Control points, matrix of size (dim,nc).
  26. % k - Knot sequence, row vector of size nk.
  27. % t - Raise the B-Spline degree t times.
  28. %
  29. % ic - Control points of the new B-Spline.
  30. % ik - Knot vector of the new B-Spline.
  31. %
  32. [mc,nc] = size(c);
  33. %
  34. % int bspdegelev(int d, double *c, int mc, int nc, double *k, int nk,
  35. % int t, int *nh, double *ic, double *ik)
  36. % {
  37. % int row,col;
  38. %
  39. % int ierr = 0;
  40. % int i, j, q, s, m, ph, ph2, mpi, mh, r, a, b, cind, oldr, mul;
  41. % int n, lbz, rbz, save, tr, kj, first, kind, last, bet, ii;
  42. % double inv, ua, ub, numer, den, alf, gam;
  43. % double **bezalfs, **bpts, **ebpts, **Nextbpts, *alfs;
  44. %
  45. % double **ctrl = vec2mat(c, mc, nc);
  46. % ic = zeros(mc,nc*(t)); % double **ictrl = vec2mat(ic, mc, nc*(t+1));
  47. %
  48. n = nc - 1; % n = nc - 1;
  49. %
  50. bezalfs = zeros(d+1,d+t+1); % bezalfs = matrix(d+1,d+t+1);
  51. bpts = zeros(mc,d+1); % bpts = matrix(mc,d+1);
  52. ebpts = zeros(mc,d+t+1); % ebpts = matrix(mc,d+t+1);
  53. Nextbpts = zeros(mc,d+1); % Nextbpts = matrix(mc,d+1);
  54. alfs = zeros(d,1); % alfs = (double *) mxMalloc(d*sizeof(double));
  55. %
  56. m = n + d + 1; % m = n + d + 1;
  57. ph = d + t; % ph = d + t;
  58. ph2 = floor(ph / 2); % ph2 = ph / 2;
  59. %
  60. % // compute bezier degree elevation coefficeients
  61. bezalfs(1,1) = 1; % bezalfs[0][0] = bezalfs[ph][d] = 1.0;
  62. bezalfs(d+1,ph+1) = 1; %
  63. for i=1:ph2 % for (i = 1; i <= ph2; i++) {
  64. inv = 1/bincoeff(ph,i); % inv = 1.0 / bincoeff(ph,i);
  65. mpi = min(d,i); % mpi = min(d,i);
  66. %
  67. for j=max(0,i-t):mpi % for (j = max(0,i-t); j <= mpi; j++)
  68. bezalfs(j+1,i+1) = inv*bincoeff(d,j)*bincoeff(t,i-j); % bezalfs[i][j] = inv * bincoeff(d,j) * bincoeff(t,i-j);
  69. end
  70. end % }
  71. %
  72. for i=ph2+1:ph-1 % for (i = ph2+1; i <= ph-1; i++) {
  73. mpi = min(d,i); % mpi = min(d, i);
  74. for j=max(0,i-t):mpi % for (j = max(0,i-t); j <= mpi; j++)
  75. bezalfs(j+1,i+1) = bezalfs(d-j+1,ph-i+1); % bezalfs[i][j] = bezalfs[ph-i][d-j];
  76. end
  77. end % }
  78. %
  79. mh = ph; % mh = ph;
  80. kind = ph+1; % kind = ph+1;
  81. r = -1; % r = -1;
  82. a = d; % a = d;
  83. b = d+1; % b = d+1;
  84. cind = 1; % cind = 1;
  85. ua = k(1); % ua = k[0];
  86. %
  87. for ii=0:mc-1 % for (ii = 0; ii < mc; ii++)
  88. ic(ii+1,1) = c(ii+1,1); % ictrl[0][ii] = ctrl[0][ii];
  89. end %
  90. for i=0:ph % for (i = 0; i <= ph; i++)
  91. ik(i+1) = ua; % ik[i] = ua;
  92. end %
  93. % // initialise first bezier seg
  94. for i=0:d % for (i = 0; i <= d; i++)
  95. for ii=0:mc-1 % for (ii = 0; ii < mc; ii++)
  96. bpts(ii+1,i+1) = c(ii+1,i+1); % bpts[i][ii] = ctrl[i][ii];
  97. end
  98. end %
  99. % // big loop thru knot vector
  100. while b < m % while (b < m) {
  101. i = b; % i = b;
  102. while b < m && k(b+1) == k(b+2) % while (b < m && k[b] == k[b+1])
  103. b = b + 1; % b++;
  104. end %
  105. mul = b - i + 1; % mul = b - i + 1;
  106. mh = mh + mul + t; % mh += mul + t;
  107. ub = k(b+1); % ub = k[b];
  108. oldr = r; % oldr = r;
  109. r = d - mul; % r = d - mul;
  110. %
  111. % // insert knot u(b) r times
  112. if oldr > 0 % if (oldr > 0)
  113. lbz = floor((oldr+2)/2); % lbz = (oldr+2) / 2;
  114. else % else
  115. lbz = 1; % lbz = 1;
  116. end %
  117. if r > 0 % if (r > 0)
  118. rbz = ph - floor((r+1)/2); % rbz = ph - (r+1)/2;
  119. else % else
  120. rbz = ph; % rbz = ph;
  121. end %
  122. if r > 0 % if (r > 0) {
  123. % // insert knot to get bezier segment
  124. numer = ub - ua; % numer = ub - ua;
  125. for q=d:-1:mul+1 % for (q = d; q > mul; q--)
  126. alfs(q-mul) = numer / (k(a+q+1)-ua); % alfs[q-mul-1] = numer / (k[a+q]-ua);
  127. end
  128. for j=1:r % for (j = 1; j <= r; j++) {
  129. save = r - j; % save = r - j;
  130. s = mul + j; % s = mul + j;
  131. %
  132. for q=d:-1:s % for (q = d; q >= s; q--)
  133. for ii=0:mc-1 % for (ii = 0; ii < mc; ii++)
  134. tmp1 = alfs(q-s+1)*bpts(ii+1,q+1);
  135. tmp2 = (1-alfs(q-s+1))*bpts(ii+1,q);
  136. bpts(ii+1,q+1) = tmp1 + tmp2; % bpts[q][ii] = alfs[q-s]*bpts[q][ii]+(1.0-alfs[q-s])*bpts[q-1][ii];
  137. end
  138. end %
  139. for ii=0:mc-1 % for (ii = 0; ii < mc; ii++)
  140. Nextbpts(ii+1,save+1) = bpts(ii+1,d+1); % Nextbpts[save][ii] = bpts[d][ii];
  141. end
  142. end % }
  143. end % }
  144. % // end of insert knot
  145. %
  146. % // degree elevate bezier
  147. for i=lbz:ph % for (i = lbz; i <= ph; i++) {
  148. for ii=0:mc-1 % for (ii = 0; ii < mc; ii++)
  149. ebpts(ii+1,i+1) = 0; % ebpts[i][ii] = 0.0;
  150. end
  151. mpi = min(d, i); % mpi = min(d, i);
  152. for j=max(0,i-t):mpi % for (j = max(0,i-t); j <= mpi; j++)
  153. for ii=0:mc-1 % for (ii = 0; ii < mc; ii++)
  154. tmp1 = ebpts(ii+1,i+1);
  155. tmp2 = bezalfs(j+1,i+1)*bpts(ii+1,j+1);
  156. ebpts(ii+1,i+1) = tmp1 + tmp2; % ebpts[i][ii] = ebpts[i][ii] + bezalfs[i][j]*bpts[j][ii];
  157. end
  158. end
  159. end % }
  160. % // end of degree elevating bezier
  161. %
  162. if oldr > 1 % if (oldr > 1) {
  163. % // must remove knot u=k[a] oldr times
  164. first = kind - 2; % first = kind - 2;
  165. last = kind; % last = kind;
  166. den = ub - ua; % den = ub - ua;
  167. bet = floor((ub-ik(kind)) / den); % bet = (ub-ik[kind-1]) / den;
  168. %
  169. % // knot removal loop
  170. for tr=1:oldr-1 % for (tr = 1; tr < oldr; tr++) {
  171. i = first; % i = first;
  172. j = last; % j = last;
  173. kj = j - kind + 1; % kj = j - kind + 1;
  174. while j-i > tr % while (j - i > tr) {
  175. % // loop and compute the new control points
  176. % // for one removal step
  177. if i < cind % if (i < cind) {
  178. alf = (ub-ik(i+1))/(ua-ik(i+1)); % alf = (ub-ik[i])/(ua-ik[i]);
  179. for ii=0:mc-1 % for (ii = 0; ii < mc; ii++)
  180. tmp1 = alf*ic(ii+1,i+1);
  181. tmp2 = (1-alf)*ic(ii+1,i);
  182. ic(ii+1,i+1) = tmp1 + tmp2; % ictrl[i][ii] = alf * ictrl[i][ii] + (1.0-alf) * ictrl[i-1][ii];
  183. end
  184. end % }
  185. if j >= lbz % if (j >= lbz) {
  186. if j-tr <= kind-ph+oldr % if (j-tr <= kind-ph+oldr) {
  187. gam = (ub-ik(j-tr+1)) / den; % gam = (ub-ik[j-tr]) / den;
  188. for ii=0:mc-1 % for (ii = 0; ii < mc; ii++)
  189. tmp1 = gam*ebpts(ii+1,kj+1);
  190. tmp2 = (1-gam)*ebpts(ii+1,kj+2);
  191. ebpts(ii+1,kj+1) = tmp1 + tmp2; % ebpts[kj][ii] = gam*ebpts[kj][ii] + (1.0-gam)*ebpts[kj+1][ii];
  192. end % }
  193. else % else {
  194. for ii=0:mc-1 % for (ii = 0; ii < mc; ii++)
  195. tmp1 = bet*ebpts(ii+1,kj+1);
  196. tmp2 = (1-bet)*ebpts(ii+1,kj+2);
  197. ebpts(ii+1,kj+1) = tmp1 + tmp2; % ebpts[kj][ii] = bet*ebpts[kj][ii] + (1.0-bet)*ebpts[kj+1][ii];
  198. end
  199. end % }
  200. end % }
  201. i = i + 1; % i++;
  202. j = j - 1; % j--;
  203. kj = kj - 1; % kj--;
  204. end % }
  205. %
  206. first = first - 1; % first--;
  207. last = last + 1; % last++;
  208. end % }
  209. end % }
  210. % // end of removing knot n=k[a]
  211. %
  212. % // load the knot ua
  213. if a ~= d % if (a != d)
  214. for i=0:ph-oldr-1 % for (i = 0; i < ph-oldr; i++) {
  215. ik(kind+1) = ua; % ik[kind] = ua;
  216. kind = kind + 1; % kind++;
  217. end
  218. end % }
  219. %
  220. % // load ctrl pts into ic
  221. for j=lbz:rbz % for (j = lbz; j <= rbz; j++) {
  222. for ii=0:mc-1 % for (ii = 0; ii < mc; ii++)
  223. ic(ii+1,cind+1) = ebpts(ii+1,j+1); % ictrl[cind][ii] = ebpts[j][ii];
  224. end
  225. cind = cind + 1; % cind++;
  226. end % }
  227. %
  228. if b < m % if (b < m) {
  229. % // setup for next pass thru loop
  230. for j=0:r-1 % for (j = 0; j < r; j++)
  231. for ii=0:mc-1 % for (ii = 0; ii < mc; ii++)
  232. bpts(ii+1,j+1) = Nextbpts(ii+1,j+1); % bpts[j][ii] = Nextbpts[j][ii];
  233. end
  234. end
  235. for j=r:d % for (j = r; j <= d; j++)
  236. for ii=0:mc-1 % for (ii = 0; ii < mc; ii++)
  237. bpts(ii+1,j+1) = c(ii+1,b-d+j+1); % bpts[j][ii] = ctrl[b-d+j][ii];
  238. end
  239. end
  240. a = b; % a = b;
  241. b = b+1; % b++;
  242. ua = ub; % ua = ub;
  243. % }
  244. else % else
  245. % // end knot
  246. for i=0:ph % for (i = 0; i <= ph; i++)
  247. ik(kind+i+1) = ub; % ik[kind+i] = ub;
  248. end
  249. end
  250. end % }
  251. % End big while loop % // end while loop
  252. %
  253. % *nh = mh - ph - 1;
  254. %
  255. % freevec2mat(ctrl);
  256. % freevec2mat(ictrl);
  257. % freematrix(bezalfs);
  258. % freematrix(bpts);
  259. % freematrix(ebpts);
  260. % freematrix(Nextbpts);
  261. % mxFree(alfs);
  262. %
  263. % return(ierr);
  264. % }
  265. function b = bincoeff(n,k)
  266. % Computes the binomial coefficient.
  267. %
  268. % ( n ) n!
  269. % ( ) = --------
  270. % ( k ) k!(n-k)!
  271. %
  272. % b = bincoeff(n,k)
  273. %
  274. % Algorithm from 'Numerical Recipes in C, 2nd Edition' pg215.
  275. % double bincoeff(int n, int k)
  276. % {
  277. b = floor(0.5+exp(factln(n)-factln(k)-factln(n-k))); % return floor(0.5+exp(factln(n)-factln(k)-factln(n-k)));
  278. % }
  279. function f = factln(n)
  280. % computes ln(n!)
  281. if n <= 1, f = 0; return, end
  282. f = gammaln(n+1); %log(factorial(n));