1 // This is core/vgl/vgl_plane_3d.h
2 #ifndef vgl_plane_3d_h
3 #define vgl_plane_3d_h
4 //:
5 // \file
6 // \brief a plane in 3D nonhomogeneous space
7 // \author Don Hamilton, Peter Tu
8 // \date   Feb 15 2000
9 //
10 // \verbatim
11 //  Modifications
12 //   Peter Vanroose  6 July 2001: Added assertion in constructors
13 //   Peter Vanroose  6 July 2001: Now using vgl_vector_3d for normal direction
14 //   Peter Vanroose  6 July 2001: Implemented constructor from 3 points
15 //   Peter Vanroose  6 July 2001: Added normal(); replaced data_[4] by a_ b_ c_ d_
16 //   Peter Vanroose  6 July 2001: Added operator== and operator!=
17 //   Peter Vanroose 19 Aug. 2004: implementation of both constructors corrected
18 //   Peter Vanroose 21 May  2009: istream operator>> re-implemented
19 // \endverbatim
20 
21 #include <iosfwd>
22 #ifdef _MSC_VER
23 #  include <vcl_msvc_warnings.h>
24 #endif
25 #include <cassert>
26 #include "vgl_fwd.h" // forward declare vgl_homg_plane_3d, vgl_point_3d
27 #include "vgl_vector_3d.h"
28 
29 //: Represents a Euclidean 3D plane
30 //  The equation of the plane is $ a x + b y + c z + d = 0 $
31 template <class T>
32 class vgl_plane_3d
33 {
34   // the data associated with this plane
35   T a_;
36   T b_;
37   T c_;
38   T d_;
39 
40  public:
41 
42   // Constructors/Initializers/Destructor------------------------------------
43 
44   // Default constructor: horizontal XY-plane (equation 1.z = 0)
vgl_plane_3d()45   inline vgl_plane_3d () : a_(0), b_(0), c_(1), d_(0) {}
46 
47 #if 0
48   // Default copy constructor - compiler provides the correct one
49   inline vgl_plane_3d (vgl_plane_3d<T> const& pl)
50     : a_(pl.a()), b_(pl.b()), c_(pl.c()), d_(pl.d()) {}
51   // Default destructor - compiler provides the correct one
52   inline ~vgl_plane_3d () {}
53   // Default assignment operator - compiler provides the correct one
54   inline vgl_plane_3d<T>& operator=(vgl_plane_3d<T> const& pl)
55   { a_ = pl.a(); b_ = pl.b(); c_ = pl.c(); d_ = pl.d(); return *this; }
56 #endif
57 
58   //: Construct a vgl_plane_3d from its equation $ax+by+cz+d=0$
59   //  At least one of a, b or c should be nonzero.
vgl_plane_3d(T ta,T tb,T tc,T td)60   inline vgl_plane_3d (T ta,T tb,T tc,T td)
61     : a_(ta), b_(tb), c_(tc), d_(td) { assert(ta||tb||tc); }
62 
63   //: Construct a vgl_plane_3d from its equation $v[0]x+v[1]y+v[2]z+v[3]=0$
64   //  At least one of v[0], v[1] or v[2] should be nonzero.
vgl_plane_3d(const T v[4])65   inline vgl_plane_3d (const T v[4])
66     : a_(v[0]), b_(v[1]), c_(v[2]), d_(v[3]) { assert(a_||b_||c_); }
67 
68   //: Construct from a homogeneous plane
69   vgl_plane_3d (vgl_homg_plane_3d<T> const& p);
70 
71   //: Construct from Normal and a point
72   //  The plane goes through the point \a p and will be orthogonal to \a normal.
73   vgl_plane_3d (vgl_vector_3d<T> const& normal,
74                 vgl_point_3d<T> const& p);
75 
76   //: Construct from three non-collinear points
77   //  The plane will contain all three points \a p1, \a p2 and \a p3.
78   vgl_plane_3d (vgl_point_3d<T> const& p1,
79                 vgl_point_3d<T> const& p2,
80                 vgl_point_3d<T> const& p3);
81 
82   //: Construct from two non-skew rays. The rays intersect at their origins
83   // or are parallel. The plane will contain the two rays
84   vgl_plane_3d (vgl_ray_3d<T> const& r0, vgl_ray_3d<T> const& r1);
85 
86   // Data Access-------------------------------------------------------------
87 
88   //: Return \a x coefficient
a()89   inline T a()  const {return a_;}
nx()90   inline T nx() const {return a_;}
91   //: Return \a y coefficient
b()92   inline T b()  const {return b_;}
ny()93   inline T ny() const {return b_;}
94   //: Return \a z coefficient
c()95   inline T c()  const {return c_;}
nz()96   inline T nz() const {return c_;}
97   //: Return constant coefficient
d()98   inline T d()  const {return d_;}
99 
100   //: Set this vgl_plane_3d to have the equation $ax+by+cz+d=0$
set(T ta,T tb,T tc,T td)101   inline void set(T ta,T tb,T tc,T td) { assert(ta||tb||tc); a_=ta; b_=tb; c_=tc; d_=td; }
102 
103   //: the comparison operator
104   //  The equations need not be identical, but just equivalent.
105   bool operator==( vgl_plane_3d<T> const& p) const;
106   inline bool operator!=( vgl_plane_3d<T>const& p) const { return !operator==(p); }
107 
108   //: Return true iff the plane is the plane at infinity.
109   //  Always returns false
110   inline bool ideal(T = (T)0) const { return false; }
111 
112   // divide all plane coefs by sqrt(a^2 +b^2 +c^2)
113   bool normalize();
114 
115   //: Return the normal direction, i.e., a unit vector orthogonal to this plane
normal()116   inline vgl_vector_3d<T> normal() const
117   { return normalized(vgl_vector_3d<T>(a(),b(),c())); }
118 
119   //: Return true if p is on the plane
120   bool contains(vgl_point_3d<T> const& p, T tol = (T)0) const;
121 
122   // the coordinate system on the plane, (u, v), is defined as,
123   // cases:
124   // 1) n not parallel to Y
125   //   u = Y x n and v = n x u
126   //
127   // 2) n parallel to Y
128   //   u = n x Z and v = u x n
129   //
130   // the plane origin is the point in the plane closest to the world origin
131 
132   //: Given a 3-d point, return a 2-d point in the coord. system of the plane
133   // If the point is not on the plane then false is returned
134   bool plane_coords(vgl_point_3d<T> const& p3d,
135                     vgl_point_2d<T>& p2d, T tol=(T)0 ) const;
136 
137   //: inverse map from plane coordinates to world coordinates
138   vgl_point_3d<T> world_coords(vgl_point_2d<T> const& p2d) const;
139 
140   //: plane coordinate unit vectors
141   void plane_coord_vectors(vgl_vector_3d<T>& uvec,
142                            vgl_vector_3d<T>& vvec) const;
143 };
144 
145 //: Return true iff p is the plane at infinity
146 //  Always returns false
147 template <class T>
148 inline bool is_ideal(vgl_plane_3d<T> const &, T /*tol*/ = (T)0) {
149   return false;
150 }
151 
152 //: Write to stream
153 // \relatesalso vgl_plane_3d
154 template <class T>
155 std::ostream& operator<<(std::ostream& s, const vgl_plane_3d<T>& p);
156 
157 //: Read in four plane parameters from stream
158 //  Either just reads four blank-separated numbers,
159 //  or reads four comma-separated numbers,
160 //  or reads four numbers in parenthesized form "(123, 321, -456, 777)"
161 //  or reads a formatted line equation "123x+321y-456z+777=0"
162 // \relatesalso vgl_plane_3d
163 template <class T>
164 std::istream& operator>>(std::istream& is, vgl_plane_3d<T>& p);
165 
166 #define VGL_PLANE_3D_INSTANTIATE(T) extern "please include vgl/vgl_plane_3d.hxx first"
167 
168 #endif // vgl_plane_3d_h
169