fw4spl
PlaneFunctions.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2009-2015.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwMath/PlaneFunctions.hpp"
8 
9 #include <glm/glm.hpp>
10 #include <glm/ext.hpp>
11 
12 
13 #define EPSILON 0.00000001
14 
15 namespace fwMath
16 {
17 
18 //------------------------------------------------------------------------------
19 
20 fwPlane getPlane(const fwVec3d & point1, const fwVec3d & point2, const fwVec3d & point3)
21 {
22  fwPlane plane;
23  setValues(plane, point1, point2, point3);
24 
25  return plane;
26 }
27 
28 //------------------------------------------------------------------------------
29 
30 void setValues(fwPlane& plane, const fwVec3d & point1, const fwVec3d & point2, const fwVec3d & point3)
31 {
32  ::glm::dvec3 p1(point1[0], point1[1], point1[2]);
33  ::glm::dvec3 p2(point2[0], point2[1], point2[2]);
34  ::glm::dvec3 p3(point3[0], point3[1], point3[2]);
35 
36  ::glm::dvec3 normal = ::glm::cross(p2 - p1, p3 - p1);
37  if(::glm::length(normal) <= 0.0)
38  {
39  normal[0] = 0.0;
40  normal[1] = 0.0;
41  normal[2] = 1.0;
42  }
43  normal = ::glm::normalize(normal);
44  double distance = ::glm::dot(normal, p1);
45 
46  plane[0] = normal[0];
47  plane[1] = normal[1];
48  plane[2] = normal[2];
49  plane[3] = distance;
50 }
51 
52 //------------------------------------------------------------------------------
53 
54 fwVec3d getNormal(const fwPlane& plane)
55 {
56  return {{plane[0], plane[1], plane[2]}};
57 }
58 
59 //------------------------------------------------------------------------------
60 
61 void setNormal(fwPlane& plane, const fwVec3d& normal)
62 {
63  ::glm::dvec3 vecNormal(normal[0], normal[1], normal[2]);
64  vecNormal = ::glm::normalize(vecNormal);
65 
66  plane[0] = vecNormal[0];
67  plane[1] = vecNormal[1];
68  plane[2] = vecNormal[2];
69 }
70 
71 //------------------------------------------------------------------------------
72 
73 double getDistance(const fwPlane& plane)
74 {
75  return plane[3];
76 }
77 
78 //------------------------------------------------------------------------------
79 
80 void setDistance(fwPlane& plane, const double distance)
81 {
82  plane[3] = distance;
83 }
84 
85 //------------------------------------------------------------------------------
86 
87 bool intersect( const fwPlane& plane, const fwLine & line, fwVec3d & point)
88 {
89  ::glm::dvec3 normal(plane[0], plane[1], plane[2]);
90  normal = ::glm::normalize(normal);
91  ::glm::dvec3 lineDirection(line.second[0] - line.first[0],
92  line.second[1] - line.first[1],
93  line.second[2] - line.first[2]);
94  lineDirection = ::glm::normalize(lineDirection);
95  ::glm::dvec3 lineOrigin(line.first[0], line.first[1], line.first[2]);
96 
97  double intersectionDistance = 0.;
98  double d = ::glm::dot(lineDirection, normal);
99 
100  if(std::abs(d) < EPSILON)
101  {
102  return false;
103  }
104 
105  intersectionDistance = (plane[3] - ::glm::dot(normal, lineOrigin)) / d;
106 
107  lineOrigin += lineDirection * intersectionDistance;
108  point[0] = lineOrigin[0];
109  point[1] = lineOrigin[1];
110  point[2] = lineOrigin[2];
111 
112  return true;
113 }
114 
115 //------------------------------------------------------------------------------
116 
117 bool isInHalfSpace(const fwPlane& plane, const fwVec3d& point)
118 {
119  ::glm::dvec3 pointGlm(point[0], point[1], point[2]);
120  ::glm::dvec3 normal(plane[0], plane[1], plane[2]);
121  ::glm::normalize(normal);
122  ::glm::dvec3 pos = normal * plane[3];
123  return (::glm::dot(normal, pointGlm-pos) >= 0.0);
124 }
125 
126 //------------------------------------------------------------------------------
127 
128 void transform(fwPlane& plane, const fwMatrix4x4& matrix)
129 {
130  ::glm::dvec3 normal(plane[0], plane[1], plane[2]);
131  ::glm::dvec3 beg(normal * plane[3]);
132  ::glm::dvec3 end(beg + normal);
133  ::glm::dvec4 beg4(beg, 1.0);
134  ::glm::dvec4 end4(end, 1.0);
135  ::glm::dmat4x4 mat(matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0],
136  matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1],
137  matrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2],
138  matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]);
139 
140  beg4 = mat * beg4;
141  end4 = mat * end4;
142 
143  end[0] = end4[0];
144  end[1] = end4[1];
145  end[2] = end4[2];
146 
147  beg[0] = beg4[0];
148  beg[1] = beg4[1];
149  beg[2] = beg4[2];
150 
151  normal = end - beg;
152  normal = ::glm::normalize(normal);
153 
154  plane[0] = normal[0];
155  plane[1] = normal[1];
156  plane[2] = normal[2];
157  plane[3] = ::glm::dot(normal, beg);
158 }
159 
160 //------------------------------------------------------------------------------
161 
162 void offset(fwPlane& plane, double offset)
163 {
164  double distance = getDistance(plane);
165  distance += offset;
166  setDistance(plane, distance);
167 }
168 
169 //------------------------------------------------------------------------------
170 
171 fwPlane getPlane(const fwVec3d& normal,const fwVec3d& point)
172 {
173  ::glm::dvec3 pointGlm(point[0], point[1], point[2]);
174  ::glm::dvec3 normalGlm(normal[0], normal[1], normal[2]);
175  normalGlm = ::glm::normalize(normalGlm);
176  fwPlane plane;
177  plane[0] = normalGlm[0];
178  plane[1] = normalGlm[1];
179  plane[2] = normalGlm[2];
180  plane[3] = ::glm::dot(normalGlm, pointGlm);
181  return plane;
182 }
183 
184 } // namespace fwMath
185 
186 //------------------------------------------------------------------------------
187 
188 bool operator==(fwPlane& plane1, fwPlane& plane2)
189 {
190  ::glm::dvec4 pl1(plane1[0], plane1[1], plane1[2], plane1[3]);
191  ::glm::dvec4 pl2(plane2[0], plane2[1], plane2[2], plane2[3]);
192 
193  double dx = pl1[0] - pl2[0];
194  double dy = pl1[1] - pl2[1];
195  double dz = pl1[2] - pl2[2];
196  double dd = pl1[3] - pl2[3];
197 
198  return ( std::abs(dx) < EPSILON &&
199  std::abs(dy) < EPSILON &&
200  std::abs(dz) < EPSILON &&
201  std::abs(dd) < EPSILON );
202 }
203 
204 //------------------------------------------------------------------------------
FWMATH_API bool isInHalfSpace(const fwPlane &_plane, const fwVec3d &_point)
Compute if a point is in a half plane.
FWMATH_API double getDistance(const fwPlane &_plane)
Get the distance from origin for the given plan (_plane).
FWMATH_API void offset(fwPlane &_plane, double _offset)
Add an offset at the distance of origin which define the plane (_plane).
FWMATH_API void setValues(fwPlane &_plane, const fwVec3d &_point1, const fwVec3d &_point2, const fwVec3d &_point3)
Initialize a plane _plane with three points (_point1, _point2, _point3). It computes the plane&#39;s norm...
FWMATH_API void setDistance(fwPlane &_plane, const double _distance)
Set the distance from origin (_distance) for the given plan (_plane).
FWMATH_API void setNormal(fwPlane &_plane, const fwVec3d &_normal)
Set the normal of the given plane _plane.
The namespace fwMath contains classes which provide the implementation of several mathematic function...
Definition: Compare.hpp:12
FWMATH_API fwVec3d getNormal(const fwPlane &_plane)
Return the normal of the given plane _plane.
FWMATH_API void transform(fwPlane &_plane, const fwMatrix4x4 &_matrix)
Apply a transformation to a plane. The transformation is defined by a matrix 4x4. ...
FWMATH_API bool intersect(const fwLine &_ray, double _radius, const fwVec3d &_point)
Compute the projection of a point in a given direction and test if this intersection is inside a give...