1 // Some tests for vgl_plane_3d
2 // J.L. Mundy Sept. 17, 2010
3 
4 #include <iostream>
5 #include <sstream>
6 #include <cmath>
7 #include "testlib/testlib_test.h"
8 #include "vgl/vgl_plane_3d.h"
9 #include "vgl/vgl_point_3d.h"
10 #include "vgl/vgl_point_2d.h"
11 #include "vgl/vgl_vector_3d.h"
12 #include "vgl/vgl_ray_3d.h"
13 #include "vgl/vgl_closest_point.h"
14 #ifdef _MSC_VER
15 #  include "vcl_msvc_warnings.h"
16 #endif
17 static void
test_constructor()18 test_constructor()
19 {
20   double a = 0.0, b = 10.0, c = 0.0, d = 0.0;
21   vgl_plane_3d<double> plane_abcd(a, b, c, d);
22   vgl_vector_3d<double> n(0.0, 1.0, 0.0);
23   vgl_point_3d<double> p0(0.0, 0.0, 0.0);
24   vgl_plane_3d<double> plane_ptn(n, p0);
25   vgl_vector_3d<double> nabcd = plane_abcd.normal(), nptn = plane_ptn.normal();
26   double dist = std::fabs(1.0 - dot_product(nabcd, nptn));
27   TEST_NEAR("Constructors and Normal", dist, 0.0, 1e-5);
28   // case I coincident
29   vgl_vector_3d<double> dir0(-1.0, 0.0, 0.0), dir1(0.0, 0.0, 1.0);
30   vgl_ray_3d<double> r0(p0, dir0), r1(p0, dir1);
31   vgl_plane_3d<double> plane_coin_rays(r0, r1);
32   vgl_vector_3d<double> ncoin = plane_coin_rays.normal();
33   dist = std::fabs(1.0 - dot_product(ncoin, nptn));
34   TEST_NEAR("Coincident ray constructor", dist, 0.0, 1e-5);
35   vgl_point_3d<double> p0p(-1.0, 0.0, 0.0);
36   vgl_ray_3d<double> r0p(p0p, dir1);
37   vgl_plane_3d<double> plane_para_rays(r0p, r1);
38   vgl_vector_3d<double> npara = plane_para_rays.normal();
39   dist = std::fabs(1.0 - dot_product(npara, nptn));
40   TEST_NEAR("Parallel ray constructor", dist, 0.0, 1e-5);
41 }
42 
43 static void
test_operations()44 test_operations()
45 {
46   // a plane rotated 45 degrees around the Y axis, i.e. normal is
47   // perpendicular to Y
48   double a = 1.0, b = 0.0, c = 1.0, d = 0.0;
49   vgl_plane_3d<double> plane(a, b, c, d);
50   vgl_point_3d<double> p3d(1.0, 1.0, -1.0);
51   vgl_point_2d<double> p2d, p2dy, p2dys;
52   bool good = plane.plane_coords(p3d, p2d, 1e-5);
53   double er = std::fabs(p2d.x() - std::sqrt(2.0));
54 
55   // a plane with the Y axis as its normal
56   a = 0.0, b = 1.0, c = 0.0;
57   vgl_plane_3d<double> plane1(a, b, c, d);
58   vgl_point_3d<double> p3dy(1.0, 0.0, 1.0);
59   good = good && plane1.plane_coords(p3dy, p2dy, 1e-5);
60   er += std::fabs(p2dy.x() - 1.0) + std::fabs(p2dy.y() - 1.0);
61   // shift the plane along the y axis
62   d = -10.0;
63   vgl_plane_3d<double> plane1s(a, b, c, d);
64   vgl_point_3d<double> p3dys(1.0, 10.0, 1.0);
65   good = good && plane1s.plane_coords(p3dys, p2dys, 1e-5);
66   er += std::fabs(p2dys.x() - 1.0) + std::fabs(p2dys.y() - 1.0);
67   good = good && (er < 1e-5);
68   TEST("Plane Coordinate System: world -> plane", good, true);
69 
70   vgl_point_3d<double> p3d1, p3d2, p3d3;
71   p3d1 = plane.world_coords(p2d);
72   p3d2 = plane1.world_coords(p2dy);
73   p3d3 = plane1s.world_coords(p2dys);
74   er = (p3d1 - p3d).length();
75   er += (p3d2 - p3dy).length();
76   er += (p3d3 - p3dys).length();
77   TEST_NEAR("Plane Coordinate System: plane -> world", er, 0.0, 1e-5);
78 
79   // test with a realistic plane
80   vgl_point_3d<double> pt3d(-51.26, -7045.5, -50.0);
81   vgl_plane_3d<double> plane_real(-.162, 0.987, 0.0, 6943.55);
82   vgl_point_3d<double> pt3d_on = vgl_closest_point(pt3d, plane_real);
83   vgl_point_2d<double> pt2d;
84   good = plane_real.plane_coords(pt3d_on, pt2d, 1e-5);
85   TEST("Realistic plane test: world -> plane", good, true);
86   vgl_point_3d<double> prec_3d = plane_real.world_coords(pt2d);
87   er = (prec_3d - pt3d_on).length();
88   TEST_NEAR("Realistic plane test", er, 0.0, 1e-5);
89 
90   // test stream operators
91   double as = 0.1, bs = 0.5, cs = 0.86, ds = -1.0;
92   vgl_plane_3d<double> pstr(as, bs, cs, ds);
93   std::stringstream ss;
94   ss << pstr;
95   vgl_plane_3d<double> prec;
96   ss >> prec;
97   TEST("plane stream ops", pstr == prec, true);
98 }
99 
100 void
test_plane_3d()101 test_plane_3d()
102 {
103   std::cout << "**********************\n"
104             << " Testing vgl_plane_3d\n"
105             << "**********************\n\n";
106 
107   test_constructor();
108   test_operations();
109 }
110 
111 
112 TESTMAIN(test_plane_3d);
113