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