1 // Some tests for vgl_spline_*d
2 // J.L. Mundy August, 2015
3 #include <iostream>
4 #include <fstream>
5 #include <cmath>
6 #include "testlib/testlib_test.h"
7 #include "vgl/vgl_cubic_spline_3d.h"
8 #include "vgl/vgl_cubic_spline_2d.h"
9 #include "vgl/vgl_point_3d.h"
10 #include "vgl/vgl_point_2d.h"
11 #ifdef _MSC_VER
12 #  include "vcl_msvc_warnings.h"
13 #endif
14 #include "vpl/vpl.h"
15 
16 static void
test_spline()17 test_spline()
18 {
19   vgl_point_3d<double> pm1(1.0, 0.0, 0.0);
20   vgl_point_3d<double> p0(1.0, 3.0, 2.0);
21   vgl_point_3d<double> p1(2.0, 2.0, 4.0);
22   vgl_point_3d<double> p2(2.0, 0.0, 2.0);
23   std::vector<vgl_point_3d<double>> knots;
24   knots.push_back(pm1);
25   knots.push_back(p0);
26   knots.push_back(p1);
27   knots.push_back(p2);
28   vgl_cubic_spline_3d<double> spl(knots);
29   for (double t = 1.0; t < 2.1; t += 0.1)
30   {
31     vgl_point_3d<double> p = spl(t);
32     std::cout << t << ' ' << p.x() << ' ' << p.y() << ' ' << p.z() << '\n';
33   }
34   double vxs = (spl(1.5)).x(), vx = 1.5, ex = std::fabs(vxs - vx);
35   double vys = (spl(1.5)).y(), vy = 2.8125, ey = std::fabs(vys - vy);
36   double vzs = (spl(1.5)).z(), vz = 3.25, ez = std::fabs(vzs - vz);
37   double error = ex + ey + ez;
38   TEST_NEAR("Spline interpolation (open)", error, 0.0, 1e-05);
39 
40   std::vector<vgl_point_3d<double>> knots2;
41   knots2.push_back(pm1);
42   knots2.push_back(p0);
43   knots2.push_back(p1);
44   vgl_cubic_spline_3d<double> spl2(knots2, 0.5, true);
45   for (double t = 1.0; t < 2; t += 0.1)
46   {
47     vgl_point_3d<double> p = spl2(t);
48     std::cout << t << ' ' << p.x() << ' ' << p.y() << ' ' << p.z() << '\n';
49   }
50   double vxsc = (spl2(1.5)).x(), vxc = 1.5625, exc = std::fabs(vxsc - vxc);
51   double vysc = (spl2(1.5)).y(), vyc = 2.8125, eyc = std::fabs(vysc - vyc);
52   double vzsc = (spl2(1.5)).z(), vzc = 3.375, ezc = std::fabs(vzsc - vzc);
53   double errorc = exc + eyc + ezc;
54   TEST_NEAR("Spline interpolation (closed)", errorc, 0.0, 1e-05);
55   // test I/O
56   std::string path = "./testio.txt";
57   std::ofstream ostr(path.c_str());
58   ostr << spl;
59   ostr.close();
60   std::ifstream istr(path.c_str());
61   vgl_cubic_spline_3d<double> io_spl;
62   istr >> io_spl;
63   bool good = io_spl == spl;
64   TEST("Spline 3d I/O", good, true);
65   vpl_unlink(path.c_str());
66 
67   // test tangent
68   vgl_vector_3d<double> tan = spl.tangent(1.5);
69   std::cout << tan << '\n';
70   double dx = 0.401288, dy = -0.441404, dz = 0.802577;
71   double etx = std::fabs(dx - tan.x()), ety = std::fabs(dy - tan.y()), etz = std::fabs(dz - tan.z());
72   double etan = etx + ety + etz;
73   TEST_NEAR("spline tangent", etan, 0.0, 0.001);
74 
75   // 2-d spline tests
76   vgl_point_2d<double> pm12(1.0, 0.0);
77   vgl_point_2d<double> p02(1.0, 3.0);
78   vgl_point_2d<double> p12(2.0, 2.0);
79   vgl_point_2d<double> p22(2.0, 0.0);
80   std::vector<vgl_point_2d<double>> knots2d;
81   knots2d.push_back(pm12);
82   knots2d.push_back(p02);
83   knots2d.push_back(p12);
84   knots2d.push_back(p22);
85   vgl_cubic_spline_2d<double> spl2d(knots2d);
86   double vxs2d = (spl2d(1.5)).x(), vx2d = 1.5, ex2d = std::fabs(vxs2d - vx2d);
87   double vys2d = (spl2d(1.5)).y(), vy2d = 2.8125, ey2d = std::fabs(vys2d - vy2d);
88 
89   double error2d = ex2d + ey2d;
90   TEST_NEAR("2d spline interpolation  (open)", error2d, 0.0, 1e-05);
91   // test 2d I/O
92   std::string path2d = "./testio.txt";
93   std::ofstream ostr2d(path2d.c_str());
94   ostr2d << spl2d;
95   ostr2d.close();
96   std::ifstream istr2d(path2d.c_str());
97   vgl_cubic_spline_2d<double> io_spl2d;
98   istr2d >> io_spl2d;
99   good = io_spl2d == spl2d;
100   TEST("Spline 2d I/O", good, true);
101   vpl_unlink(path2d.c_str());
102   // test tangent
103   vgl_vector_2d<double> tan2d = spl2d.tangent(1.5);
104   std::cout << tan2d << '\n';
105   dx = 0.672684;
106   dy = -0.73993;
107   double etx2d = std::fabs(dx - tan2d.x()), ety2d = std::fabs(dy - tan2d.y());
108   double etan2d = etx2d + ety2d;
109   TEST_NEAR("spline tangent", etan2d, 0.0, 0.001);
110 }
111 
112 TESTMAIN(test_spline);
113