1 line
14 KiB
Plaintext
1 line
14 KiB
Plaintext
|
|
{"version":3,"file":"NURBSUtils.cjs","sources":["../../src/curves/NURBSUtils.js"],"sourcesContent":["import { Vector3, Vector4 } from 'three'\n\n/**\n * NURBS utils\n *\n * See NURBSCurve and NURBSSurface.\n **/\n\n/**************************************************************\n *\tNURBS Utils\n **************************************************************/\n\n/*\nFinds knot vector span.\n\np : degree\nu : parametric value\nU : knot vector\n\nreturns the span\n*/\nfunction findSpan(p, u, U) {\n const n = U.length - p - 1\n\n if (u >= U[n]) {\n return n - 1\n }\n\n if (u <= U[p]) {\n return p\n }\n\n let low = p\n let high = n\n let mid = Math.floor((low + high) / 2)\n\n while (u < U[mid] || u >= U[mid + 1]) {\n if (u < U[mid]) {\n high = mid\n } else {\n low = mid\n }\n\n mid = Math.floor((low + high) / 2)\n }\n\n return mid\n}\n\n/*\nCalculate basis functions. See The NURBS Book, page 70, algorithm A2.2\n\nspan : span in which u lies\nu : parametric point\np : degree\nU : knot vector\n\nreturns array[p+1] with basis functions values.\n*/\nfunction calcBasisFunctions(span, u, p, U) {\n const N = []\n const left = []\n const right = []\n N[0] = 1.0\n\n for (let j = 1; j <= p; ++j) {\n left[j] = u - U[span + 1 - j]\n right[j] = U[span + j] - u\n\n let saved = 0.0\n\n for (let r = 0; r < j; ++r) {\n const rv = right[r + 1]\n const lv = left[j - r]\n const temp = N[r] / (rv + lv)\n N[r] = saved + rv * temp\n saved = lv * temp\n }\n\n N[j] = saved\n }\n\n return N\n}\n\n/*\nCalculate B-Spline curve points. See The NURBS Book, page 82, algorithm A3.1.\n\np : degree of B-Spline\nU : knot vector\nP : control points (x, y, z, w)\nu : parametric point\n\nreturns point for given u\n*/\nfunction calcBSplinePoint(p, U, P, u) {\n const span = findSpan(p, u, U)\n const N = calcBasisFunctions(span, u, p, U)\n const C = new Vector4(0, 0, 0, 0)\n\n for (let j = 0; j <= p; ++j) {\n const point = P[span - p + j]\n const Nj = N[j]\n const wNj = point.w * Nj\n C.x += point.x * wNj\n C.y += point.y * wNj\n C.z += point.z * wNj\n C.w += point.w * Nj\n }\n\n return C\n}\n\n/*\nCalculate basis functions derivatives. See The NURBS Book, page 72, algorithm A2.3.\n\nspan : span in which u lies\nu : parametric point\np : degree\nn : number of derivatives to calculate\nU : knot vector\n\nreturns array[n+1][p+1] with basis functions derivatives\n*/\nfunction calcBasisFunctionDerivatives(span, u, p, n, U) {\n const zeroArr = []\n for (let i = 0; i <= p; ++i) zeroArr[i] = 0.0\n\n const ders = []\n\n for (let i = 0; i <= n; ++i) ders[i] = zeroArr.slice(0)\n\n const ndu = []\n\n for (let i = 0; i <= p; ++i) ndu[i] = zeroArr.slice(0)\n\n ndu[0][0] = 1.0\n\n const left = zeroArr.slice(0)\n const right = zeroArr.slice(0)\n\n for (let j = 1; j <= p; ++j) {\n left[j] = u - U[span + 1 - j]\n right[j] = U[span + j] - u\n\n let saved = 0.0\n\n for (let r = 0; r < j; ++r) {\n const rv = right[r + 1]\n const lv = left[j - r]\n ndu[j][r] = rv + lv\n\n const temp = ndu[r][j - 1] / ndu[j][r]\n ndu[r][j] = saved + rv * temp\n saved = lv * temp\n }\n\n ndu[j][j] = saved\n }\n\n for (let j = 0; j <= p; ++j) {\n ders[0][j] = ndu[j][p]\n }\n\n for (let r = 0; r <= p; ++r) {\n let s1 = 0\n let s2 = 1\n\n const a = []\n for (let i = 0; i <= p; ++i) {\n a[i] = zeroArr.slice(0)\n }\n\n a[0][0] = 1.0\n\n for (let k = 1; k <= n; ++k) {\n let d = 0.0\n const rk = r - k\n const pk = p - k\n\n if (r >= k) {\n a[s2][0] = a[s1][0] / ndu[pk + 1][rk]\n d = a[s2][0] * ndu[rk][pk]\n }\n\n const j1 = rk >= -1 ? 1 : -rk\n const j2 = r - 1 <= pk ? k - 1 : p - r\n\n for (let j = j1; j <= j2; ++j) {\n a[s2][j] = (a[s1][j] - a[s1][j - 1]) / ndu[pk + 1][rk + j]\n d += a[s2][j] * ndu[rk + j][pk]\n }\n\n if (r <= pk) {\n a[s2][k] = -a[s1][k - 1] / ndu[pk + 1][r]\n d += a[s2][k] *
|