Moby
Plane.h
1 /****************************************************************************
2  * Copyright 2008 Evan Drumwright
3  * This library is distributed under the terms of the Apache V2.0
4  * License (obtainable from http://www.apache.org/licenses/LICENSE-2.0).
5  ****************************************************************************/
6 
7 #ifndef _MOBY_PLANE_H_
8 #define _MOBY_PLANE_H_
9 
10 #include <Moby/Constants.h>
11 #include <Moby/Triangle.h>
12 #include <Ravelin/Vector3d.h>
13 
14 namespace Moby {
15 
17 class Plane
18 {
19  public:
20  Plane() { _normal.set_zero(); offset = 0; }
21  Plane(double nx, double ny, double nz, double d) { _normal = Ravelin::Vector3d(nx, ny, nz); _normal.normalize(); offset = d; }
22  Plane(const Triangle& t) { _normal = t.calc_normal(); offset = t.calc_offset(_normal); }
23  Plane(const Ravelin::Vector3d& n, double d) { _normal = Ravelin::Vector3d::normalize(n); offset = d; }
24  Plane(const Ravelin::Vector3d& normal, const Point3d& point) { _normal = Ravelin::Vector3d::normalize(normal); offset = normal.dot(point); }
25  Plane(const Plane& p) { operator=(p); }
26  void operator=(const Plane& p) { _normal = p._normal; offset = p.offset; }
27  double calc_signed_distance(const Point3d& p) const { return _normal.dot(p) - offset; }
28  bool on_plane(const Point3d& p) { return std::fabs(calc_signed_distance(p)) < NEAR_ZERO * std::max((double) 1.0, std::max(p.norm_inf(), std::fabs(offset))); }
29  bool operator==(const Plane& p) const { double dot = _normal.dot(p.get_normal()); return (std::fabs(dot - 1.0) < NEAR_ZERO && std::fabs(offset - p.offset) < NEAR_ZERO); }
30  bool operator<(const Plane& p) const;
31  boost::shared_ptr<const Ravelin::Pose3d> get_pose() const { return _normal.pose; }
32  Point3d project(const Point3d& p) const;
33  Ravelin::Origin2d to_2D(const Point3d& p) const;
34  Plane transform(const Ravelin::Transform3d& T) const;
35 
37  Plane operator-() const { return Plane(-_normal, -offset); }
38 
40  const Ravelin::Vector3d& get_normal() const { return _normal; }
41 
43  void set_normal(const Ravelin::Vector3d& n) { _normal = Ravelin::Vector3d::normalize(n); }
44 
46  double offset;
47 
48  private:
49  Ravelin::Vector3d _normal;
50 }; // end class
51 
53 inline Plane Plane::transform(const Ravelin::Transform3d& T) const
54 {
55  // setup the new plane
56  Plane p;
57 
58  // get the new normal
59  p._normal = T.transform_vector(_normal);
60 
61  // compute the new offset using a point on the old plane
62  // NOTE: n' * (n*offset) - offset = 0
63  Point3d plane_point = _normal * offset;
64 
65  // transform that point
66  Point3d new_plane_point = T.transform_point(plane_point);
67 
68  // now compute the offset
69  p.offset = p._normal.dot(new_plane_point);
70 
71  return p;
72 }
73 
75 inline Ravelin::Origin2d Plane::to_2D(const Point3d& p) const
76 {
77  const unsigned X = 0, Y = 1, Z = 2;
78 
79  // setup the projection matrix
80  Ravelin::Vector3d v1, v2;
81  Ravelin::Vector3d::determine_orthonormal_basis(_normal, v1, v2);
82  Ravelin::Matrix3d R;
83  R.set_row(X, Ravelin::Origin3d(v1));
84  R.set_row(Y, Ravelin::Origin3d(v2));
85  R.set_row(Z, Ravelin::Origin3d(_normal));
86 
87  // multiply
88  Ravelin::Origin3d result = R * Ravelin::Origin3d(p);
89 
90  return Ravelin::Origin2d(result[X], result[Y]);
91 }
92 
94 inline Point3d Plane::project(const Point3d& p) const
95 {
96  double d = _normal.dot(p);
97  return p - _normal*d;
98 }
99 
100 inline bool Plane::operator<(const Plane& p) const
101 {
102  const unsigned X = 0, Y = 1, Z = 2;
103 
104  if (_normal[X] < p.get_normal()[X])
105  return true;
106  else if (_normal[X] == p.get_normal()[X])
107  {
108  if (_normal[Y] < p.get_normal()[Y])
109  return true;
110  else if (_normal[Y] == p.get_normal()[Y])
111  {
112  if (_normal[Z] < p.get_normal()[Z])
113  return true;
114  else if (_normal[Z] == p.get_normal()[Z])
115  return offset < p.offset;
116  }
117  }
118 
119  return false;
120 }
121 
122 inline std::ostream& operator<<(std::ostream& out, const Plane& p)
123 {
124  out << "normal: " << p.get_normal() << " offset: " << p.offset;
125  return out;
126 }
127 
128 } // end namespace
129 
130 #endif
131 
Plane operator-() const
Assuming this plane represents a half-space, negates the half-space.
Definition: Plane.h:37
Point3d project(const Point3d &p) const
Projects a point onto the plane.
Definition: Plane.h:94
const Ravelin::Vector3d & get_normal() const
Gets the outward pointing normal to the plane.
Definition: Plane.h:40
Defines a plane using the equation <n, x> = d.
Definition: Plane.h:17
Ravelin::Origin2d to_2D(const Point3d &p) const
Transforms a point to 2D.
Definition: Plane.h:75
Plane transform(const Ravelin::Transform3d &T) const
Transforms a plane.
Definition: Plane.h:53
double offset
The plane offset such that the plane equation is given by <n, x> = offset.
Definition: Plane.h:46
Ravelin::Vector3d Point3d
Typedef to distinguish between a 3D vector and a point.
Definition: Types.h:47
void set_normal(const Ravelin::Vector3d &n)
Sets the outward pointing normal to the plane.
Definition: Plane.h:43