74 #ifndef SLIP_BSPLINE_INTERPOLATION_HPP
75 #define SLIP_BSPLINE_INTERPOLATION_HPP
108 template <
class Array>
139 Poles[0] = -0.48829458930304475513011803888378906211227916123938;
140 Poles[1] = -0.081679271076237512597937765737059080653379610398148;
141 Poles[2] = -0.0014141518083258177510872439765585925278641690553467;
145 Poles[0] = -0.53528043079643816554240378168164607183392315234269;
146 Poles[1] = -0.12255461519232669051527226435935734360548654942730;
147 Poles[2] = -0.0091486948096082769285930216516478534156925639545994;
151 Poles[0] = -0.57468690924876543053013930412874542429066157804125;
152 Poles[1] = -0.16303526929728093524055189686073705223476814550830;
153 Poles[2] = -0.023632294694844850023403919296361320612665920854629;
154 Poles[3] = -0.00015382131064169091173935253018402160762964054070043;
158 Poles[0] = -0.60799738916862577900772082395428976943963471853991;
159 Poles[1] = -0.20175052019315323879606468505597043468089886575747;
160 Poles[2] = -0.043222608540481752133321142979429688265852380231497;
161 Poles[3] = -0.0021213069031808184203048965578486234220548560988624;
164 std::cerr<<
"Invalid spline degree"<<std::endl;;
183 template<
typename InputIterator>
186 InputIterator inlast,
191 std::size_t DataLength = inlast-infirst;
194 std::size_t Horizon = DataLength;
200 double Sum, zn, z2n, iz;
201 if (Horizon < DataLength)
206 InputIterator it = infirst+1;
207 for (std::size_t n = 1L; n < Horizon; n++,it++)
219 z2n = std::pow(z, (
double)(DataLength - 1L));
220 Sum = (*infirst) + z2n * (*(inlast-1));
222 for (InputIterator it=infirst+1; it!=inlast-1; it++)
224 Sum += (zn + z2n) * (*it);
228 return(Sum / (1.0 - zn * zn));
243 template<
typename InputIterator>
250 return ((z / (z * z - 1.0)) * (z * (*(outlast-1)) + (*outlast)));
281 template<
typename InputIterator,
282 typename OutputIterator,
283 typename InputIterator2>
286 InputIterator inlast,
287 OutputIterator outfirst,
288 InputIterator2 Poles_first,
289 InputIterator2 Poles_last,
295 std::size_t NbPoles =
static_cast<std::size_t
>(Poles_last - Poles_first);
297 std::size_t length = (inlast-infirst);
305 InputIterator2 it_poles = Poles_first;
306 for (std::size_t k = 0L; k < NbPoles; ++k, ++it_poles)
308 Lambda = Lambda * (1.0 - *it_poles) * (1.0 - 1.0 / *it_poles);
313 for (it=infirst,it2=outfirst;it!=inlast;it++,it2++)
319 it_poles = Poles_first;
320 for (std::size_t k = 0L; k < NbPoles; ++k, ++it_poles)
325 for (it=infirst+1,it2=outfirst+1;it!=inlast;it++,it2++)
327 *it2 += *it_poles * (*(it2-1));
333 for (it2--;it2!=outfirst-1;it2--)
335 *it2 = *it_poles * ((*(it2+1)) - *it2);
362 template<
typename InputIterator,
363 typename OutputIterator,
367 InputIterator inlast,
368 OutputIterator outfirst,
374 Poles.begin(),Poles.end(),
390 template<
typename RandomAccessIterator>
394 RandomAccessIterator index_first,
395 RandomAccessIterator index_last)
397 assert(static_cast<std::size_t>(index_last - index_first) == (spline_degree + 1));
398 long splinedegree=
static_cast<long>(spline_degree);
402 if (splinedegree & 1L)
404 i =
static_cast<long>(std::floor(x)) - splinedegree / 2L;
408 i =
static_cast<long>(std::floor(x + 0.5)) - spline_degree / 2L;
410 for (; index_first != index_last; ++index_first)
429 template<
typename RandomAccessIterator,
434 RandomAccessIterator index_first,
435 RandomAccessIterator index_last,
444 long SplineDegree=
static_cast<long>(spline_degree);
446 switch (SplineDegree)
451 w = x -
static_cast<double>(index_first[1]);
452 Weights[1] = 3.0 / 4.0 - w * w;
453 Weights[2] = (1.0 / 2.0) * (w - Weights[1] + 1.0);
454 Weights[0] = 1.0 - Weights[1] - Weights[2];
459 w = x -
static_cast<double>(index_first[1]);
460 Weights[3] = (1.0 / 6.0) * w * w * w;
461 Weights[0] = (1.0 / 6.0) + (1.0 / 2.0) * w * (w - 1.0) - Weights[3];
462 Weights[2] = w + Weights[0] - 2.0 * Weights[3];
463 Weights[1] = 1.0 - Weights[0] - Weights[2] - Weights[3];
468 w = x -
static_cast<double>(index_first[2]);
470 t = (1.0 / 6.0) * w2;
471 Weights[0] = 1.0 / 2.0 - w;
472 Weights[0] *= Weights[0];
473 Weights[0] *= (1.0 / 24.0) * Weights[0];
474 t0 = w * (t - 11.0 / 24.0);
475 t1 = 19.0 / 96.0 + w2 * (1.0 / 4.0 - t);
476 Weights[1] = t1 + t0;
477 Weights[3] = t1 - t0;
478 Weights[4] = Weights[0] + t0 + (1.0 / 2.0) * w;
479 Weights[2] = 1.0 - Weights[0] - Weights[1] - Weights[3] - Weights[4];
485 w = x -
static_cast<double>(index_first[2]);
487 Weights[5] = (1.0 / 120.0) * w * w2 * w2;
492 Weights[0] = (1.0 / 24.0) * (1.0 / 5.0 + w2 + w4) - Weights[5];
493 t0 = (1.0 / 24.0) * (w2 * (w2 - 5.0) + 46.0 / 5.0);
494 t1 = (-1.0 / 12.0) * w * (t + 4.0);
495 Weights[2] = t0 + t1;
496 Weights[3] = t0 - t1;
497 t0 = (1.0 / 16.0) * (9.0 / 5.0 - t);
498 t1 = (1.0 / 24.0) * w * (w4 - w2 - 5.0);
499 Weights[1] = t0 + t1;
500 Weights[4] = t0 - t1;
505 w = x -
static_cast<double>(index_first[3]);
506 Weights[0] = 1.0 / 2.0 - w;
507 Weights[0] *= Weights[0] * Weights[0];
508 Weights[0] *= Weights[0] / 720.0;
509 Weights[1] = (361.0 / 192.0 - w * (59.0 / 8.0 + w
510 * (-185.0 / 16.0 + w * (25.0 / 3.0 + w * (-5.0 / 2.0 + w)
511 * (1.0 / 2.0 + w))))) / 120.0;
512 Weights[2] = (10543.0 / 960.0 + w * (-289.0 / 16.0 + w
513 * (79.0 / 16.0 + w * (43.0 / 6.0 + w * (-17.0 / 4.0 + w
514 * (-1.0 + w)))))) / 48.0;
516 Weights[3] = (5887.0 / 320.0 - w2 * (231.0 / 16.0 - w2
517 * (21.0 / 4.0 - w2))) / 36.0;
518 Weights[4] = (10543.0 / 960.0 + w * (289.0 / 16.0 + w
519 * (79.0 / 16.0 + w * (-43.0 / 6.0 + w * (-17.0 / 4.0 + w
520 * (1.0 + w)))))) / 48.0;
521 Weights[6] = 1.0 / 2.0 + w;
522 Weights[6] *= Weights[6] * Weights[6];
523 Weights[6] *= Weights[6] / 720.0;
524 Weights[5] = 1.0 - Weights[0] - Weights[1] - Weights[2] - Weights[3]
525 - Weights[4] - Weights[6];
530 w = x -
static_cast<double>(index_first[3]);
531 Weights[0] = 1.0 - w;
532 Weights[0] *= Weights[0];
533 Weights[0] *= Weights[0] * Weights[0];
534 Weights[0] *= (1.0 - w) / 5040.0;
536 Weights[1] = (120.0 / 7.0 + w * (-56.0 + w * (72.0 + w
537 * (-40.0 + w2 * (12.0 + w * (-6.0 + w)))))) / 720.0;
538 Weights[2] = (397.0 / 7.0 - w * (245.0 / 3.0 + w * (-15.0 + w
539 * (-95.0 / 3.0 + w * (15.0 + w * (5.0 + w
540 * (-5.0 + w))))))) / 240.0;
541 Weights[3] = (2416.0 / 35.0 + w2 * (-48.0 + w2 * (16.0 + w2
542 * (-4.0 + w)))) / 144.0;
543 Weights[4] = (1191.0 / 35.0 - w * (-49.0 + w * (-9.0 + w
544 * (19.0 + w * (-3.0 + w) * (-3.0 + w2))))) / 144.0;
545 Weights[5] = (40.0 / 7.0 + w * (56.0 / 3.0 + w * (24.0 + w
546 * (40.0 / 3.0 + w2 * (-4.0 + w * (-2.0 + w)))))) / 240.0;
548 Weights[7] *= Weights[7] * Weights[7];
549 Weights[7] *= w / 5040.0;
550 Weights[6] = 1.0 - Weights[0] - Weights[1] - Weights[2] - Weights[3]
551 - Weights[4] - Weights[5] - Weights[7];
556 w = x -
static_cast<double>(index_first[4]);
557 Weights[0] = 1.0 / 2.0 - w;
558 Weights[0] *= Weights[0];
559 Weights[0] *= Weights[0];
560 Weights[0] *= Weights[0] / 40320.0;
562 Weights[1] = (39.0 / 16.0 - w * (6.0 + w * (-9.0 / 2.0 + w2)))
563 * (21.0 / 16.0 + w * (-15.0 / 4.0 + w * (9.0 / 2.0 + w
564 * (-3.0 + w)))) / 5040.0;
565 Weights[2] = (82903.0 / 1792.0 + w * (-4177.0 / 32.0 + w
566 * (2275.0 / 16.0 + w * (-487.0 / 8.0 + w * (-85.0 / 8.0 + w
567 * (41.0 / 2.0 + w * (-5.0 + w * (-2.0 + w)))))))) / 1440.0;
568 Weights[3] = (310661.0 / 1792.0 - w * (14219.0 / 64.0 + w
569 * (-199.0 / 8.0 + w * (-1327.0 / 16.0 + w * (245.0 / 8.0 + w
570 * (53.0 / 4.0 + w * (-8.0 + w * (-1.0 + w)))))))) / 720.0;
571 Weights[4] = (2337507.0 / 8960.0 + w2 * (-2601.0 / 16.0 + w2
572 * (387.0 / 8.0 + w2 * (-9.0 + w2)))) / 576.0;
573 Weights[5] = (310661.0 / 1792.0 - w * (-14219.0 / 64.0 + w
574 * (-199.0 / 8.0 + w * (1327.0 / 16.0 + w * (245.0 / 8.0 + w
575 * (-53.0 / 4.0 + w * (-8.0 + w * (1.0 + w)))))))) / 720.0;
576 Weights[7] = (39.0 / 16.0 - w * (-6.0 + w * (-9.0 / 2.0 + w2)))
577 * (21.0 / 16.0 + w * (15.0 / 4.0 + w * (9.0 / 2.0 + w
578 * (3.0 + w)))) / 5040.0;
579 Weights[8] = 1.0 / 2.0 + w;
580 Weights[8] *= Weights[8];
581 Weights[8] *= Weights[8];
582 Weights[8] *= Weights[8] / 40320.0;
583 Weights[6] = 1.0 - Weights[0] - Weights[1] - Weights[2] - Weights[3]
584 - Weights[4] - Weights[5] - Weights[7] - Weights[8];
589 w = x -
static_cast<double>(index_first[4]);
590 Weights[0] = 1.0 - w;
591 Weights[0] *= Weights[0];
592 Weights[0] *= Weights[0];
593 Weights[0] *= Weights[0] * (1.0 - w) / 362880.0;
594 Weights[1] = (502.0 / 9.0 + w * (-246.0 + w * (472.0 + w
595 * (-504.0 + w * (308.0 + w * (-84.0 + w * (-56.0 / 3.0 + w
596 * (24.0 + w * (-8.0 + w))))))))) / 40320.0;
597 Weights[2] = (3652.0 / 9.0 - w * (2023.0 / 2.0 + w * (-952.0 + w
598 * (938.0 / 3.0 + w * (112.0 + w * (-119.0 + w * (56.0 / 3.0 + w
599 * (14.0 + w * (-7.0 + w))))))))) / 10080.0;
600 Weights[3] = (44117.0 / 42.0 + w * (-2427.0 / 2.0 + w * (66.0 + w
601 * (434.0 + w * (-129.0 + w * (-69.0 + w * (34.0 + w * (6.0 + w
602 * (-6.0 + w))))))))) / 4320.0;
604 Weights[4] = (78095.0 / 63.0 - w2 * (700.0 + w2 * (-190.0 + w2
605 * (100.0 / 3.0 + w2 * (-5.0 + w))))) / 2880.0;
606 Weights[5] = (44117.0 / 63.0 + w * (809.0 + w * (44.0 + w
607 * (-868.0 / 3.0 + w * (-86.0 + w * (46.0 + w * (68.0 / 3.0 + w
608 * (-4.0 + w * (-4.0 + w))))))))) / 2880.0;
609 Weights[6] = (3652.0 / 21.0 - w * (-867.0 / 2.0 + w * (-408.0 + w
610 * (-134.0 + w * (48.0 + w * (51.0 + w * (-4.0 + w) * (-1.0 + w)
611 * (2.0 + w))))))) / 4320.0;
612 Weights[7] = (251.0 / 18.0 + w * (123.0 / 2.0 + w * (118.0 + w
613 * (126.0 + w * (77.0 + w * (21.0 + w * (-14.0 / 3.0 + w
614 * (-6.0 + w * (-2.0 + w))))))))) / 10080.0;
615 Weights[9] = w2 * w2;
616 Weights[9] *= Weights[9] * w / 362880.0;
617 Weights[8] = 1.0 - Weights[0] - Weights[1] - Weights[2] - Weights[3]
618 - Weights[4] - Weights[5] - Weights[6] - Weights[7] - Weights[9];
621 std::cout<<
"Invalid spline degree\n"<<std::endl;
655 template <
class RandomAccessIterator>
658 RandomAccessIterator coef_last,
660 std::size_t SplineDegree)
664 long coef_size =
static_cast<long>(coef_last-coef_first);
665 long Width2 = 2L * coef_size - 2L;
681 long splinedegree =
static_cast<long>(SplineDegree);
683 for (
long k = 0L; k <= splinedegree; ++k)
685 Index[k] = (coef_size == 1L) ? (0L) : ((Index[k] < 0L) ?
686 (-Index[k] - Width2 * ((-Index[k]) / Width2))
687 : (Index[k] - Width2 * (Index[k] / Width2)));
688 if (coef_size <= Index[k])
690 Index[k] = Width2 - Index[k];
695 double interpolated = 0.0;
698 for (
long j = 0L; j <= splinedegree; ++j)
700 interpolated += Weights[j] * coef_first[Index[j]];
735 template <
typename RandomAccessIterator2d1,
736 typename RandomAccessIterator2d2>
739 RandomAccessIterator2d1 in_bot,
740 const std::size_t degree,
741 RandomAccessIterator2d2 out_up,
742 RandomAccessIterator2d2 out_bot,
743 const double tolerance =
746 assert((in_bot-in_up)[0] == (out_bot-out_up)[0]);
747 assert((in_bot-in_up)[1] == (out_bot-out_up)[1]);
749 std::size_t rows =
static_cast<std::size_t
>((in_bot-in_up)[0]);
750 std::size_t cols =
static_cast<std::size_t
>((in_bot-in_up)[1]);
753 slipalgo::BSplinePoles< slip::Array<double> >(degree,poles);
757 for (std::size_t y = 0; y < rows; ++y)
768 for (std::size_t x = 0; x < cols; ++x)
796 template <
class Matrix1,
800 const Matrix1 &input,
805 input.bottom_right(),
808 output.bottom_right());
844 template <
typename RandomAccessIterator3d1,
845 typename RandomAccessIterator3d2>
848 RandomAccessIterator3d1 in_bbot,
849 const std::size_t degree,
850 RandomAccessIterator3d2 out_fup,
851 RandomAccessIterator3d2 out_bbot,
852 const double tolerance =
855 assert((in_bbot-in_fup) == (out_bbot-out_fup));
856 std::size_t slices =
static_cast<std::size_t
>((in_bbot-in_fup)[0]);
857 std::size_t rows =
static_cast<std::size_t
>((in_bbot-in_fup)[1]);
858 std::size_t cols =
static_cast<std::size_t
>((in_bbot-in_fup)[2]);
861 slipalgo::BSplinePoles< slip::Array<double> >(degree,poles);
866 for (std::size_t x = 0; x < cols; ++x)
868 for (std::size_t y = 0; y < rows; ++y)
876 for (std::size_t z = 0; z < slices; ++z)
878 for (std::size_t x = 0; x < cols; ++x)
887 for (std::size_t z = 0; z < slices; ++z)
889 for (std::size_t y = 0; y < rows; ++y)
911 template <
typename RandomAccessIterator2d>
914 RandomAccessIterator2d Bcoeff_bot,
917 std::size_t SplineDegree)
920 long rows =
static_cast<long>((Bcoeff_bot - Bcoeff_up)[0]);
921 long cols =
static_cast<long>((Bcoeff_bot - Bcoeff_up)[1]);
923 long Width2 = 2L * cols - 2L;
924 long Height2 = 2L * rows - 2L;
925 long splinedegree =
static_cast<long>(SplineDegree);
955 for (
long k = 0L; k <= splinedegree; k++)
957 xIndex[k] = (cols == 1L) ? (0L) : ((xIndex[k] < 0L) ?
958 (-xIndex[k] - Width2 * ((-xIndex[k]) / Width2))
959 : (xIndex[k] - Width2 * (xIndex[k] / Width2)));
960 if (cols <= xIndex[k])
962 xIndex[k] = Width2 - xIndex[k];
964 yIndex[k] = (rows == 1L) ? (0L) : ((yIndex[k] < 0L) ?
965 (-yIndex[k] - Height2 * ((-yIndex[k]) / Height2))
966 : (yIndex[k] - Height2 * (yIndex[k] / Height2)));
967 if (rows <= yIndex[k])
969 yIndex[k] = Height2 - yIndex[k];
975 double interpolated = 0.0;
977 for (
long j = 0L; j <= splinedegree; j++)
981 for (
long i = 0L; i <= splinedegree; i++)
984 w += xWeights[i] * Bcoeff_up[d];
986 interpolated += yWeights[j] * w;
989 return(interpolated);
1041 template <
class Matrix1>
1046 std::size_t SplineDegree)
1051 long Width2 = 2L * Bcoeff.cols() - 2L, Height2 = 2L * Bcoeff.rows() - 2L;
1052 long splinedegree =
static_cast<long>(SplineDegree);
1082 for (
long k = 0L; k <= splinedegree; k++)
1085 xIndex[k] = (Bcoeff.cols() == 1L) ? (0L) : ((xIndex[k] < 0L) ?
1086 (-xIndex[k] - Width2 * ((-xIndex[k]) / Width2))
1087 : (xIndex[k] - Width2 * (xIndex[k] / Width2)));
1088 if (((
long) Bcoeff.cols()) <= xIndex[k])
1090 xIndex[k] = Width2 - xIndex[k];
1092 yIndex[k] = (Bcoeff.rows() == 1L) ? (0L) : ((yIndex[k] < 0L) ?
1093 (-yIndex[k] - Height2 * ((-yIndex[k]) / Height2))
1094 : (yIndex[k] - Height2 * (yIndex[k] / Height2)));
1095 if (((
long) Bcoeff.rows()) <= yIndex[k])
1097 yIndex[k] = Height2 - yIndex[k];
1103 double interpolated = 0.0;
1104 for (
long j = 0L; j <= splinedegree; j++)
1107 for (
long i = 0L; i <= splinedegree; i++)
1109 w += xWeights[i] * Bcoeff[yIndex[j]][xIndex[i]];
1111 interpolated += yWeights[j] * w;
1114 return(interpolated);
1179 template <
class Container3d>
1185 std::size_t SplineDegree)
1189 long Width2 = 2L * Bcoeff.cols() - 2L;
1190 long Height2 = 2L * Bcoeff.rows() - 2L;
1191 long Depth2 = 2L * Bcoeff.slices() - 2L;
1193 long splinedegree =
static_cast<long>(SplineDegree);
1236 for (
long k = 0L; k <= splinedegree; k++)
1239 xIndex[k] = (Bcoeff.cols() == 1L) ? (0L) : ((xIndex[k] < 0L) ?
1240 (-xIndex[k] - Width2 * ((-xIndex[k]) / Width2))
1241 : (xIndex[k] - Width2 * (xIndex[k] / Width2)));
1242 if (((
long) Bcoeff.cols()) <= xIndex[k])
1244 xIndex[k] = Width2 - xIndex[k];
1246 yIndex[k] = (Bcoeff.rows() == 1L) ? (0L) : ((yIndex[k] < 0L) ?
1247 (-yIndex[k] - Height2 * ((-yIndex[k]) / Height2))
1248 : (yIndex[k] - Height2 * (yIndex[k] / Height2)));
1249 if (((
long) Bcoeff.rows()) <= yIndex[k])
1251 yIndex[k] = Height2 - yIndex[k];
1253 zIndex[k] = (Bcoeff.slices() == 1L) ? (0L) : ((zIndex[k] < 0L) ?
1254 (-zIndex[k] - Depth2 * ((-zIndex[k]) / Depth2))
1255 : (zIndex[k] - Depth2 * (zIndex[k] / Depth2)));
1256 if (((
long) Bcoeff.slices()) <= zIndex[k])
1258 zIndex[k] = Depth2 - zIndex[k];
1264 double interpolated = 0.0;
1265 for (
long j = 0L; j <= splinedegree; ++j)
1268 for (
long i = 0L; i <= splinedegree; ++i)
1271 for (
long k = 0L; k <= splinedegree; ++k)
1273 w2 += zWeights[k] * Bcoeff[zIndex[k]][yIndex[j]][xIndex[i]];
1275 w += xWeights[i] * w2;
1277 interpolated += yWeights[j] * w;
1280 return(interpolated);
1296 template <
typename RandomAccessIterator3d>
1299 RandomAccessIterator3d Bcoeff_bbot,
1303 std::size_t SplineDegree)
1306 long slices =
static_cast<long>((Bcoeff_bbot - Bcoeff_fup)[0]);
1307 long rows =
static_cast<long>((Bcoeff_bbot - Bcoeff_fup)[1]);
1308 long cols =
static_cast<long>((Bcoeff_bbot - Bcoeff_fup)[2]);
1311 long Width2 = 2L * cols - 2L;
1312 long Height2 = 2L * rows - 2L;
1313 long Depth2 = 2L * slices - 2L;
1315 long splinedegree =
static_cast<long>(SplineDegree);
1358 for (
long k = 0L; k <= splinedegree; k++)
1361 xIndex[k] = (cols == 1L) ? (0L) : ((xIndex[k] < 0L) ?
1362 (-xIndex[k] - Width2 * ((-xIndex[k]) / Width2))
1363 : (xIndex[k] - Width2 * (xIndex[k] / Width2)));
1364 if (cols <= xIndex[k])
1366 xIndex[k] = Width2 - xIndex[k];
1368 yIndex[k] = (rows == 1L) ? (0L) : ((yIndex[k] < 0L) ?
1369 (-yIndex[k] - Height2 * ((-yIndex[k]) / Height2))
1370 : (yIndex[k] - Height2 * (yIndex[k] / Height2)));
1371 if (rows <= yIndex[k])
1373 yIndex[k] = Height2 - yIndex[k];
1375 zIndex[k] = (slices == 1L) ? (0L) : ((zIndex[k] < 0L) ?
1376 (-zIndex[k] - Depth2 * ((-zIndex[k]) / Depth2))
1377 : (zIndex[k] - Depth2 * (zIndex[k] / Depth2)));
1378 if (slices <= zIndex[k])
1380 zIndex[k] = Depth2 - zIndex[k];
1386 double interpolated = 0.0;
1388 for (
long j = 0L; j <= splinedegree; ++j)
1392 for (
long i = 0L; i <= splinedegree; ++i)
1396 for (
long k = 0L; k <= splinedegree; ++k)
1399 w2 += zWeights[k] * Bcoeff_fup[d];
1401 w += xWeights[i] * w2;
1403 interpolated += yWeights[j] * w;
1406 return(interpolated);
1434 template <
typename RandomAccessIterator1,
1435 typename RandomAccessIterator2>
1437 RandomAccessIterator1 in_last,
1438 const std::size_t spline_degree,
1439 RandomAccessIterator2 out_first,
1440 RandomAccessIterator2 out_last)
1442 assert(static_cast<std::size_t>(out_last-out_first) >= static_cast<std::size_t>(in_last-in_first));
1443 std::size_t in_size =
static_cast<std::size_t
>(in_last-in_first);
1444 std::size_t out_size =
static_cast<std::size_t
>(out_last-out_first);
1459 for(; out_first != out_last; ++out_first,++it_x)
1463 *it_x,spline_degree);
1496 template <
typename RandomAccessIterator2d1,
1497 typename RandomAccessIterator2d2>
1499 RandomAccessIterator2d1 in_bot,
1500 const std::size_t spline_degree,
1501 RandomAccessIterator2d2 out_up,
1502 RandomAccessIterator2d2 out_bot)
1504 assert((in_bot-in_up)[0] <= (out_bot-out_up)[0]);
1505 assert((in_bot-in_up)[1] <= (out_bot-out_up)[1]);
1507 std::size_t in_rows =
static_cast<std::size_t
>((in_bot-in_up)[0]);
1508 std::size_t in_cols =
static_cast<std::size_t
>((in_bot-in_up)[1]);
1510 std::size_t out_rows =
static_cast<std::size_t
>((out_bot-out_up)[0]);
1511 std::size_t out_cols =
static_cast<std::size_t
>((out_bot-out_up)[1]);
1533 for(std::size_t i = 0; i < out_rows; ++i)
1536 for(std::size_t j = 0; j < out_cols; ++j)
1586 template <
typename RandomAccessIterator3d1,
1587 typename RandomAccessIterator3d2>
1589 RandomAccessIterator3d1 in_bbot,
1590 const std::size_t spline_degree,
1591 RandomAccessIterator3d2 out_fup,
1592 RandomAccessIterator3d2 out_bbot)
1595 std::size_t in_slices =
static_cast<std::size_t
>((in_bbot-in_fup)[0]);
1596 std::size_t in_rows =
static_cast<std::size_t
>((in_bbot-in_fup)[1]);
1597 std::size_t in_cols =
static_cast<std::size_t
>((in_bbot-in_fup)[2]);
1599 std::size_t out_slices =
static_cast<std::size_t
>((out_bbot-out_fup)[0]);
1600 std::size_t out_rows =
static_cast<std::size_t
>((out_bbot-out_fup)[1]);
1601 std::size_t out_cols =
static_cast<std::size_t
>((out_bbot-out_fup)[2]);
1627 for(std::size_t k = 0; k < out_slices; ++k)
1630 for(std::size_t i = 0; i < out_rows; ++i)
1633 for(std::size_t j = 0; j < out_cols; ++j)
1675 template <
class GrayScaleImage>
1678 GrayScaleImage& OutputImage,
1679 const int SplineDegree=3,
1680 const double OriginX=0.0,
1681 const double OriginY=0.0,
1682 const double Angle=0.0,
1683 const double ShiftX=0.0,
1684 const double ShiftY=0.0,
1685 const bool Masking=
true)
1688 std::size_t Width = OutputImage.rows();
1689 std::size_t Height = OutputImage.cols();
1690 double width =
static_cast<double>(Width) - 0.5;
1691 double height =
static_cast<double>(Height) - 0.5;
1697 InputImage.bottom_right(),
1707 double x0 = a11 * (ShiftX + OriginX) + a12 * (ShiftY + OriginY);
1708 double y0 = a21 * (ShiftX + OriginX) + a22 * (ShiftY + OriginY);
1709 double shiftX = OriginX - x0;
1710 double shiftY = OriginY - y0;
1715 for (std::size_t y = 0; y < Height; ++y)
1717 x0 = a12 * (double)y + shiftX;
1718 y0 = a22 * (double)y + shiftY;
1719 for (std::size_t x = 0; x < Width; ++x)
1721 double x1 = x0 + a11 *
static_cast<double>(x);
1722 double y1 = y0 + a21 *
static_cast<double>(x);
1726 if ( (x1 <= -0.5) || (width <= x1)
1727 || (y1 <= -0.5) || (height <= y1))
1729 OutputImage[y][x] = 0.0F;
1755 #endif //SLIP_BSPLINE_INTERPOLATION_HPP
Provides a class to manipulate 2d dynamic and generic arrays.
void bspline_resampling_3d(RandomAccessIterator3d1 in_fup, RandomAccessIterator3d1 in_bbot, const std::size_t spline_degree, RandomAccessIterator3d2 out_fup, RandomAccessIterator3d2 out_bbot)
Resample a 3d range using bspline interpolation.
iterator2d upper_left()
Returns a read/write iterator2d that points to the first element of the Array2d. It points to the upp...
Provides a class to modelize the difference of slip::Point2d.
double BSplineInitialCausalCoefficient(InputIterator infirst, InputIterator inlast, double z, double Tolerance)
BSpline computation of causal coefficients based on http://bigwww.epfl.ch/thevenaz/interpolation/.
iterator3d front_upper_left()
Returns a read/write iterator3d that points to the first element of the Array3d. It points to the fro...
Difference of Point3D class, specialization of DPoint<CoordType,DIM> with DIM = 3.
double BSplineInterpolatedValue(RandomAccessIterator coef_first, RandomAccessIterator coef_last, double x, std::size_t SplineDegree)
BSpline interpolation from the interpolation coefficients. based on http://bigwww.epfl.ch/thevenaz/interpolation/.
void change_dynamic(InputIterator first, InputIterator last, OutputIterator result, UnaryOperation dynamic_fun)
Changes the dynamic of a container.
double BSplineInitialAntiCausalCoefficient(InputIterator outlast, const double z)
BSpline computation of anticausal coefficients based on http://bigwww.epfl.ch/thevenaz/interpolation/...
This is a three-dimensional dynamic and generic container. This container statisfies the Bidirectionn...
slip::lin_alg_traits< T >::value_type epsilon()
Returns the epsilon value of a real or a complex.
iterator begin()
Returns a read/write iterator that points to the first element in the Array. Iteration is done in ord...
iterator2d bottom_right()
Returns a read/write iterator2d that points to the past the end element of the Array2d. It points to past the end element of the bottom right element of the Array2d.
void BSplineComputeInterpolationCoefficients(InputIterator infirst, InputIterator inlast, OutputIterator outfirst, InputIterator2 Poles_first, InputIterator2 Poles_last, double Tolerance=std::numeric_limits< double >::epsilon())
BSpline computation of coefficients based on http://bigwww.epfl.ch/thevenaz/interpolation/.
Provides a class to modelize the difference of slip::Point3d.
void bspline_resampling_1d(RandomAccessIterator1 in_first, RandomAccessIterator1 in_last, const std::size_t spline_degree, RandomAccessIterator2 out_first, RandomAccessIterator2 out_last)
Resample a range using bspline interpolation.
void iota(ForwardIterator first, ForwardIterator last, T value, T step=T(1))
Iota assigns sequential increasing values based on a predefined step to a range. That is...
static _Tp pi()
Constant .
HyperVolume< T > sin(const HyperVolume< T > &M)
Provides a class to manipulate 1d dynamic and generic arrays.
HyperVolume< T > cos(const HyperVolume< T > &M)
void bspline_resampling_2d(RandomAccessIterator2d1 in_up, RandomAccessIterator2d1 in_bot, const std::size_t spline_degree, RandomAccessIterator2d2 out_up, RandomAccessIterator2d2 out_bot)
Resample a 2d range using bspline interpolation.
void BSplineSamplesToCoefficients2d(RandomAccessIterator2d1 in_up, RandomAccessIterator2d1 in_bot, const std::size_t degree, RandomAccessIterator2d2 out_up, RandomAccessIterator2d2 out_bot, const double tolerance=std::numeric_limits< double >::epsilon())
Convert a 2d samples range to a 2d bspline coefficients range.
iterator end()
Returns a read/write iterator that points one past the last element in the Array. Iteration is done i...
void copy(_II first, _II last, _OI output_first)
Copy algorithm optimized for slip iterators.
Difference of Point2D class, specialization of DPoint<CoordType,DIM> with DIM = 2.
Provides some mathematical functors and constants.
HyperVolume< T > sqrt(const HyperVolume< T > &M)
void BSplineComputeInterpolationWeights(const std::size_t spline_degree, double x, RandomAccessIterator index_first, RandomAccessIterator index_last, Array &Weights)
Computes the bspline interpolations weights. based on http://bigwww.epfl.ch/thevenaz/interpolation/.
void BSplineGeometricTransformation(const GrayScaleImage &InputImage, GrayScaleImage &OutputImage, const int SplineDegree=3, const double OriginX=0.0, const double OriginY=0.0, const double Angle=0.0, const double ShiftX=0.0, const double ShiftY=0.0, const bool Masking=true)
BSpline computation of a geometric transformation. based on http://bigwww.epfl.ch/thevenaz/interpolat...
Provides some algorithms to computes arithmetical operations on ranges.
Functor object uses to change the range of container according to an affine transformation.
iterator3d back_bottom_right()
Returns a read/write iterator3d that points to the past the end element of the Array3d. It points to past the end element of the back bottom right element of the Array3d.
HyperVolume< T > log(const HyperVolume< T > &M)
Provides algorithms and functors to change the dynamic of ranges.
Provides a class to manipulate 3d dynamic and generic arrays.
void BSplineSamplesToCoefficients3d(RandomAccessIterator3d1 in_fup, RandomAccessIterator3d1 in_bbot, const std::size_t degree, RandomAccessIterator3d2 out_fup, RandomAccessIterator3d2 out_bbot, const double tolerance=std::numeric_limits< double >::epsilon())
Convert a 3d samples range to a 3d bspline coefficients range.
void BSplineComputeInterpolationIndexes(const std::size_t spline_degree, double x, RandomAccessIterator index_first, RandomAccessIterator index_last)
Computes the bspline interpolations indices. based on http://bigwww.epfl.ch/thevenaz/interpolation/.
This is a linear (one-dimensional) dynamic template container. This container statisfies the RandomAc...
void BSplinePoles(const std::size_t degree, Array &Poles)
BSpline Poles computations based on http://bigwww.epfl.ch/thevenaz/interpolation/.
void BSplineSamplesToCoefficients(const std::size_t degree, const Matrix1 &input, Matrix2 &output)
BSpline computation of coefficients for 2D container based on http://bigwww.epfl.ch/thevenaz/interpol...
This is a two-dimensional dynamic and generic container. This container statisfies the Bidirectionnal...