HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
plane.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the Apache License, Version 2.0 (the "Apache License")
5 // with the following modification; you may not use this file except in
6 // compliance with the Apache License and the following modification to it:
7 // Section 6. Trademarks. is deleted and replaced with:
8 //
9 // 6. Trademarks. This License does not grant permission to use the trade
10 // names, trademarks, service marks, or product names of the Licensor
11 // and its affiliates, except as required to comply with Section 4(c) of
12 // the License and to reproduce the content of the NOTICE file.
13 //
14 // You may obtain a copy of the Apache License at
15 //
16 // http://www.apache.org/licenses/LICENSE-2.0
17 //
18 // Unless required by applicable law or agreed to in writing, software
19 // distributed under the Apache License with the above modification is
20 // distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21 // KIND, either express or implied. See the Apache License for the specific
22 // language governing permissions and limitations under the Apache License.
23 //
24 #ifndef PXR_BASE_GF_PLANE_H
25 #define PXR_BASE_GF_PLANE_H
26 
27 /// \file gf/plane.h
28 /// \ingroup group_gf_BasicGeometry
29 
30 #include "pxr/pxr.h"
31 #include "pxr/base/gf/vec3d.h"
32 #include "pxr/base/gf/api.h"
33 
34 #include <iosfwd>
35 #include <vector>
36 
38 
39 class GfRange3d;
40 class GfMatrix4d;
41 class GfVec4d;
42 
43 /// \class GfPlane
44 /// \ingroup group_gf_BasicGeometry
45 ///
46 /// Basic type: 3-dimensional plane
47 ///
48 /// This class represents a three-dimensional plane as a normal vector
49 /// and the distance of the plane from the origin, measured along the
50 /// normal. The plane can also be used to represent a half-space: the
51 /// side of the plane in the direction of the normal.
52 ///
53 class GfPlane
54 {
55  public:
56 
57  /// The default constructor leaves the plane parameters undefined.
58  GfPlane() {
59  }
60 
61  /// This constructor sets this to the plane perpendicular to \p normal and
62  /// at \p distance units from the origin. The passed-in normal is
63  /// normalized to unit length first.
64  GfPlane(const GfVec3d &normal, double distanceToOrigin) {
65  Set(normal, distanceToOrigin);
66  }
67 
68  /// This constructor sets this to the plane perpendicular to \p normal and
69  /// that passes through \p point. The passed-in normal is normalized to
70  /// unit length first.
71  GfPlane(const GfVec3d &normal, const GfVec3d &point) {
72  Set(normal, point);
73  }
74 
75  /// This constructor sets this to the plane that contains the three given
76  /// points. The normal is constructed from the cross product of (\p p1 -
77  /// \p p0) (\p p2 - \p p0). Results are undefined if the points are
78  /// collinear.
79  GfPlane(const GfVec3d &p0, const GfVec3d &p1, const GfVec3d &p2) {
80  Set(p0, p1, p2);
81  }
82 
83  /// This constructor creates a plane given by the equation
84  /// \p eqn[0] * x + \p eqn[1] * y + \p eqn[2] * z + \p eqn[3] = 0.
85  GfPlane(const GfVec4d &eqn) {
86  Set(eqn);
87  }
88 
89  /// Sets this to the plane perpendicular to \p normal and at \p distance
90  /// units from the origin. The passed-in normal is normalized to unit
91  /// length first.
92  void Set(const GfVec3d &normal, double distanceToOrigin) {
93  _normal = normal.GetNormalized();
94  _distance = distanceToOrigin;
95  }
96 
97  /// This constructor sets this to the plane perpendicular to \p normal and
98  /// that passes through \p point. The passed-in normal is normalized to
99  /// unit length first.
100  GF_API
101  void Set(const GfVec3d &normal, const GfVec3d &point);
102 
103  /// This constructor sets this to the plane that contains the three given
104  /// points. The normal is constructed from the cross product of (\p p1 -
105  /// \p p0) (\p p2 - \p p0). Results are undefined if the points are
106  /// collinear.
107  GF_API
108  void Set(const GfVec3d &p0,
109  const GfVec3d &p1,
110  const GfVec3d &p2);
111 
112  /// This method sets this to the plane given by the equation
113  /// \p eqn[0] * x + \p eqn[1] * y + \p eqn[2] * z + \p eqn[3] = 0.
114  GF_API
115  void Set(const GfVec4d &eqn);
116 
117  /// Returns the unit-length normal vector of the plane.
118  const GfVec3d & GetNormal() const {
119  return _normal;
120  }
121 
122  /// Returns the distance of the plane from the origin.
123  double GetDistanceFromOrigin() const {
124  return _distance;
125  }
126 
127  /// Give the coefficients of the equation of the plane. Suitable
128  /// to OpenGL calls to set the clipping plane.
129  GF_API
130  GfVec4d GetEquation() const;
131 
132  /// Component-wise equality test. The normals and distances must match
133  /// exactly for planes to be considered equal.
134  bool operator ==(const GfPlane &p) const {
135  return (_normal == p._normal &&
136  _distance == p._distance);
137  }
138 
139  /// Component-wise inequality test. The normals and distances must match
140  /// exactly for planes to be considered equal.
141  bool operator !=(const GfPlane &p) const {
142  return ! (*this == p);
143  }
144 
145  /// Returns the distance of point \p from the plane. This distance will be
146  /// positive if the point is on the side of the plane containing the
147  /// normal.
148  double GetDistance(const GfVec3d &p) const {
149  return p * _normal - _distance;
150  }
151 
152  /// Return the projection of \p p onto the plane.
153  GfVec3d Project(const GfVec3d& p) const {
154  return p - GetDistance(p) * _normal;
155  }
156 
157  /// Transforms the plane by the given matrix.
158  GF_API
159  GfPlane & Transform(const GfMatrix4d &matrix);
160 
161  /// Flip the plane normal (if necessary) so that \p p is in the positive
162  /// halfspace.
163  void Reorient(const GfVec3d& p) {
164  if (GetDistance(p) < 0) {
165  _normal = -_normal;
166  _distance = -_distance;
167  }
168  }
169 
170  /// Returns \c true if the given aligned bounding box is at least
171  /// partially on the positive side (the one the normal points into) of the
172  /// plane.
173  GF_API
174  bool IntersectsPositiveHalfSpace(const GfRange3d &box) const;
175 
176  /// Returns true if the given point is on the plane or within its positive
177  /// half space.
178  bool IntersectsPositiveHalfSpace(const GfVec3d &pt) const {
179  return GetDistance(pt) >= 0.0;
180  }
181 
182  private:
183  /// The normal to the plane. Points in direction of half-space.
184  GfVec3d _normal;
185 
186  /// Distance from the plane to the origin.
187  double _distance;
188 };
189 
190 /// Fits a plane to the given \p points. There must be at least three points in
191 /// order to fit the plane; if the size of \p points is less than three, this
192 /// issues a coding error.
193 ///
194 /// If the \p points are all collinear, then no plane can be determined, and
195 /// this function returns \c false. Otherwise, if the fitting is successful,
196 /// it returns \c true and sets \p *fitPlane to the fitted plane. If \p points
197 /// contains exactly three points, then the resulting plane is the exact plane
198 /// defined by the three points. If \p points contains more than three points,
199 /// then this function determines the best-fitting plane for the given points.
200 /// The orientation of the plane normal is arbitrary with regards to the
201 /// plane's positive and negative half-spaces; you can use GfPlane::Reorient()
202 /// to flip the plane if necessary.
203 ///
204 /// The current implementation uses linear least squares and thus defines
205 /// "best-fitting" as minimizing the sum of the squares of the vertical
206 /// distances between points and the plane surface.
207 GF_API
208 bool GfFitPlaneToPoints(const std::vector<GfVec3d>& points, GfPlane* fitPlane);
209 
210 /// Output a GfPlane using the format [(nx ny nz) distance].
211 /// \ingroup group_gf_DebuggingOutput
212 GF_API std::ostream& operator<<(std::ostream&, const GfPlane&);
213 
215 
216 #endif // PXR_BASE_GF_PLANE_H
GF_API GfPlane & Transform(const GfMatrix4d &matrix)
Transforms the plane by the given matrix.
GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glad.h:2676
GfPlane(const GfVec3d &normal, const GfVec3d &point)
Definition: plane.h:71
bool operator==(const GfPlane &p) const
Definition: plane.h:134
bool IntersectsPositiveHalfSpace(const GfVec3d &pt) const
Definition: plane.h:178
bool operator!=(const GfPlane &p) const
Definition: plane.h:141
void Set(const GfVec3d &normal, double distanceToOrigin)
Definition: plane.h:92
GfPlane(const GfVec3d &p0, const GfVec3d &p1, const GfVec3d &p2)
Definition: plane.h:79
Definition: vec4d.h:62
GF_API bool IntersectsPositiveHalfSpace(const GfRange3d &box) const
Definition: plane.h:53
void Reorient(const GfVec3d &p)
Definition: plane.h:163
const GfVec3d & GetNormal() const
Returns the unit-length normal vector of the plane.
Definition: plane.h:118
GF_API bool GfFitPlaneToPoints(const std::vector< GfVec3d > &points, GfPlane *fitPlane)
double GetDistance(const GfVec3d &p) const
Definition: plane.h:148
double GetDistanceFromOrigin() const
Returns the distance of the plane from the origin.
Definition: plane.h:123
GfVec3d Project(const GfVec3d &p) const
Return the projection of p onto the plane.
Definition: plane.h:153
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1432
GfPlane()
The default constructor leaves the plane parameters undefined.
Definition: plane.h:58
Definition: vec3d.h:62
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
GfPlane(const GfVec4d &eqn)
Definition: plane.h:85
GF_API std::ostream & operator<<(std::ostream &, const GfPlane &)
GfPlane(const GfVec3d &normal, double distanceToOrigin)
Definition: plane.h:64
GF_API GfVec4d GetEquation() const
#define GF_API
Definition: api.h:40
GfVec3d GetNormalized(double eps=GF_MIN_VECTOR_LENGTH) const
Definition: vec3d.h:277