/trunk/octave-forge/extra/nurbs/inst/bspdegelev.m

# · Objective C · 296 lines · 284 code · 12 blank · 0 comment · 95 complexity · 5a7638accd22f943a5ac4278ab8176b6 MD5 · raw file

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