20 #ifndef MIRTK_BSpline_H 21 #define MIRTK_BSpline_H 23 #include "mirtk/Config.h" 24 #include "mirtk/Math.h" 25 #include "mirtk/Stream.h" 27 #include "mirtk/NumericsExport.h" 70 template <
class TReal>
94 MIRTKCU_API
static TReal
Weight(TReal);
101 MIRTKCU_API
static void Weights(TReal, TReal[4]);
139 MIRTKCU_API
static TReal
B(TReal);
142 MIRTKCU_API
static TReal
B(
int, TReal);
145 MIRTKCU_API
static TReal
B0(TReal);
148 MIRTKCU_API
static TReal
B1(TReal);
151 MIRTKCU_API
static TReal
B2(TReal);
154 MIRTKCU_API
static TReal
B3(TReal);
157 MIRTKCU_API
static TReal
B_I(TReal);
160 MIRTKCU_API
static TReal
B_I(
int, TReal);
163 MIRTKCU_API
static TReal
B0_I(TReal);
166 MIRTKCU_API
static TReal
B1_I(TReal);
169 MIRTKCU_API
static TReal
B2_I(TReal);
172 MIRTKCU_API
static TReal
B3_I(TReal);
175 MIRTKCU_API
static TReal
B_II(TReal);
178 MIRTKCU_API
static TReal
B_II(
int, TReal);
181 MIRTKCU_API
static TReal
B0_II(TReal);
184 MIRTKCU_API
static TReal
B1_II(TReal);
187 MIRTKCU_API
static TReal
B2_II(TReal);
190 MIRTKCU_API
static TReal
B3_II(TReal);
193 MIRTKCU_API
static TReal
B_III(TReal);
196 MIRTKCU_API
static TReal
B_III(
int, TReal);
199 MIRTKCU_API
static TReal
B0_III(TReal);
202 MIRTKCU_API
static TReal
B1_III(TReal);
205 MIRTKCU_API
static TReal
B2_III(TReal);
208 MIRTKCU_API
static TReal
B3_III(TReal);
211 MIRTKCU_API
static TReal
B_nI(
int, TReal);
214 MIRTKCU_API
static TReal
B_nI(
int,
int, TReal);
217 MIRTKCU_API
static TReal
B0_nI(
int, TReal);
220 MIRTKCU_API
static TReal
B1_nI(
int, TReal);
223 MIRTKCU_API
static TReal
B2_nI(
int, TReal);
226 MIRTKCU_API
static TReal
B3_nI(
int, TReal);
249 #endif // defined(__clang__) 254 template <
class TReal>
256 TReal(1.0/6.0), TReal(2.0/3.0), TReal(1.0/6.0), TReal(0.0)
259 template <
class TReal>
261 TReal(-0.5), TReal(0.0), TReal(0.5), TReal(0.0)
264 template <
class TReal>
266 TReal(1.0), TReal(-2.0), TReal(1.0), TReal(0.0)
277 template <
class TReal>
280 TReal c =
static_cast<TReal
>(1.0 - t);
283 value[0] =
static_cast<TReal
>(c * c * c / 6.0);
284 value[1] =
static_cast<TReal
>(( 3.0 * a - 6.0 * b + 4.0) / 6.0);
285 value[2] =
static_cast<TReal
>((-3.0 * a + 3.0 * b + 3.0 * t + 1.0) / 6.0);
286 value[3] =
static_cast<TReal
>(a / 6.0);
290 template <
class TReal>
297 value = 2.0/3.0 + (0.5*t-1.0)*t*t;
303 return static_cast<TReal
>(value);
307 template <
class TReal>
314 template <
class TReal>
318 case 0:
return B0(t);
319 case 1:
return B1(t);
320 case 2:
return B2(t);
321 case 3:
return B3(t);
322 default:
return TReal(0);
327 template <
class TReal>
330 return static_cast<TReal
>((1.0-t)*(1.0-t)*(1.0-t)/6.0);
334 template <
class TReal>
337 return static_cast<TReal
>((3.0*t*t*t - 6.0*t*t + 4.0)/6.0);
341 template <
class TReal>
344 return static_cast<TReal
>((-3.0*t*t*t + 3.0*t*t + 3.0*t + 1.0)/6.0);
348 template <
class TReal>
351 return static_cast<TReal
>((t*t*t)/6.0);
355 template <
class TReal>
362 value = (1.5 * y - 2.0) * t;
365 value = -0.5 * y * y;
366 if (t < 0.0) value = -value;
369 return static_cast<TReal
>(value);
373 template <
class TReal>
377 case 0:
return B0_I(t);
378 case 1:
return B1_I(t);
379 case 2:
return B2_I(t);
380 case 3:
return B3_I(t);
381 default:
return TReal(0);
386 template <
class TReal>
389 return static_cast<TReal
>(-(1.0-t)*(1.0-t)/2.0);
393 template <
class TReal>
396 return static_cast<TReal
>((9.0*t*t - 12.0*t)/6.0);
400 template <
class TReal>
403 return static_cast<TReal
>((-9.0*t*t + 6.0*t + 3.0)/6.0);
407 template <
class TReal>
410 return static_cast<TReal
>((t*t)/2.0);
414 template <
class TReal>
421 value = 3.0 * t - 2.0;
426 return static_cast<TReal
>(value);
430 template <
class TReal>
434 case 0:
return B0_II(t);
435 case 1:
return B1_II(t);
436 case 2:
return B2_II(t);
437 case 3:
return B3_II(t);
438 default:
return TReal(0);
443 template <
class TReal>
446 return static_cast<TReal
>(1.0 - t);
450 template <
class TReal>
453 return static_cast<TReal
>(3.0*t - 2.0);
457 template <
class TReal>
460 return static_cast<TReal
>(-3.0*t + 1.0);
464 template <
class TReal>
471 template <
class TReal>
474 TReal y = fabs(t), value;
477 value = copysign(TReal(3.0), t);
479 value = copysign(TReal(1.0), -t);
488 template <
class TReal>
496 default:
return TReal(0);
501 template <
class TReal>
508 template <
class TReal>
515 template <
class TReal>
522 template <
class TReal>
529 template <
class TReal>
533 case 0:
return B (t);
534 case 1:
return B_I (t);
535 case 2:
return B_II (t);
536 case 3:
return B_III(t);
537 default:
return TReal(0);
542 template <
class TReal>
546 case 0:
return B (i, t);
547 case 1:
return B_I (i, t);
548 case 2:
return B_II (i, t);
549 case 3:
return B_III(i, t);
550 default:
return TReal(0);
555 template <
class TReal>
559 case 0:
return B0 (t);
560 case 1:
return B0_I (t);
561 case 2:
return B0_II (t);
563 default:
return TReal(0);
568 template <
class TReal>
572 case 0:
return B1 (t);
573 case 1:
return B1_I (t);
574 case 2:
return B1_II (t);
576 default:
return TReal(0);
581 template <
class TReal>
585 case 0:
return B2 (t);
586 case 1:
return B2_I (t);
587 case 2:
return B2_II (t);
589 default:
return TReal(0);
594 template <
class TReal>
598 case 0:
return B3 (t);
599 case 1:
return B3_I (t);
600 case 2:
return B3_II (t);
602 default:
return TReal(0);
607 template <
class TReal>
613 for (
int l = 0; l < 4; l++) {
614 LookupTable [i][l] =
B (l, static_cast<TReal>(i) / static_cast<TReal>(LookupTableSize-1));
615 LookupTable_I [i][l] =
B_I (l, static_cast<TReal>(i) / static_cast<TReal>(LookupTableSize-1));
616 LookupTable_II[i][l] =
B_II(l, static_cast<TReal>(i) / static_cast<TReal>(LookupTableSize-1));
624 template <
class TReal>
627 if (t < .0)
return 0;
633 template <
class TReal>
672 template <
class TReal>
674 int xIndex [6],
int yIndex [6],
675 TReal xWeight[6], TReal yWeight[6])
679 if (spline_degree & 1) {
680 i =
static_cast<int>(floor(x )) - spline_degree / 2;
681 j =
static_cast<int>(floor(y )) - spline_degree / 2;
683 i =
static_cast<int>(floor(x + 0.5)) - spline_degree / 2;
684 j =
static_cast<int>(floor(y + 0.5)) - spline_degree / 2;
686 for (
int m = 0; m <= spline_degree; m++) {
692 double w, w2, w4, t, t0, t1;
694 switch (spline_degree) {
697 w = x -
static_cast<double>(xIndex[1]);
698 xWeight[1] = TReal(3.0 / 4.0 - w * w);
699 xWeight[2] = TReal((1.0 / 2.0) * (w - xWeight[1] + 1.0));
700 xWeight[0] = TReal(1.0 - xWeight[1] - xWeight[2]);
702 w = y -
static_cast<double>(yIndex[1]);
703 yWeight[1] = TReal(3.0 / 4.0 - w * w);
704 yWeight[2] = TReal((1.0 / 2.0) * (w - yWeight[1] + 1.0));
705 yWeight[0] = TReal(1.0 - yWeight[1] - yWeight[2]);
709 w = x -
static_cast<double>(xIndex[1]);
710 xWeight[3] = TReal((1.0 / 6.0) * w * w * w);
711 xWeight[0] = TReal((1.0 / 6.0) + (1.0 / 2.0) * w * (w - 1.0) - xWeight[3]);
712 xWeight[2] = TReal(w + xWeight[0] - 2.0 * xWeight[3]);
713 xWeight[1] = TReal(1.0 - xWeight[0] - xWeight[2] - xWeight[3]);
715 w = y -
static_cast<double>(yIndex[1]);
716 yWeight[3] = TReal((1.0 / 6.0) * w * w * w);
717 yWeight[0] = TReal((1.0 / 6.0) + (1.0 / 2.0) * w * (w - 1.0) - yWeight[3]);
718 yWeight[2] = TReal(w + yWeight[0] - 2.0 * yWeight[3]);
719 yWeight[1] = TReal(1.0 - yWeight[0] - yWeight[2] - yWeight[3]);
723 w = x -
static_cast<double>(xIndex[2]);
725 t = (1.0 / 6.0) * w2;
726 xWeight[0] = TReal(1.0 / 2.0 - w);
727 xWeight[0] *= xWeight[0];
728 xWeight[0] *= TReal(1.0 / 24.0) * xWeight[0];
729 t0 = w * (t - 11.0 / 24.0);
730 t1 = 19.0 / 96.0 + w2 * (1.0 / 4.0 - t);
731 xWeight[1] = TReal(t1 + t0);
732 xWeight[3] = TReal(t1 - t0);
733 xWeight[4] = TReal(xWeight[0] + t0 + (1.0 / 2.0) * w);
734 xWeight[2] = TReal(1.0 - xWeight[0] - xWeight[1] - xWeight[3] - xWeight[4]);
736 w = y -
static_cast<double>(yIndex[2]);
738 t = (1.0 / 6.0) * w2;
739 yWeight[0] = TReal(1.0 / 2.0 - w);
740 yWeight[0] *= yWeight[0];
741 yWeight[0] *= TReal(1.0 / 24.0) * yWeight[0];
742 t0 = w * (t - 11.0 / 24.0);
743 t1 = 19.0 / 96.0 + w2 * (1.0 / 4.0 - t);
744 yWeight[1] = TReal(t1 + t0);
745 yWeight[3] = TReal(t1 - t0);
746 yWeight[4] = TReal(yWeight[0] + t0 + (1.0 / 2.0) * w);
747 yWeight[2] = TReal(1.0 - yWeight[0] - yWeight[1] - yWeight[3] - yWeight[4]);
751 w = x -
static_cast<double>(xIndex[2]);
753 xWeight[5] = TReal((1.0 / 120.0) * w * w2 * w2);
758 xWeight[0] = TReal((1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - xWeight[5]);
759 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
760 t1 = (-1.0 / 12.0) * w * (t + 4.0);
761 xWeight[2] = TReal(t0 + t1);
762 xWeight[3] = TReal(t0 - t1);
763 t0 = (1.0 / 16.0) * (9.0 / 5.0 - t);
764 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
765 xWeight[1] = TReal(t0 + t1);
766 xWeight[4] = TReal(t0 - t1);
768 w = y -
static_cast<double>(yIndex[2]);
770 yWeight[5] = TReal((1.0 / 120.0) * w * w2 * w2);
775 yWeight[0] = TReal((1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - yWeight[5]);
776 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
777 t1 = (-1.0 / 12.0) * w * (t + 4.0);
778 yWeight[2] = TReal(t0 + t1);
779 yWeight[3] = TReal(t0 - t1);
780 t0 = (1.0 / 16.0) * (9.0 / 5.0 - t);
781 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
782 yWeight[1] = TReal(t0 + t1);
783 yWeight[4] = TReal(t0 - t1);
786 cerr <<
"ComputeBSplineIndicesAndWeights: Unsupported B-spline degree: " << spline_degree << endl;
793 template <
class TReal>
795 int xIndex [6],
int yIndex [6],
int zIndex [6],
796 TReal xWeight[6], TReal yWeight[6], TReal zWeight[6])
801 if (spline_degree & 1) {
802 i =
static_cast<int>(floor(x)) - spline_degree / 2;
803 j =
static_cast<int>(floor(y)) - spline_degree / 2;
804 k =
static_cast<int>(floor(z)) - spline_degree / 2;
805 for (m = 0; m <= spline_degree; m++) {
811 i =
static_cast<int>(floor(x + 0.5)) - spline_degree / 2;
812 j =
static_cast<int>(floor(y + 0.5)) - spline_degree / 2;
813 k =
static_cast<int>(floor(z + 0.5)) - spline_degree / 2;
814 for (m = 0; m <= spline_degree; m++) {
822 double w, w2, w4, t, t0, t1;
824 switch (spline_degree) {
827 w = x -
static_cast<double>(xIndex[1]);
828 xWeight[1] = TReal(3.0 / 4.0 - w * w);
829 xWeight[2] = TReal((1.0 / 2.0) * (w - xWeight[1] + 1.0));
830 xWeight[0] = TReal(1.0 - xWeight[1] - xWeight[2]);
832 w = y -
static_cast<double>(yIndex[1]);
833 yWeight[1] = TReal(3.0 / 4.0 - w * w);
834 yWeight[2] = TReal((1.0 / 2.0) * (w - yWeight[1] + 1.0));
835 yWeight[0] = TReal(1.0 - yWeight[1] - yWeight[2]);
837 w = z -
static_cast<double>(zIndex[1]);
838 zWeight[1] = TReal(3.0 / 4.0 - w * w);
839 zWeight[2] = TReal((1.0 / 2.0) * (w - zWeight[1] + 1.0));
840 zWeight[0] = TReal(1.0 - zWeight[1] - zWeight[2]);
844 w = x -
static_cast<double>(xIndex[1]);
845 xWeight[3] = TReal((1.0 / 6.0) * w * w * w);
846 xWeight[0] = TReal((1.0 / 6.0) + (1.0 / 2.0) * w * (w - 1.0) - xWeight[3]);
847 xWeight[2] = TReal(w + xWeight[0] - 2.0 * xWeight[3]);
848 xWeight[1] = TReal(1.0 - xWeight[0] - xWeight[2] - xWeight[3]);
850 w = y -
static_cast<double>(yIndex[1]);
851 yWeight[3] = TReal((1.0 / 6.0) * w * w * w);
852 yWeight[0] = TReal((1.0 / 6.0) + (1.0 / 2.0) * w * (w - 1.0) - yWeight[3]);
853 yWeight[2] = TReal(w + yWeight[0] - 2.0 * yWeight[3]);
854 yWeight[1] = TReal(1.0 - yWeight[0] - yWeight[2] - yWeight[3]);
856 w = z -
static_cast<double>(zIndex[1]);
857 zWeight[3] = TReal((1.0 / 6.0) * w * w * w);
858 zWeight[0] = TReal((1.0 / 6.0) + (1.0 / 2.0) * w * (w - 1.0) - zWeight[3]);
859 zWeight[2] = TReal(w + zWeight[0] - 2.0 * zWeight[3]);
860 zWeight[1] = TReal(1.0 - zWeight[0] - zWeight[2] - zWeight[3]);
864 w = x -
static_cast<double>(xIndex[2]);
866 t = (1.0 / 6.0) * w2;
867 xWeight[0] = TReal(1.0 / 2.0 - w);
868 xWeight[0] *= xWeight[0];
869 xWeight[0] *= TReal(1.0 / 24.0) * xWeight[0];
870 t0 = w * (t - 11.0 / 24.0);
871 t1 = 19.0 / 96.0 + w2 * (1.0 / 4.0 - t);
872 xWeight[1] = TReal(t1 + t0);
873 xWeight[3] = TReal(t1 - t0);
874 xWeight[4] = TReal(xWeight[0] + t0 + (1.0 / 2.0) * w);
875 xWeight[2] = TReal(1.0 - xWeight[0] - xWeight[1] - xWeight[3] - xWeight[4]);
877 w = y -
static_cast<double>(yIndex[2]);
879 t = (1.0 / 6.0) * w2;
880 yWeight[0] = TReal(1.0 / 2.0 - w);
881 yWeight[0] *= yWeight[0];
882 yWeight[0] *= TReal(1.0 / 24.0) * yWeight[0];
883 t0 = w * (t - 11.0 / 24.0);
884 t1 = 19.0 / 96.0 + w2 * (1.0 / 4.0 - t);
885 yWeight[1] = TReal(t1 + t0);
886 yWeight[3] = TReal(t1 - t0);
887 yWeight[4] = TReal(yWeight[0] + t0 + (1.0 / 2.0) * w);
888 yWeight[2] = TReal(1.0 - yWeight[0] - yWeight[1] - yWeight[3] - yWeight[4]);
890 w = z -
static_cast<double>(zIndex[2]);
892 t = (1.0 / 6.0) * w2;
893 zWeight[0] = TReal(1.0 / 2.0 - w);
894 zWeight[0] *= zWeight[0];
895 zWeight[0] *= TReal(1.0 / 24.0) * zWeight[0];
896 t0 = w * (t - 11.0 / 24.0);
897 t1 = 19.0 / 96.0 + w2 * (1.0 / 4.0 - t);
898 zWeight[1] = TReal(t1 + t0);
899 zWeight[3] = TReal(t1 - t0);
900 zWeight[4] = TReal(zWeight[0] + t0 + (1.0 / 2.0) * w);
901 zWeight[2] = TReal(1.0 - zWeight[0] - zWeight[1] - zWeight[3] - zWeight[4]);
905 w = x -
static_cast<double>(xIndex[2]);
907 xWeight[5] = TReal((1.0 / 120.0) * w * w2 * w2);
912 xWeight[0] = TReal((1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - xWeight[5]);
913 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
914 t1 = (-1.0 / 12.0) * w * (t + 4.0);
915 xWeight[2] = TReal(t0 + t1);
916 xWeight[3] = TReal(t0 - t1);
917 t0 = (1.0 / 16.0) * (9.0 / 5.0 - t);
918 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
919 xWeight[1] = TReal(t0 + t1);
920 xWeight[4] = TReal(t0 - t1);
922 w = y -
static_cast<double>(yIndex[2]);
924 yWeight[5] = TReal((1.0 / 120.0) * w * w2 * w2);
929 yWeight[0] = TReal((1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - yWeight[5]);
930 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
931 t1 = (-1.0 / 12.0) * w * (t + 4.0);
932 yWeight[2] = TReal(t0 + t1);
933 yWeight[3] = TReal(t0 - t1);
934 t0 = (1.0 / 16.0) * (9.0 / 5.0 - t);
935 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
936 yWeight[1] = TReal(t0 + t1);
937 yWeight[4] = TReal(t0 - t1);
939 w = z -
static_cast<double>(zIndex[2]);
941 zWeight[5] = TReal((1.0 / 120.0) * w * w2 * w2);
946 zWeight[0] = TReal((1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - zWeight[5]);
947 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
948 t1 = (-1.0 / 12.0) * w * (t + 4.0);
949 zWeight[2] = TReal(t0 + t1);
950 zWeight[3] = TReal(t0 - t1);
951 t0 = (1.0 / 16.0) * (9.0 / 5.0 - t);
952 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
953 zWeight[1] = TReal(t0 + t1);
954 zWeight[4] = TReal(t0 - t1);
957 cerr <<
"ComputeBSplineIndicesAndWeights: Unsupported B-spline degree: " << spline_degree << endl;
964 template <
class TReal>
966 int xIndex [6],
int yIndex [6],
int zIndex [6],
int tIndex[6],
967 TReal xWeight[6], TReal yWeight[6], TReal zWeight[6], TReal tWeight[6])
972 if (spline_degree & 1) {
973 i =
ifloor(x) - spline_degree / 2;
974 j =
ifloor(y) - spline_degree / 2;
975 k =
ifloor(z) - spline_degree / 2;
976 l =
ifloor(t) - spline_degree / 2;
977 for (m = 0; m <= spline_degree; m++) {
984 i =
ifloor(x + .5) - spline_degree / 2;
985 j =
ifloor(y + .5) - spline_degree / 2;
986 k =
ifloor(z + .5) - spline_degree / 2;
987 l =
ifloor(t + .5) - spline_degree / 2;
988 for (m = 0; m <= spline_degree; m++) {
997 double w, w2, w4, t0, t1;
999 switch (spline_degree) {
1002 w = x -
static_cast<double>(xIndex[1]);
1003 xWeight[1] = TReal(3.0 / 4.0 - w * w);
1004 xWeight[2] = TReal((1.0 / 2.0) * (w - xWeight[1] + 1.0));
1005 xWeight[0] = TReal(1.0 - xWeight[1] - xWeight[2]);
1007 w = y -
static_cast<double>(yIndex[1]);
1008 yWeight[1] = TReal(3.0 / 4.0 - w * w);
1009 yWeight[2] = TReal((1.0 / 2.0) * (w - yWeight[1] + 1.0));
1010 yWeight[0] = TReal(1.0 - yWeight[1] - yWeight[2]);
1012 w = z -
static_cast<double>(zIndex[1]);
1013 zWeight[1] = TReal(3.0 / 4.0 - w * w);
1014 zWeight[2] = TReal((1.0 / 2.0) * (w - zWeight[1] + 1.0));
1015 zWeight[0] = TReal(1.0 - zWeight[1] - zWeight[2]);
1017 w = t -
static_cast<double>(tIndex[1]);
1018 tWeight[1] = TReal(3.0 / 4.0 - w * w);
1019 tWeight[2] = TReal((1.0 / 2.0) * (w - tWeight[1] + 1.0));
1020 tWeight[0] = TReal(1.0 - tWeight[1] - tWeight[2]);
1024 w = x -
static_cast<double>(xIndex[1]);
1025 xWeight[3] = TReal((1.0 / 6.0) * w * w * w);
1026 xWeight[0] = TReal((1.0 / 6.0) + (1.0 / 2.0) * w * (w - 1.0) - xWeight[3]);
1027 xWeight[2] = TReal(w + xWeight[0] - 2.0 * xWeight[3]);
1028 xWeight[1] = TReal(1.0 - xWeight[0] - xWeight[2] - xWeight[3]);
1030 w = y -
static_cast<double>(yIndex[1]);
1031 yWeight[3] = TReal((1.0 / 6.0) * w * w * w);
1032 yWeight[0] = TReal((1.0 / 6.0) + (1.0 / 2.0) * w * (w - 1.0) - yWeight[3]);
1033 yWeight[2] = TReal(w + yWeight[0] - 2.0 * yWeight[3]);
1034 yWeight[1] = TReal(1.0 - yWeight[0] - yWeight[2] - yWeight[3]);
1036 w = z -
static_cast<double>(zIndex[1]);
1037 zWeight[3] = TReal((1.0 / 6.0) * w * w * w);
1038 zWeight[0] = TReal((1.0 / 6.0) + (1.0 / 2.0) * w * (w - 1.0) - zWeight[3]);
1039 zWeight[2] = TReal(w + zWeight[0] - 2.0 * zWeight[3]);
1040 zWeight[1] = TReal(1.0 - zWeight[0] - zWeight[2] - zWeight[3]);
1042 w = t -
static_cast<double>(tIndex[1]);
1043 tWeight[3] = TReal((1.0 / 6.0) * w * w * w);
1044 tWeight[0] = TReal((1.0 / 6.0) + (1.0 / 2.0) * w * (w - 1.0) - tWeight[3]);
1045 tWeight[2] = TReal(w + tWeight[0] - 2.0 * tWeight[3]);
1046 tWeight[1] = TReal(1.0 - tWeight[0] - tWeight[2] - tWeight[3]);
1050 w = x -
static_cast<double>(xIndex[2]);
1052 t = (1.0 / 6.0) * w2;
1053 xWeight[0] = TReal(1.0 / 2.0 - w);
1054 xWeight[0] *= xWeight[0];
1055 xWeight[0] *= TReal(1.0 / 24.0) * xWeight[0];
1056 t0 = w * (t - 11.0 / 24.0);
1057 t1 = 19.0 / 96.0 + w2 * (1.0 / 4.0 - t);
1058 xWeight[1] = TReal(t1 + t0);
1059 xWeight[3] = TReal(t1 - t0);
1060 xWeight[4] = TReal(xWeight[0] + t0 + (1.0 / 2.0) * w);
1061 xWeight[2] = TReal(1.0 - xWeight[0] - xWeight[1] - xWeight[3] - xWeight[4]);
1063 w = y -
static_cast<double>(yIndex[2]);
1065 t = (1.0 / 6.0) * w2;
1066 yWeight[0] = TReal(1.0 / 2.0 - w);
1067 yWeight[0] *= yWeight[0];
1068 yWeight[0] *= TReal(1.0 / 24.0) * yWeight[0];
1069 t0 = w * (t - 11.0 / 24.0);
1070 t1 = 19.0 / 96.0 + w2 * (1.0 / 4.0 - t);
1071 yWeight[1] = TReal(t1 + t0);
1072 yWeight[3] = TReal(t1 - t0);
1073 yWeight[4] = TReal(yWeight[0] + t0 + (1.0 / 2.0) * w);
1074 yWeight[2] = TReal(1.0 - yWeight[0] - yWeight[1] - yWeight[3] - yWeight[4]);
1076 w = z -
static_cast<double>(zIndex[2]);
1078 t = (1.0 / 6.0) * w2;
1079 zWeight[0] = TReal(1.0 / 2.0 - w);
1080 zWeight[0] *= zWeight[0];
1081 zWeight[0] *= TReal(1.0 / 24.0) * zWeight[0];
1082 t0 = w * (t - 11.0 / 24.0);
1083 t1 = 19.0 / 96.0 + w2 * (1.0 / 4.0 - t);
1084 zWeight[1] = TReal(t1 + t0);
1085 zWeight[3] = TReal(t1 - t0);
1086 zWeight[4] = TReal(zWeight[0] + t0 + (1.0 / 2.0) * w);
1087 zWeight[2] = TReal(1.0 - zWeight[0] - zWeight[1] - zWeight[3] - zWeight[4]);
1089 w = t -
static_cast<double>(tIndex[2]);
1091 t = (1.0 / 6.0) * w2;
1092 tWeight[0] = TReal(1.0 / 2.0 - w);
1093 tWeight[0] *= tWeight[0];
1094 tWeight[0] *= TReal(1.0 / 24.0) * tWeight[0];
1095 t0 = w * (t - 11.0 / 24.0);
1096 t1 = 19.0 / 96.0 + w2 * (1.0 / 4.0 - t);
1097 tWeight[1] = TReal(t1 + t0);
1098 tWeight[3] = TReal(t1 - t0);
1099 tWeight[4] = TReal(tWeight[0] + t0 + (1.0 / 2.0) * w);
1100 tWeight[2] = TReal(1.0 - tWeight[0] - tWeight[1] - tWeight[3] - tWeight[4]);
1104 w = x -
static_cast<double>(xIndex[2]);
1106 xWeight[5] = TReal((1.0 / 120.0) * w * w2 * w2);
1110 t = w2 * (w2 - 3.0);
1111 xWeight[0] = TReal((1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - xWeight[5]);
1112 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
1113 t1 = (-1.0 / 12.0) * w * (t + 4.0);
1114 xWeight[2] = TReal(t0 + t1);
1115 xWeight[3] = TReal(t0 - t1);
1116 t0 = (1.0 / 16.0) * (9.0 / 5.0 - t);
1117 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
1118 xWeight[1] = TReal(t0 + t1);
1119 xWeight[4] = TReal(t0 - t1);
1121 w = y -
static_cast<double>(yIndex[2]);
1123 yWeight[5] = TReal((1.0 / 120.0) * w * w2 * w2);
1127 t = w2 * (w2 - 3.0);
1128 yWeight[0] = TReal((1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - yWeight[5]);
1129 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
1130 t1 = (-1.0 / 12.0) * w * (t + 4.0);
1131 yWeight[2] = TReal(t0 + t1);
1132 yWeight[3] = TReal(t0 - t1);
1133 t0 = (1.0 / 16.0) * (9.0 / 5.0 - t);
1134 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
1135 yWeight[1] = TReal(t0 + t1);
1136 yWeight[4] = TReal(t0 - t1);
1138 w = z -
static_cast<double>(zIndex[2]);
1140 zWeight[5] = TReal((1.0 / 120.0) * w * w2 * w2);
1144 t = w2 * (w2 - 3.0);
1145 zWeight[0] = TReal((1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - zWeight[5]);
1146 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
1147 t1 = (-1.0 / 12.0) * w * (t + 4.0);
1148 zWeight[2] = TReal(t0 + t1);
1149 zWeight[3] = TReal(t0 - t1);
1150 t0 = (1.0 / 16.0) * (9.0 / 5.0 - t);
1151 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
1152 zWeight[1] = TReal(t0 + t1);
1153 zWeight[4] = TReal(t0 - t1);
1155 w = t -
static_cast<double>(tIndex[2]);
1157 tWeight[5] = TReal((1.0 / 120.0) * w * w2 * w2);
1161 t = w2 * (w2 - 3.0);
1162 tWeight[0] = TReal((1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - tWeight[5]);
1163 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
1164 t1 = (-1.0 / 12.0) * w * (t + 4.0);
1165 tWeight[2] = TReal(t0 + t1);
1166 tWeight[3] = TReal(t0 - t1);
1167 t0 = (1.0 / 16.0) * (9.0 / 5.0 - t);
1168 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
1169 tWeight[1] = TReal(t0 + t1);
1170 tWeight[4] = TReal(t0 - t1);
1173 cerr <<
"ComputeBSplineIndicesAndWeights: Unsupported B-spline degree: " << spline_degree << endl;
1181 #endif // MIRTK_BSpline_H static int VariableToIndex(TReal)
Returns the lookup table index for a given value in [0,1].
static MIRTKCU_API TReal Weight(TReal)
Returns the value of the B-spline function.
static MIRTKCU_API TReal B_I(TReal)
Returns the 1st derivative value of the B-spline function.
static MIRTKCU_API TReal B(TReal)
Returns the value of the B-spline function.
static MIRTKCU_API TReal B3(TReal)
Returns the value of the fourth B-spline basis function.
static MIRTK_Numerics_EXPORT TReal LookupTable_II[LookupTableSize][4]
Lookup table of B-spline basis function 2nd derivative values.
static MIRTKCU_API TReal B2(TReal)
Returns the value of the third B-spline basis function.
static MIRTKCU_API TReal B2_II(TReal)
Returns the 2nd derivative value of the third B-spline basis function.
static MIRTKCU_API TReal B1_III(TReal)
Returns the 3rd derivative value of the second B-spline basis function.
static MIRTK_Numerics_EXPORT TReal WeightLookupTable[LookupTableSize]
Lookup table of B-spline function values.
TReal RealType
Floating point precision type used.
static MIRTKCU_API TReal B2_III(TReal)
Returns the 3rd derivative value of the third B-spline basis function.
static MIRTKCU_API TReal B0_nI(int, TReal)
Returns the n-th derivative value of the first B-spline basis function.
static MIRTKCU_API TReal B1(TReal)
Returns the value of the second B-spline basis function.
MIRTKCU_API int ifloor(T x)
Round floating-point value to next smaller integer and cast to int.
static MIRTKCU_API TReal B3_nI(int, TReal)
Returns the n-th derivative value of the fourth B-spline basis function.
static MIRTKCU_API TReal B0_I(TReal)
Returns the 1st derivative value of the first B-spline basis function.
static MIRTKCU_API TReal B_II(TReal)
Returns the 2nd derivative value of the B-spline function.
static const unsigned int LookupTableSize
Size of lookup tables of pre-computed B-spline values.
static MIRTK_Numerics_EXPORT TReal LookupTable[LookupTableSize][4]
Lookup table of B-spline basis function values.
static MIRTKCU_API TReal B_III(TReal)
Returns the 3rd derivative value of the B-spline function.
static MIRTKCU_API TReal B2_nI(int, TReal)
Returns the n-th derivative value of the third B-spline basis function.
static const TReal LatticeWeights_I[4]
static const TReal LatticeWeights_II[4]
static MIRTKCU_API TReal B3_II(TReal)
Returns the 2nd derivative value of the fourth B-spline basis function.
void ComputeBSplineIndicesAndWeights(double x, double y, int spline_degree, int xIndex [6], int yIndex [6], TReal xWeight[6], TReal yWeight[6])
Compute indices and weights required for 2D B-spline interpolation.
static MIRTKCU_API TReal B1_II(TReal)
Returns the 2nd derivative value of the second B-spline basis function.
static MIRTKCU_API void Weights(TReal, TReal[4])
static MIRTKCU_API TReal B_nI(int, TReal)
Returns the n-th derivative value of the B-spline function.
static void Initialize(bool=false)
Initialize lookup tables.
static MIRTKCU_API TReal B1_I(TReal)
Returns the 1st derivative value of the second B-spline basis function.
static MIRTK_Numerics_EXPORT bool _initialized
Flag which indicates whether the lookup tables are initialized.
static MIRTKCU_API TReal B0_II(TReal)
Returns the 2nd derivative value of the first B-spline basis function.
MIRTKCU_API int iround(T x)
Round floating-point value and cast to int.
static MIRTKCU_API TReal B2_I(TReal)
Returns the 1st derivative value of the third B-spline basis function.
static MIRTKCU_API TReal B0_III(TReal)
Returns the 3rd derivative value of the first B-spline basis function.
static MIRTKCU_API TReal B0(TReal)
Returns the value of the first B-spline basis function.
static MIRTKCU_API TReal B1_nI(int, TReal)
Returns the n-th derivative value of the second B-spline basis function.
static MIRTKCU_API TReal B3_I(TReal)
Returns the 1st derivative value of the fourth B-spline basis function.
static const TReal LatticeWeights[4]
static MIRTKCU_API TReal B3_III(TReal)
Returns the 3rd derivative value of the fourth B-spline basis function.
static MIRTK_Numerics_EXPORT TReal LookupTable_I[LookupTableSize][4]
Lookup table of B-spline basis function 1st derivative values.