-
Notifications
You must be signed in to change notification settings - Fork 0
/
code.js
2722 lines (2133 loc) · 81.9 KB
/
code.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
//----------------Chapter 1 : Curve and Surface Basics
// ALGORITHM A1.1
// Horner's algorithm for computing a point on a power basis curve.
function Horner1(a, n, u0) {
let C = a[n];
for (let i = n - 1; i >= 0; i--) {
C = C * u0 + a[i];
}
return C;
}
// Example usage of ALGORITHM A1.1
// let a = [/* coefficients array */];
// let n = a.length - 1;
// let u0 = /* value of u */;
// let point = Horner1(a, n, u0);
// console.log(point);
// ALGORITHM A1.2
// Bernstein's algorithm for computing the value of a Bernstein polynomial.
function Bernstein(i, n, u) {
let temp = new Array(n).fill(0.0);
temp[n - i] = 1.0;
let u1 = 1.0 - u;
for (let k = 1; k <= n; k++) {
for (let j = n; j >= k; j--) {
temp[j] = u1 * temp[j] + u * temp[j - 1];
}
}
return temp[n];
}
// Example usage of ALGORITHM A1.2
// let i = /* index */;
// let n = /* degree */;
// let u = /* value of u */;
// let B = Bernstein(i, n, u);
// console.log(B);
// ALGORITHM A1.3
// Algorithm for computing all nth-degree Bernstein polynomials.
function AllBernstein(n, u) {
let B = new Array(n + 1).fill(0.0);
B[0] = 1.0;
let u1 = 1.0 - u;
for (let j = 1; j <= n; j++) {
let saved = 0.0;
for (let k = 0; k < j; k++) {
let temp = B[k];
B[k] = saved + u1 * temp;
saved = u * temp;
}
B[j] = saved;
}
return B;
}
// Example usage of ALGORITHM A1.3
// let n = /* degree */;
// let u = /* value of u */;
// let Bs = AllBernstein(n, u);
// console.log(Bs);
// ALGORITHM A1.4
// Function to compute a point on a Bezier curve using Bernstein polynomials.
function PointOnBezierCurve(P, n, u) {
// Compute point on Bezier curve.
// Input: P (control points), n, u
// Output: C (a point)
let B = AllBernstein(n, u); // B is calculated using the previously defined AllBernstein function
let C = 0.0;
for (let k = 0; k <= n; k++) {
C = C + B[k] * P[k];
}
return C;
}
// Example usage of ALGORITHM A1.4
// let P = [/* array of control points */];
// let n = P.length - 1;
// let u = /* value of u */;
// let pointOnCurve = PointOnBezierCurve(P, n, u);
// console.log(pointOnCurve);
// ALGORITHM A1.5
// Function to compute a point on a Bezier curve using de Casteljau's algorithm.
function deCasteljau1(P, n, u) {
// Compute point on a Bézier curve using de Casteljau.
// Input: P (control points), n, u
// Output: C (a point)
let Q = P.slice(); // Use local array so we do not destroy control points
for (let k = 1; k <= n; k++) {
for (let i = 0; i <= n - k; i++) {
Q[i] = (1.0 - u) * Q[i] + u * Q[i + 1];
}
}
return Q[0];
}
// Example usage of ALGORITHM A1.5
// let P = [/* array of control points */];
// let n = P.length - 1;
// let u = /* value of u */;
// let pointOnCurve = deCasteljau1(P, n, u);
// console.log(pointOnCurve);
// ALGORITHM A1.6
// Function to compute a point on a power basis surface.
function Horner2(a, n, m, u0, v0) {
// Compute point on a power basis surface.
// Input: a (array of arrays), n, m, u0, v0
// Output: S
let S = new Array(m + 1).fill(0);
for (let i = 0; i <= n; i++) {
S = Horner1(a[i], m, v0, S); // a[i] is the ith row
}
return Horner1(S, n, u0);
}
// Example usage of ALGORITHM A1.6
// let a = [/* array of arrays representing the surface control points */];
// let n = /* the degree in the u direction */;
// let m = /* the degree in the v direction */;
// let u0 = /* value of u */;
// let v0 = /* value of v */;
// let surfacePoint = Horner2(a, n, m, u0, v0);
// console.log(surfacePoint);
// ALGORITHM A1.7
// Function to compute a point on a Bézier surface using de Casteljau's algorithm.
function deCasteljau2(P, n, m, u0, v0) {
// Compute a point on a Bézier surface by the de Casteljau.
// Input: P (array of arrays of control points), n, m, u0, v0
// Output: S (a point)
let S;
let Q = [];
if (n <= m) {
for (let j = 0; j <= m; j++) {
Q[j] = deCasteljau1(P.map(row => row[j]), n, u0); // P[j] is the jth column
}
S = deCasteljau1(Q, m, v0);
} else {
for (let i = 0; i <= n; i++) {
Q[i] = deCasteljau1(P[i], m, v0); // P[i] is the ith row
}
S = deCasteljau1(Q, n, u0);
}
return S;
}
// Example usage of ALGORITHM A1.7
// let P = [/* array of arrays representing the surface control points */];
// let n = /* the degree in the u direction */;
// let m = /* the degree in the v direction */;
// let u0 = /* value of u */;
// let v0 = /* value of v */;
// let surfacePoint = deCasteljau2(P, n, m, u0, v0);
// console.log(surfacePoint);
//--------------------Chapter 2 : B-Spline Basis Functions
// ALGORITHM A2.1
// Function to determine the knot span index in NURBS calculations.
function FindSpan(n, p, u, U) {
// Determine the knot span index
// Input: n (number of knots minus one), p (degree of B-spline), u (parameter value), U (knot vector)
// Return: the knot span index
if (u === U[n + 1]) return n; // Special case
let low = p;
let high = n + 1;
let mid = Math.floor((low + high) / 2);
while (u < U[mid] || u >= U[mid + 1]) {
if (u < U[mid]) {
high = mid;
} else {
low = mid;
}
mid = Math.floor((low + high) / 2);
}
return mid;
}
// Example usage of ALGORITHM A2.1
// let n = /* the number of knots minus one */;
// let p = /* the degree of the B-spline */;
// let u = /* the parameter value */;
// let U = [/* the knot vector */];
// let span = FindSpan(n, p, u, U);
// console.log(span); // This will output the knot span index
// ALGORITHM A2.2
// Function to compute the nonvanishing basis functions.
function BasisFuns(i, p, u, U) {
// Compute the nonvanishing basis functions
// Input: i (knot span), p (degree of B-spline), u (parameter value), U (knot vector)
// Output: N (array of basis functions)
let N = new Array(p + 1).fill(0.0);
N[0] = 1.0;
let left = new Array(p + 1);
let right = new Array(p + 1);
for (let j = 1; j <= p; j++) {
left[j] = u - U[i + 1 - j];
right[j] = U[i + j] - u;
let saved = 0.0;
for (let r = 0; r < j; r++) {
let temp = N[r] / (right[r + 1] + left[j - r]);
N[r] = saved + right[r + 1] * temp;
saved = left[j - r] * temp;
}
N[j] = saved;
}
return N;
}
// Example usage of ALGORITHM A2.2
// let i = /* the knot span */;
// let p = /* the degree of the B-spline */;
// let u = /* the parameter value */;
// let U = [/* the knot vector */];
// let basisFuns = BasisFuns(i, p, u, U);
// console.log(basisFuns); // This will output the array of basis functions
// Function to find the span and multiplicity of a knot in a knot vector
function findSpanMult(n, p, u, UP) {
// Input: n (number of control points minus 1), p (degree of curve), u (parameter value),
// UP (knot vector)
// Output: span (the span in which u lies), mult (multiplicity of u)
if (u === UP[n + 1]) {
return [n, 1]; // Special case when u is the last knot value
}
// Find the span of u
let low = p;
let high = n + 1;
let mid = Math.floor((low + high) / 2);
while (u < UP[mid] || u >= UP[mid + 1]) {
if (u < UP[mid]) {
high = mid;
} else {
low = mid;
}
mid = Math.floor((low + high) / 2);
}
// Find the multiplicity of u
let mult = 0;
for (let i = mid; i < UP.length && UP[i] === u; i++) {
mult++;
}
return [mid, mult];
}
// Example usage of findSpanMult
// let n = /* number of control points minus 1 */;
// let p = /* degree of curve */;
// let u = /* parameter value */;
// let UP = [/* knot vector */];
// let [span, mult] = findSpanMult(n, p, u, UP);
// console.log('Span:', span, 'Multiplicity:', mult);
// ALGORITHM A2.3
// Function to compute the nonvanishing basis functions and their derivatives.
function DersBasisFuns(i, p, u, U, n) {
// Compute nonzero basis functions and their derivatives.
// Input: i, p, u, U
// Modified from ALGORITHM A2.2 to store functions and knot differences.
// Output: ders (derivatives)
let ndu = Array.from(Array(p + 1), () => new Array(p + 1).fill(0));
ndu[0][0] = 1.0;
let left = new Array(p + 1);
let right = new Array(p + 1);
let a = Array.from(Array(2), () => new Array(p + 1).fill(0));
let ders = Array.from(Array(n + 1), () => new Array(p + 1).fill(0));
for (let j = 1; j <= p; j++) {
left[j] = u - U[i + 1 - j];
right[j] = U[i + j] - u;
let saved = 0.0;
for (let r = 0; r < j; r++) {
// Lower triangle
ndu[j][r] = right[r + 1] + left[j - r];
let temp = ndu[r][j - 1] / ndu[j][r];
// Upper triangle
ndu[r][j] = saved + right[r + 1] * temp;
saved = left[j - r] * temp;
}
ndu[j][j] = saved;
}
for (let j = 0; j <= p; j++) {
// Load the basis functions
ders[0][j] = ndu[j][p];
}
// This section computes the derivatives
for (let r = 0; r <= p; r++) {
let s1 = 0;
let s2 = 1; // alternate rows in array a
a[0][0] = 1.0;
// Loop to compute kth derivative
for (let k = 1; k <= n; k++) {
let d = 0.0;
let rk = r - k;
let pk = p - k;
if (r >= k) {
a[s2][0] = a[s1][0] / ndu[pk + 1][rk];
d = a[s2][0] * ndu[rk][pk];
}
let j1 = (rk >= -1) ? 1 : -rk;
let j2 = (r - 1 <= pk) ? k - 1 : p - r;
for (let j = j1; j <= j2; j++) {
a[s2][j] = (a[s1][j] - a[s1][j - 1]) / ndu[pk + 1][rk + j];
d += a[s2][j] * ndu[rk + j][pk];
}
if (r <= pk) {
a[s2][k] = -a[s1][k - 1] / ndu[pk + 1][r];
d += a[s2][k] * ndu[r][pk];
}
ders[k][r] = d;
// Switch rows
let temp = s1;
s1 = s2;
s2 = temp;
}
}
// Multiply through by the correct factors (Eq. [2.9])
let r = p;
for (let k = 1; k <= n; k++) {
for (let j = 0; j <= p; j++) {
ders[k][j] *= r;
}
r *= (p - k);
}
return ders;
}
// Example usage of ALGORITHM A2.3
// let i = /* the knot span */;
// let p = /* the degree of the B-spline */;
// let u = /* the parameter value */;
// let U = [/* the knot vector */];
// let n = /* the order of the derivative */;
// let ders = DersBasisFuns(i, p, u, U, n);
// console.log(ders); // This will output the derivatives of the basis functions
// ALGORITHM A2.4
// Function to compute the basis function Nip.
function OneBasisFun(p, m, U, i, u) {
// Compute the basis function Nip
// Input: p (degree of B-spline), m (upper index of U), U (knot vector), i (knot span), u (parameter value)
// Output: Nip (the value of the basis function)
if ((i === 0 && u === U[0]) || (i === m - p - 1 && u === U[m])) {
// Special cases
return 1.0;
}
if (u < U[i] || u >= U[i + p + 1]) {
// Local property
return 0.0;
}
let N = new Array(p + 1).fill(0.0);
// Initialize zeroth-degree functions
for (let j = 0; j <= p; j++) {
if (u >= U[i + j] && u < U[i + j + 1]) {
N[j] = 1.0;
}
}
// Compute triangular table
for (let k = 1; k <= p; k++) {
let saved = 0.0;
if (N[0] === 0.0) {
saved = 0.0;
} else {
saved = ((u - U[i]) * N[0]) / (U[i + k] - U[i]);
}
for (let j = 0; j < p - k + 1; j++) {
let Uleft = U[i + j + 1];
let Uright = U[i + j + k + 1];
if (N[j + 1] === 0.0) {
N[j] = saved;
saved = 0.0;
} else {
let temp = N[j + 1] / (Uright - Uleft);
N[j] = saved + (Uright - u) * temp;
saved = (u - Uleft) * temp;
}
}
}
let Nip = N[0];
return Nip;
}
// Example usage of ALGORITHM A2.4
// let p = /* the degree of the B-spline */;
// let m = /* the upper index of U */;
// let U = [/* the knot vector */];
// let i = /* the knot span */;
// let u = /* the parameter value */;
// let Nip = OneBasisFun(p, m, U, i, u);
// console.log(Nip); // This will output the value of the basis function
// ALGORITHM A2.5
// Function to compute derivatives of basis function Nip.
function DersOneBasisFun(p, m, U, i, u, n) {
// Compute derivatives of basis function Nip
// Input: p (degree of B-spline), m (upper index of U), U (knot vector), i (knot span), u (parameter value), n (derivative order)
// Output: ders (array of derivatives)
let ders = new Array(n + 1).fill(0.0);
// Local property
if (u < U[i] || u >= U[i + p + 1]) {
return ders;
}
// Initialize zeroth-degree functs
let N = Array.from(Array(p + 1), () => new Array(p + 1).fill(0));
N[0][0] = 1.0;
for (let j = 1; j <= p; j++) {
if (u >= U[i + j] && u < U[i + j + 1]) {
N[j][0] = 1.0;
}
}
// Compute full triangular table
for (let k = 1; k <= p; k++) {
let saved = 0.0;
if (N[0][k - 1] === 0.0) {
saved = 0.0;
} else {
saved = ((u - U[i]) * N[0][k - 1]) / (U[i + k] - U[i]);
}
for (let j = 0; j < p - k + 1; j++) {
let Uleft = U[i + j + 1];
let Uright = U[i + j + k + 1];
if (N[j + 1][k - 1] === 0.0) {
N[j][k] = saved;
saved = 0.0;
} else {
let temp = N[j + 1][k - 1] / (Uright - Uleft);
N[j][k] = saved + (Uright - u) * temp;
saved = (u - Uleft) * temp;
}
}
}
// The function value
ders[0] = N[0][p];
// Compute the derivatives
for (let k = 1; k <= n; k++) {
for (let j = 0; j <= k; j++) {
N[j][p - k] = N[j][p - k] / (U[i + p - k + j + 1] - U[i + j]);
}
let rk = p - k;
for (let j = 0; j <= rk; j++) {
let saved = (rk + 1) * N[j][p - k];
for (let jj = 0; jj < k; jj++) {
saved = saved - (p - k + jj) * U[i + j + jj] * N[j][p - k - jj - 1];
}
ders[k] += saved;
}
}
return ders;
}
// Example usage of ALGORITHM A2.5
// let p = /* the degree of the B-spline */;
// let m = /* the upper index of U */;
// let U = [/* the knot vector */];
// let i = /* the knot span */;
// let u = /* the parameter value */;
// let n = /* the derivative order */;
// let derivatives = DersOneBasisFun(p, m, U, i, u, n);
// console.log(derivatives); // This will output the array of derivatives of the basis function
//--------------------Chapter 3 : B-spline Curves and Surfaces
// ALGORITHM A3.1
// Function to compute a curve point.
function CurvePoint(n, p, U, P, u) {
// Compute curve point
// Input: n (number of control points minus 1), p (degree of the curve), U (knot vector), P (control points), u (parameter value)
// Output: C (point on the curve)
let span = FindSpan(n, p, u, U);
let N = BasisFuns(span, u, p, U);
let C = [0.0, 0.0, 0.0]; // Assuming a 3-dimensional point for C
for (let i = 0; i <= p; i++) {
C[0] += N[i] * P[span - p + i][0]; // x-coordinate
C[1] += N[i] * P[span - p + i][1]; // y-coordinate
C[2] += N[i] * P[span - p + i][2]; // z-coordinate (if 3D)
}
return C;
}
// Example usage of ALGORITHM A3.1
// let n = /* the number of control points minus 1 */;
// let p = /* the degree of the curve */;
// let U = [/* the knot vector */];
// let P = [/* the array of control points */];
// let u = /* the parameter value */;
// let curvePoint = CurvePoint(n, p, U, P, u);
// console.log(curvePoint); // This will output the computed curve point
// ALGORITHM A3.2
// Function to compute curve derivatives.
function CurveDerivsAlg1(n, p, U, P, u, d) {
// Compute curve derivatives
// Input: n (number of control points minus 1), p (degree of the curve), U (knot vector), P (control points), u (parameter value), d (derivative order)
// Output: CK (derivatives of the curve)
let du = Math.min(d, p);
let CK = Array.from({ length: du + 1 }, () => [0.0, 0.0, 0.0]); // Assuming a 3-dimensional space for derivatives
let span = FindSpan(n, p, u, U);
let nders = DersBasisFuns(span, u, p, du, U);
for (let k = 0; k <= du; k++) {
for (let j = 0; j <= p; j++) {
if (nders[k][j] !== 0) {
CK[k][0] += nders[k][j] * P[span - p + j][0]; // x-coordinate derivative
CK[k][1] += nders[k][j] * P[span - p + j][1]; // y-coordinate derivative
CK[k][2] += nders[k][j] * P[span - p + j][2]; // z-coordinate derivative (if 3D)
}
}
}
return CK;
}
// Example usage of ALGORITHM A3.2
// let n = /* the number of control points minus 1 */;
// let p = /* the degree of the curve */;
// let U = [/* the knot vector */];
// let P = [/* the array of control points */];
// let u = /* the parameter value */;
// let d = /* the derivative order */;
// let curveDerivatives = CurveDerivsAlg1(n, p, U, P, u, d);
// console.log(curveDerivatives); // This will output the derivatives of the curve
// ALGORITHM A3.3
// Function to compute control points of curve derivatives.
function CurveDerivCpts(n, p, U, P, d, r1, r2) {
// Compute control points of curve derivatives
// Input: n (number of control points minus 1), p (degree of the curve), U (knot vector),
// P (control points), d (derivative order), r1, r2 (range of control points)
// Output: PK (control points of the derivatives)
let PK = Array.from({ length: d + 1 }, () => []);
let r = r2 - r1;
// Initialize control points of the curve derivatives
for (let i = 0; i <= r; i++) {
PK[0][i] = P[r1 + i].slice(); // Assuming each control point is an array [x, y, z]
}
// Compute the remaining control points
for (let k = 1; k <= d; k++) {
let tmp = p - k + 1;
for (let i = 0; i <= r - k; i++) {
PK[k][i] = [];
for (let j = 0; j < P[0].length; j++) { // Iterate over each dimension
PK[k][i][j] = tmp * (PK[k - 1][i + 1][j] - PK[k - 1][i][j]) / (U[r1 + i + p + 1] - U[r1 + i + k]);
}
}
}
return PK;
}
// Example usage of ALGORITHM A3.3
// let n = /* the number of control points minus 1 */;
// let p = /* the degree of the curve */;
// let U = [/* the knot vector */];
// let P = [/* the control points as an array of [x, y, z] points */];
// let d = /* the derivative order */;
// let r1 = /* the lower index of the range of control points */;
// let r2 = /* the upper index of the range of control points */;
// let derivativeControlPoints = CurveDerivCpts(n, p, U, P, d, r1, r2);
// console.log(derivativeControlPoints); // This will output the control points for the curve derivatives
// ALGORITHM A3.4
// Function to compute curve derivatives.
function CurveDerivsAlg2(n, p, U, P, u, d) {
// Compute curve derivatives
// Input: n (number of control points minus 1), p (degree of the curve), U (knot vector), P (control points), u (parameter value), d (derivative order)
// Output: CK (curve derivatives at u)
let du = Math.min(d, p);
let CK = Array.from({ length: du + 1 }, () => [0.0, 0.0, 0.0]); // Assuming 3D points for CK
let span = FindSpan(n, p, u, U);
let N = AllBasisFuns(span, u, p, U); // Assuming AllBasisFuns returns all the non-zero basis functions at u
let PK = CurveDerivCpts(n, p, U, P, d, span - p, span); // Assuming CurveDerivCpts computes the control points for the derivatives
for (let k = 0; k <= du; k++) {
CK[k] = [0.0, 0.0, 0.0]; // Initialize the kth derivative
for (let j = 0; j <= p - k; j++) {
CK[k][0] += N[j][p - k] * PK[k][j][0]; // x-coordinate
CK[k][1] += N[j][p - k] * PK[k][j][1]; // y-coordinate
CK[k][2] += N[j][p - k] * PK[k][j][2]; // z-coordinate (if 3D)
}
}
return CK;
}
// Example usage of ALGORITHM A3.4
// let n = /* the number of control points minus 1 */;
// let p = /* the degree of the curve */;
// let U = [/* the knot vector */];
// let P = [/* the array of control points as [x, y, z] */];
// let u = /* the parameter value */;
// let d = /* the derivative order */;
// let curveDerivatives = CurveDerivsAlg2(n, p, U, P, u, d);
// console.log(curveDerivatives); // This will output the curve derivatives at u
// ALGORITHM A3.5
// Function to compute surface point.
function SurfacePoint(n, p, U, m, q, V, P, u, v) {
// Compute surface point
// Input: n, p, U (knot vector in u direction), m, q, V (knot vector in v direction), P (control point grid), u, v (parameter values)
// Output: S (point on the surface)
let uspan = FindSpan(n, p, u, U);
let Nu = BasisFuns(uspan, u, p, U);
let vspan = FindSpan(m, q, v, V);
let Nv = BasisFuns(vspan, v, q, V);
let uind = uspan - p;
let S = [0.0, 0.0, 0.0]; // Assuming a 3-dimensional point for S
for (let l = 0; l <= q; l++) {
let temp = [0.0, 0.0, 0.0]; // Temporary point to accumulate the influence of the basis functions in u direction
let vind = vspan - q + l;
for (let k = 0; k <= p; k++) {
let uindk = uind + k;
temp[0] += Nu[k] * P[uindk][vind][0]; // x-coordinate
temp[1] += Nu[k] * P[uindk][vind][1]; // y-coordinate
temp[2] += Nu[k] * P[uindk][vind][2]; // z-coordinate (if 3D)
}
S[0] += Nv[l] * temp[0];
S[1] += Nv[l] * temp[1];
S[2] += Nv[l] * temp[2];
}
return S;
}
// Example usage of ALGORITHM A3.5
// let n = /* number of control points in u direction minus 1 */;
// let p = /* degree of the surface in u direction */;
// let U = [/* knot vector in u direction */];
// let m = /* number of control points in v direction minus 1 */;
// let q = /* degree of the surface in v direction */;
// let V = [/* knot vector in v direction */];
// let P = [/* control point grid as an array of arrays of [x, y, z] points */];
// let u = /* parameter value in u direction */;
// let v = /* parameter value in v direction */;
// let surfacePoint = SurfacePoint(n, p, U, m, q, V, P, u, v);
// console.log(surfacePoint); // This will output the surface point at (u, v)
// ALGORITHM A3.6
// Function to compute surface derivatives.
function SurfaceDerivsAlg1(n, p, U, m, q, V, P, u, v, d) {
// Compute surface derivatives
// Input: n (number of control points in u direction minus 1), p (degree in u direction), U (knot vector in u direction),
// m (number of control points in v direction minus 1), q (degree in v direction), V (knot vector in v direction),
// P (control point grid), u, v (parameter values), d (order of derivatives)
// Output: SKL (surface derivatives)
let du = Math.min(d, p);
let dv = Math.min(d, q);
let SKL = Array.from(Array(du + 1), () => Array(dv + 1).fill(null).map(() => [0.0, 0.0, 0.0])); // Assuming 3D points for SKL
let uspan = FindSpan(n, p, u, U);
let Nu = DersBasisFuns(uspan, u, p, du, U); // Assuming DersBasisFuns returns the derivatives of the basis functions
let vspan = FindSpan(m, q, v, V);
let Nv = DersBasisFuns(vspan, v, q, dv, V); // Assuming DersBasisFuns returns the derivatives of the basis functions
for (let k = 0; k <= du; k++) {
for (let s = 0; s <= dv; s++) {
let temp = [0.0, 0.0, 0.0]; // Temporary point to accumulate the influence of the basis functions
for (let r = 0; r <= p; r++) {
for (let t = 0; t <= q; t++) {
let point = P[uspan - p + r][vspan - q + t];
let weight = Nu[k][r] * Nv[s][t];
temp[0] += point[0] * weight;
temp[1] += point[1] * weight;
temp[2] += point[2] * weight; // Assuming P is a 3D control point
}
}
SKL[k][s] = temp;
}
}
return SKL;
}
// Example usage of ALGORITHM A3.6
// let n = /* number of control points in u direction minus 1 */;
// let p = /* degree of the surface in u direction */;
// let U = [/* knot vector in u direction */];
// let m = /* number of control points in v direction minus 1 */;
// let q = /* degree of the surface in v direction */;
// let V = [/* knot vector in v direction */];
// let P = [/* control point grid as an array of arrays of [x, y, z] points */];
// let u = /* parameter value in u direction */;
// let v = /* parameter value in v direction */;
// let d = /* order of derivatives */;
// let surfaceDerivatives = SurfaceDerivsAlg1(n, p, U, m, q, V, P, u, v, d);
// console.log(surfaceDerivatives); // This will output the surface derivatives
// ALGORITHM A3.7
// Function to compute control points of derivative surfaces.
function SurfaceDerivCpts(n, p, U, m, q, V, P, d, r1, r2, s1, s2) {
// Compute control points of derivative surfaces
// Input: n, p, U (knot vector in u), m, q, V (knot vector in v), P (control points),
// d (derivative order), r1, r2, s1, s2 (control point range)
// Output: PKL (control points for the derivative surfaces)
let du = Math.min(d, p);
let dv = Math.min(d, q);
let PKL = Array.from(Array(du + 1), () => Array.from(Array(dv + 1), () => []));
let r = r2 - r1;
let s = s2 - s1;
let temp = [];
// Compute control points for the u-direction derivatives
for (let j = s1; j <= s2; j++) {
// Each P[][] is a row for CurveDerivCpts
let row = Array.from({ length: n + 1 }, (_, i) => P[i][j]);
temp = CurveDerivCpts(n, p, U, row, du, r1, r2); // Compute curve derivative control points in u
for (let k = 0; k <= du; k++) {
for (let i = 0; i <= r - k; i++) {
PKL[k][0][i + j - s1] = temp[k][i]; // Assign computed control points
}
}
}
// Compute control points for the v-direction derivatives
for (let k = 0; k <= du; k++) {
for (let i = 0; i <= r - k; i++) {
// Each PKL[k][0][] is a row for CurveDerivCpts
let col = PKL[k][0].slice(i, s + 1);
temp = CurveDerivCpts(m, q, V, col, dv, s1, s2); // Compute curve derivative control points in v
for (let l = 1; l <= dv; l++) {
for (let j = 0; j <= s - l; j++) {
PKL[k][l][i][j] = temp[l][j]; // Assign computed control points
}
}
}
}
return PKL;
}
// Example usage of ALGORITHM A3.7
// let n = /* the number of control points in u direction minus 1 */;
// let p = /* the degree in u direction */;
// let U = [/* the knot vector in u direction */];
// let m = /* the number of control points in v direction minus 1 */;
// let q = /* the degree in v direction */;
// let V = [/* the knot vector in v direction */];
// let P = [/* the control point grid */];
// let d = /* the derivative order */;
// let r1 = /* the start index in u direction */;
// let r2 = /* the end index in u direction */;
// let s1 = /* the start index in v direction */;
// let s2 = /* the end index in v direction */;
// let derivativeControlPoints = SurfaceDerivCpts(n, p, U, m, q, V, P, d, r1, r2, s1, s2);
// console.log(derivativeControlPoints); // This will output the control points for the surface derivatives
// ALGORITHM A3.8
// Function to compute surface derivatives.
function SurfaceDerivsAlg2(n, p, U, m, q, V, P, u, v, d) {
// Compute surface derivatives
// Input: n, p, U (knot vector in u), m, q, V (knot vector in v), P (control points), u, v (parameter values), d (order of derivatives)
// Output: SKL (surface derivatives at (u, v))
let du = Math.min(d, p);
let dv = Math.min(d, q);
let SKL = Array.from(Array(du + 1), () => Array.from(Array(dv + 1), () => [0.0, 0.0, 0.0])); // Assuming 3D points for SKL
let uspan = FindSpan(n, p, u, U);
let Nu = AllBasisFuns(uspan, u, p, U); // Assuming AllBasisFuns returns all non-zero basis functions at u
let vspan = FindSpan(m, q, v, V);
let Nv = AllBasisFuns(vspan, v, q, V); // Assuming AllBasisFuns returns all non-zero basis functions at v
let PKL = SurfaceDerivCpts(n, p, U, m, q, V, P, d, uspan - p, uspan, vspan - q, vspan); // Assuming SurfaceDerivCpts computes the control points for the surface derivatives
for (let k = 0; k <= du; k++) {
for (let l = 0; l <= dv; l++) {
SKL[k][l] = [0.0, 0.0, 0.0]; // Initialize the derivative
for (let i = 0; i <= q - l; i++) {
let temp = [0.0, 0.0, 0.0]; // Temporary point to accumulate the influence of the basis functions
for (let j = 0; j <= p - k; j++) {
temp[0] += Nu[j][p - k] * PKL[k][l][j][i][0]; // x-coordinate
temp[1] += Nu[j][p - k] * PKL[k][l][j][i][1]; // y-coordinate
temp[2] += Nu[j][p - k] * PKL[k][l][j][i][2]; // z-coordinate (if 3D)
}
SKL[k][l][0] += Nv[i][q - l] * temp[0];
SKL[k][l][1] += Nv[i][q - l] * temp[1];
SKL[k][l][2] += Nv[i][q - l] * temp[2];
}
}
}
return SKL;
}
// Example usage of ALGORITHM A3.8
// let n = /* the number of control points in u direction minus 1 */;
// let p = /* the degree in u direction */;
// let U = [/* the knot vector in u direction */];
// let m = /* the number of control points in v direction minus 1 */;
// let q = /* the degree in v direction */;
// let V = [/* the knot vector in v direction */];
// let P = [/* the control point grid */];
// let u = /* parameter value in u direction */;
// let v = /* parameter value in v direction */;
// let d = /* the order of derivatives */;
// let surfaceDerivatives = SurfaceDerivsAlg2(n, p, U, m, q, V, P, u, v, d);
// console.log(surfaceDerivatives); // This will output the surface derivatives at (u, v)
//--------------------Chapter 4 : Rational B-spline Curves and Surfaces
// ALGORITHM A4.1
// Function to compute point on rational B-spline curve.
function CurvePoint(n, p, U, Pw, u) {
// Compute point on rational B-spline curve
// Input: n (number of control points minus 1), p (degree of the curve), U (knot vector), Pw (control points with weights), u (parameter value)
// Output: C (point on the curve)
let span = FindSpan(n, p, u, U);