Library of Assembled Shared Sources
plane_3d.h
Go to the documentation of this file.
1/** @file
2 * @author Bram de Greve (bram@cocamware.com)
3 * @author Tom De Muer (tom@cocamware.com)
4 *
5 * *** BEGIN LICENSE INFORMATION ***
6 *
7 * The contents of this file are subject to the Common Public Attribution License
8 * Version 1.0 (the "License"); you may not use this file except in compliance with
9 * the License. You may obtain a copy of the License at
10 * http://lass.sourceforge.net/cpal-license. The License is based on the
11 * Mozilla Public License Version 1.1 but Sections 14 and 15 have been added to cover
12 * use of software over a computer network and provide for limited attribution for
13 * the Original Developer. In addition, Exhibit A has been modified to be consistent
14 * with Exhibit B.
15 *
16 * Software distributed under the License is distributed on an "AS IS" basis, WITHOUT
17 * WARRANTY OF ANY KIND, either express or implied. See the License for the specific
18 * language governing rights and limitations under the License.
19 *
20 * The Original Code is LASS - Library of Assembled Shared Sources.
21 *
22 * The Initial Developer of the Original Code is Bram de Greve and Tom De Muer.
23 * The Original Developer is the Initial Developer.
24 *
25 * All portions of the code written by the Initial Developer are:
26 * Copyright (C) 2004-2011 the Initial Developer.
27 * All Rights Reserved.
28 *
29 * Contributor(s):
30 *
31 * Alternatively, the contents of this file may be used under the terms of the
32 * GNU General Public License Version 2 or later (the GPL), in which case the
33 * provisions of GPL are applicable instead of those above. If you wish to allow use
34 * of your version of this file only under the terms of the GPL and not to allow
35 * others to use your version of this file under the CPAL, indicate your decision by
36 * deleting the provisions above and replace them with the notice and other
37 * provisions required by the GPL License. If you do not delete the provisions above,
38 * a recipient may use your version of this file under either the CPAL or the GPL.
39 *
40 * *** END LICENSE INFORMATION ***
41 */
42
43
44/** @struct lass::prim::Plane3D
45 * @brief A 3D hyper plane.
46 * @author BdG
47 * @date 2003
48 *
49 * I assume if you look to this class, you'll wonder ... "where the heck did all the code go?"
50 * Hah, I'll tell ya. There are more than one possible models for representing a plane. We can
51 * use a cartesian equation N.P + S = 0, or we can use a parametric equation P = S + x*U + y*V.
52 * This class let's you choose what implementation you want: a pure partesian model, a pure
53 * parametric model, or a model that combines both. This is done by moving all code to
54 * implemenations impl::Plane3DCartesian, impl::Plane3DParametric or impl::Plane3DCombined of
55 * which this class with inherent accoring the model you've chosen. You can select the one you
56 * want by specifying the template parameter @c EquationPolicy. You can either use Cartesian
57 * (which is the default), Parametric or Combined. Each of them will model the plane
58 * differently. They all provide the same interface, but might have different results. They
59 * might have different memory footprints, different performances, and are optimized for
60 * different purposes. Cartesian will select an implementation that only uses the cartesian
61 * equation and will be the smallest and the fastest for most purposes (that's why it is the
62 * default :). For texture mapping, you might more like the Parametric model, because it has
63 * better support for direction vectors, but it'll have to calculate the normal on the spot if
64 * you need it. Combined is the workhorse for heavy duties and implements both. Plus, it
65 * buffers the reciprocal direction vectors, so finding the parameters (x, y) of a point on the
66 * plane can happen faster.
67 *
68 * @section common_interface common interface
69 *
70 * Anyway, let me give you some general info on this whole Plane3D thing. Though there are
71 * three different implemntations, they all show the same interface. We'll explore them by this
72 * common
73 * interface:
74 *
75 * @subsection type_definitions type definitions
76 *
77 * - @c TSelf: the type of @c this
78 * - @c TImpl: type of implemantion, can be impl::Plane3DCartesian, impl::Plane3DParametric or
79 * impl::Plane3DCombined.
80 * - @c TNormalizingPolicy: the type you've used as NormalizingPolicy.
81 * - @c TPoint: type of a afine point in space.
82 * - @c TVector: type of a vector in space.
83 * - @c TUV: a pair of values (u, v) for the parametric equation P = S + u*U + v*V.
84 * - @c TValue: same as util::CallTraits<T>::TValue.
85 * - @c TParam: same as util::CallTraits<T>::TParam.
86 * - @c TReference: same as util::CallTraits<T>::TReference.
87 * - @c TConstReference: same as util::CallTraits<T>::TConstReference.
88 * - @c TNumTraits: same as num::NumTraits<T>.
89 *
90 * @subsection constructors
91 *
92 * @par Plane3D():
93 * the default constructor brings the plane in an invalid state. normal and/or direction vectors
94 * will have zero length, which indicates for this invalid state.
95 *
96 * @par Plane3D(const TPoint& iSupport, const TPoint& iPointU, const TPoint& iPointV):
97 * construct a plane through three points. The parametric equation P = S + u*U + v*V is going to
98 * be constructed as following: iSupport will be the support point S, and direction vectors U and
99 * V will be drawn from the support point to iPointU and iPointV: U = iPointU - iSupport and V =
100 * iPointV - iSupport. The cartesian equation N.P + d == 0 is constructed as following: the normal
101 * N = U x V. d is determined by demaning that N.iSupport + d == 0.
102 *
103 * @par Plane3D(const TPoint& iSupport, const TVector& iDirU, const TVector& iDirV):
104 * constructs a plane through one support point and two direction vectors (the parametric equation,
105 * anyone? :). For the parametric equation P = S + u*U + v*V, we have iSupport for S, iDirU for U
106 * and iDirV for V. Again the cartesian equation N.P + d == 0 is given by N = U x V and
107 * N.iSupport + d == 0.
108 *
109 * @par Plane3D(const TPoint& iSupport, const TVector& iNormal):
110 * constructs a plane through a support point and a normal vector. For the parametric equation
111 * P = S + u*U + v*V, we have iSupport for S, but U and V we have to get a little dirty. We have
112 * to find two vectors U and V so that iNormal = U x V. See Plane3DCommonImpl::generateDirections
113 * on how we do that. The cartesian N.P + d == 0 is simple, we have iNormal for N and d can be
114 * found by N.iSupport + d == 0.
115 *
116 * @par Plane3D(const TVector& iNormal, TParam iD):
117 * construct a plane by a normal vector and fourth value (cartesian equation? :). For the
118 * parametric equation P = S + u*U + v*V, all have to generated: for S we use the point -iD*iNormal
119 * that is the closest point of the plane to the origin, U and V we've generated again with our
120 * little trick Plane3DCommonImpl::generateDirections. For the cartesian equation N.P + d == 0, we
121 * of course use N = iNormal and d = iD.
122 *
123 * @subsection accessors
124 *
125 * After constructions, all vectors are normalized depending on the NormalizingPolicy you've
126 * choosen. if the normal vector N is scaled, then d is scaled as well, so it still represents
127 * the same plane.
128 *
129 * Now, we have a series of accessors that give you access to the internal data of the plane,
130 * including support point, direction vectors, normal vector, ... Only Plane3DCombined will be
131 * able to pull these directly from its internals, but the others don't have all data aboard, so
132 * they have to generate them. Be carefull, because it's not always what you suspect.
133 *
134 * @par const TPoint support():
135 * returns the support point of the plane. If you used a support point for the construction of the
136 * plane, models Plane3DParametric and Plane3DCombined will give you back this original one,
137 * exactly till the last bit. Plane3DCartesian doesn't keep track of support points, so it has to
138 * create one if you ask for it. It uses -d*N, the point of the plane that is closest to the
139 * origin. Mind you that this one probably will not be the same as the original one, totally
140 * different even! Of course, if you used a cartesian equation to construct the plane (without any
141 * support point), then all three models need to generate a support point at some point: -d*N. In*
142 * that case, all three models @e will return the same support point.
143 *
144 * @par void getDirections(TVector& oDirU, TVector& oDirV):
145 * get the direction vectors of the plane. almost same story as for support(). If you've created
146 * the plane by two direction vectors or through three points (which leads to two direction
147 * vectors), then models Plane3DParametric and Plane3DCombined will give you back these originals
148 * (for Unnormalized planes only! but in case of Normalized planes, they still correspond with the
149 * original directions). Plane3DCartesian has to regenerate them by using
150 * Plane3DCommonImpl::generateDirections, and hence it can end up with total different directions!
151 * (of the same plane of course). In case you've feeded the plane with a normal vector instead of
152 * direction vectors, all have to generate them and end up with the same ones.
153 *
154 * @par const TVector directionU():
155 * same story as getDirections(oDirU, oDirV), but only returns direction U. In case of
156 * Plane3DCartesian, it calls getDirections(oDirU, oDirV) itselfs, but throws away half of the
157 * result. Hence, it's pretty slow, certainly if you also call dirV(), cause it does the same
158 * thing. And then you end up with two hidden calls to getDirections(oDirU, oDirV) (which means
159 * expensive generation of direction vectors), while you could have had the same result by calling
160 * getDirections(oDirU, oDirV) once yourself but at half the price. So, the tip is: DO use
161 * getDirections(oDirU, oDirV) if you can and need them both, and certainly if you're dealing with
162 * the Plane3DCartesian model.
163 *
164 * @par const TVector directionV():
165 * same story as directionU(), but returns V instead and throws away U.
166 *
167 * @par void getReciprocals(TVector& oReciprocalU, TVector& oReciprocalV):
168 * gets the reciprocals for the direction vectors. These reciprocals can be used to find back
169 * (u, v) in the parametric equation P = S + u*U + v*V for given P. u = oReciprocalU * (P - S) and
170 * v = oReciprocalV * (P - S). In fact, they are used by TUV uv(const TPoint& iPoint) which is
171 * described below :) I'm not going to get in detail how get these reciprocals, but I will tell
172 * you that only Plane3DCombined has these stored on board, and can return them or use them without
173 * to generate them. Plane3DParametric does has to generate them on the spot, and so does
174 * Plane3DCartesian. However, for Plane3DCartesian it is even worse, because before it can create
175 * reciprocals, it has to create direction vectors first!
176 *
177 * @par const TVector reciprocalU():
178 * same story as getReciprocals(oReciprocalU, oReciprocalV), but returns only oReciprocalU. same
179 * remark as on const TVector dirU(): if it has to generate it, it has to generate both
180 * reciprocals, so it might be faster to use getReciprocals(oReciprocalU, oReciprocalV).
181 *
182 * @par const TVector reciprocalV():
183 * same story as reciprocalV(), but returns the other one.
184 *
185 * @par void getCartesian(TVector& oNormal, TReference oD):
186 * gets normal vector and d-value for the cartesian equation. Now, this is the first one
187 * Plane3DCartesian has aboard itself. Plane3DCombined also has it, but now it's up to
188 * Plane3DParametric to generate some stuff :) Though, it's less worse than the other way around.
189 * This is because the parametric equation contains more information that the normal vector, and
190 * doesn't have to 'invent' anything like Plane3DCartesian has to do to return support point or
191 * direction vectors. Actually, in theory, all three models should return the same normal and
192 * d-value. In practice however, we have to deal with numerical imprecisions. so the result of
193 * Plane3DParametric can differ a little in the last bits. not a big difference, but enough to be
194 * inequal.
195 *
196 * @par const TVector normal():
197 * returns only the normal vector of the cartesian equation. For Plane3DParametric we have again
198 * the same remark as for getDirections and getReciprocals: it uses getCartesian anyway, so that
199 * might be faster if you both need the normal and d-value.
200 *
201 * @par TValue d():
202 * same as normal(), but returns only the value d instead of the normal vector.
203 *
204 * @par const XYZ majorAxis() const
205 * Return the major axis of the normal vector.
206 * The major axis is the one with the largest (absolute) component value. e.g. if the normal
207 * vector is (-1, 4, -8), this will be the @e z axis because abs(-8) > abs(4) > abs(-1).
208 * In case there's more than one major axis possible, the "highest" index is choosen. e.g.
209 * if the normal vector is (1, 1, 0), then @e y axis will be choosen, because @e y has a higher
210 * index than @e x .
211
212 *
213 * @subsection methods_cartesian cartesian methods
214 *
215 * So far the accessors. let's get to cooler stuff. For most of this stuff, we need the cartesian
216 * equation. Plane3DCartesian and Plane3DCombined have it on board, but Plane3DParametric will
217 * have to generate it each call. Keep that in mind!
218 *
219 * @par Side classify(const TPoint& iPoint):
220 * tells at which side of the plane we can find the point iPoint: the front (sFront), the back
221 * (sBack), or right on the surface (sSurface). the front is the side where the normal sticks or
222 * points to. The back is the other one. iPoint is exactly one the surface if N.iPoint + d == 0.
223 * Since we need the parametric equation, Plane3DParametric might have a performance hit here.
224 *
225 * @par TValue equation(const TPoint& iPoint):
226 * fills in the point iPoint in the cartesian equation and returns the resutl. N.iPoint + d will
227 * usually not be equal to zero (it's only zero for points on the plane). This method returns what
228 * it is equal to. i.e. it returns N.iPoint + d. For Normalized planes this is the same as the
229 * distance of iPoint to the plane, but not for Unnormalized planes, keep that in mind! If you
230 * need the distance, used signedDistances(iPoint) as described below. Again you might have a
231 * performance hit for the Plane3DParametric model because of the need of the cartesian equation.
232 *
233 * @par TValue signedDistance(const TPoint& iPoint):
234 * returns the distance of the point to the plane, but signed. it will be positive for points in
235 * front of the plane, and negative for the ones in the back (also see: classify(iPoint)). The
236 * real (unsigned) distances is simply the absolute value of the result. For Normalized planes
237 * signedDistances(iPoint) will be equal to equation(iPoint). But for Unnormalized planes
238 * signedDistances still divides through the normal's length Again performance hit for
239 * Plane3DParametric because of the need of the cartesian equation.
240 *
241 * @par TValue squaredDistance(const TPoint& iPoint):
242 * returns the distance of iPoint to the plane but squared. Not much more to tell, realy :) Again
243 * performance hit for Plane3DParametric because of the cartesian equation.
244 *
245 * @par TVector reject(const TPoint& iPoint):
246 * returns rejection of iPoint by the plane. This is a bit tricky to explain. If you have a
247 * support point S, then this rejection is the part of (iPoint - S) that is parallel to the normal
248 * vector (or orthogonal to the plane). This would be the same as the rejection of (iPoint - S)
249 * (given by reject(iPoint - S), see below). But more descriptive might be: it is the vector you
250 * have to add to the projection of this point on the plane (given by project(iPoint), see below),
251 * to get back iPoint: iPoint == project(iPoint) + reject(iPoint). Again performance hit for
252 * Plane3DParametric because of the cartesian equation.
253 *
254 * @par TVector reject(const TVector& iVector):
255 * returns rejection of iVector by the plane. This is already somewhat easier. the rejection of
256 * iVector is that part of iVector that is parallel to the normal vector of the plane. You can
257 * also say that it is the orthogonal projection of iVector on the normal vector. Or the part of
258 * iVector that is orthogonal to the plane. Again performance hit for Plane3DParametric because
259 * of the cartersian equation.
260 *
261 * @par TPoint project(const TPoint& iPoint):
262 * return the orthogonal projection of iPoint on the plane. It is the point on the plane that is
263 * the closest one to iPoint. If you draw a line through iPoint parallel to the normal vector,
264 * this projection is the point where this line intersects the plane. It is know that iPoint ==
265 * project(iPoint) + reject(iPoint). Again performance hit for Plane3DParametric because of the
266 * cartesian equation.
267 *
268 * @par TVector project(const TVector& iVector):
269 * return the orthogonal projection of iVector on the plane. It is the part of iVector that is parallel to the plane, or orthogonal to
270 * the normal vector. It is known that iVector == project(iVector) + reject(iVector). Again
271 * performance hit for Plane3DParametric because of the cartesian equation.
272 *
273 * @par TPoint reflect(const TPoint& iPoint):
274 * return the reflection of iPoint in the plane. It is the point at the same distance of the
275 * plane, but at the exact opposite side of the plane. If you draw a line through iPoint parallel
276 * to the normal vector, it's the only other point on that line that is at the same (absolute)
277 * distance of the plane. If you walk from iPoint to the intersection point of the line and the
278 * plane, and you walk further the same distance again, you arrive at reflection of iPoint. It is
279 * known that reflect(iPoint) == project(iPoint) - reject(iPoint). Again performance hit for
280 * Plane3DParametric because of the cartesian equation.
281 *
282 * @par TVector reflect(const TVector& iVector):
283 * return the reflection of iVector in the plane. It's the vector of which the orthogonal part to
284 * the plane is flipped. It is know that reflect(iVector) == project(iVector) - reject(iVector).
285 * Again performance hit for Plane3DParametric because of the cartesian equation.
286 *
287 * @subsection cartesian_methods cartesian methods
288 *
289 * So far functions for the cartesian boys. Now some stuff for parametric fellows. It's about how
290 * we can get a point of the plane if we now its two parametrs u and v, and how we can find u and v
291 * if we know a point of the plane.
292 *
293 * @par TPoint point(TValue iU, TValue iV):
294 * return a point of the parametric equation P = S + iU * dirU + iV * dirV. In case of
295 * Plane3DCartesian, we have the same remarks as for getDirections(oDirU, oDirV): not only we have
296 * a performance hit, we probably also have to deal with totally different direction vectors than
297 * the ones we have put in the constructor.
298 *
299 * @par TPoint point(TUV iUV):
300 * return a point of the parametric equation P = S + iUV.x * dirU + iUV.y * dirV. Pretty much the
301 * same thing as the one above, but packs both values in one pair iUV. Same remarks on
302 * Plane3DCartesian.
303 *
304 * @par TUV uv(const TPoint& iPoint):
305 * returns a pair a values (u, v) so that iPoint == S + u * dirU + v * dirV. In theory, if you put
306 * these back in point(u, v), you should end up with iPoint again: point(uv(iPoint)) == iPoint ?
307 * Well, this is not totally true First of all, even in theory, it can only be true if iPoint is a
308 * point of the plane. if iPoint is not on the plane, then uv(iPoint) will give you the parameters
309 * of the point on the plane that is closest to iPoint. And that point is the projection of
310 * iPoint. So, the most you can say is that point(uv(iPoint)) == project(iPoint) ? Yes, but IN
311 * THEORY! In practice, however, numerical imprecisions will probably give you a slightly
312 * different result. You'll be very close, but the last bits will differ enough to make the them
313 * inequal. But with some epsilons, you'll be alright. Some performance remarks: Only
314 * Plane3DCombined has the necessary reciprocals for the direction vectors on board (remember the
315 * getReciprocals() discussion? well, here it we have it :) Plane3DParametric does not, and will
316 * have to recreate them on each call. This _might_ and probably will be quite costly. For
317 * Plane3DCartesian, you're totally screwed: not only do we have to genereate the reciprocals, but
318 * we also have to generate the direction vectors we want to create reciprocals of! So, you'll pay
319 * twice. And above all, it won't be the reciprocals of the direction vectors you've put it.
320 *
321 * @subsection misc_methods misc. methods
322 *
323 * @par void flip():
324 * flips the plane so that the front becomes the back and the back becomes the front. For the
325 * cartesian equation, this is done by negating the normal and d: N = -N and d = -d. Of the parametric
326 * equation, direction vector U is flipped:
327 * U = -U.
328 *
329 * @par bool isValid():
330 * returns true if the interal data represents a valid plane, and false if not. A plane is valid
331 * if none of the direction vectors nor the normal vector are zero vectors. And above of that,
332 * the direction vectors may not be colinear. Of course, we only test internal data. We will not
333 * generate direction vectors (in case of Plane3DCartesian), just to test the if they are valid.
334 * We can safely do that, because we know that if the normal vector is valid, then the generated
335 * directions will be too.
336 */
337
338
339
340#ifndef LASS_GUARDIAN_OF_INCLUSION_PRIM_PLANE_3D_H
341#define LASS_GUARDIAN_OF_INCLUSION_PRIM_PLANE_3D_H
342
343#include "prim_common.h"
344#include "equation_policy.h"
345#include "normalizing_policy.h"
346#include "point_2d.h"
347#include "point_3dh.h"
348#include "xyz.h"
349#include "impl/plane_3d_impl.h"
351
352
353
354namespace lass
355{
356namespace prim
357{
358
359template <typename T, class EquationPolicy = Cartesian, class NormalizingPolicy = Normalized>
360class Plane3D: public impl::Plane3DImpl<T, EquationPolicy, NormalizingPolicy>::Type
361{
362public:
363
364 typedef Plane3D<T, EquationPolicy, NormalizingPolicy> TSelf;
365 typedef typename impl::Plane3DImpl<T, EquationPolicy, NormalizingPolicy>::Type TImpl;
366
367 typedef typename TImpl::TPoint TPoint;
368 typedef typename TImpl::TVector TVector;
369 typedef typename TImpl::TParam TParam;
370 typedef typename TImpl::TValue TValue;
371 typedef typename TImpl::TReference TReference;
372 typedef typename TImpl::TConstReference TConstReference;
373 typedef typename TImpl::TNumTraits TNumTraits;
374
375 template <typename U>
376 struct Rebind
377 {
378 typedef Plane3D<U, EquationPolicy, NormalizingPolicy> Type;
379 };
380
381 Plane3D();
382 Plane3D(const TPoint& iSupport, const TPoint& iPointU, const TPoint& iPointV);
383 Plane3D(const TPoint& iSupport, const TVector& iDirU, const TVector& iDirV);
384 Plane3D(const TVector& iNormal, const TPoint& iSupport);
385 Plane3D(const TVector& iNormal, TParam iD);
386
387 Side classify(const TPoint& iPoint) const;
388 const TValue signedDistance(const TPoint& iPoint) const;
389 const TValue squaredDistance(const TPoint& iPoint) const;
390
391 Side classify(const TPoint& iPoint, TParam iRelativeTolerance) const;
392 const TValue signedDistance(const TPoint& iPoint, TParam iRelativeTolerance) const;
393 const TValue squaredDistance(const TPoint& iPoint, TParam iRelativeTolerance) const;
394
395 const XYZ majorAxis() const;
396
397 /*
398 typedef NormalizingPolicy TNormalizingPolicy;
399
400 typedef Point3D<T> TPoint;
401 typedef TPoint::TVector TVector;
402 typedef Point2D<T> TUV;
403
404 typedef TPoint::TValue TValue;
405 typedef TPoint::TParam TParam;
406 typedef TPoint::TReference TReference;
407 typedef TPoint::TConstReference TConstReference;
408 typedef TPoint::TNumTraits TNumTraits;
409
410 enum { dimension = TPoint::dimension };
411
412 const TPoint support() const;
413 void getDirections(TVector& oDirU, TVector& oDirV) const;
414 const TVector directionU() const;
415 const TVector directionV() const;
416
417 void getReciprocals(TVector& oReciprocalU, TVector& oReciprocalV) const;
418 const TVector reciprocalU() const;
419 const TVector reciprocalV() const;
420
421 void getCartesian(TVector& oNormal, TReference oD) const;
422 const TVector& normal() const;
423 TConstReference d() const;
424 const XYZ majorAxis() const;
425
426 Side classify(const TPoint& iPoint) const;
427 TValue equation(const TPoint& iPoint) const;
428 TValue signedDistance(const TPoint& iPoint) const;
429 TValue squaredDistance(const TPoint& iPoint) const;
430
431 TVector reject(const TPoint& iPoint) const;
432 TVector reject(const TVector& iVector) const;
433 TPoint project(const TPoint& iPoint) const;
434 TVector project(const TVector& iVector) const;
435 TPoint reflect(const TPoint& iPoint) const;
436 TVector reflect(const TVector& iVector) const;
437
438 TPoint point(TParam iU, TParam iV) const;
439 TPoint point(const TUV& iUV) const;
440 TUV uv(const TPoint& iPoint) const;
441
442 void flip();
443 bool isValid() const;
444 */
445};
446
447template <typename T>
448io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const Plane3D<T, Cartesian>& iPlane);
449template <typename T>
450io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const Plane3D<T, Parametric>& iPlane);
451template <typename T>
452io::XmlOStream& operator<<(io::XmlOStream& ioOStream, const Plane3D<T, Combined>& iPlane);
453
454}
455
456}
457
458#include "plane_3d.inl"
459
460//#ifdef LASS_GUARDIAN_OF_INCLUSION_PRIM_LINE_3D_H
461//#include "line_3d_plane_3d.h"
462//#endif
463
464#ifdef LASS_GUARDIAN_OF_INCLUSION_PRIM_AABB_3D_H
465# include "aabb_3d_plane_3d.h"
466#endif
467
468#ifdef LASS_GUARDIAN_OF_INCLUSION_PRIM_LINE_SEGMENT_3D_H
470#endif
471
472#ifdef LASS_GUARDIAN_OF_INCLUSION_PRIM_RAY_3D_H
473# include "plane_3d_ray_3d.h"
474#endif
475
476#ifdef LASS_GUARDIAN_OF_INCLUSION_PRIM_TRANSFORMATION_3D_H
478#endif
479
480#endif
481
482// --- END OF FILE ------------------------------------------------------------------------------
Output stream for writing a selection of geometric primitives to XML files.
A 3D hyper plane.
Definition plane_3d.h:361
Side classify(const TPoint &iPoint, TParam iRelativeTolerance) const
Return on what side a point is located.
Definition plane_3d.inl:140
const TValue signedDistance(const TPoint &iPoint) const
Return signed distance of point to plane.
Definition plane_3d.inl:119
const TValue squaredDistance(const TPoint &iPoint) const
Return squared distance of point to plane.
Definition plane_3d.inl:130
const TValue squaredDistance(const TPoint &iPoint, TParam iRelativeTolerance) const
Return squared distance of point to plane.
Definition plane_3d.inl:164
const TValue signedDistance(const TPoint &iPoint, TParam iRelativeTolerance) const
Return signed distance of point to plane.
Definition plane_3d.inl:153
Side classify(const TPoint &iPoint) const
Return on what side a point is located.
Definition plane_3d.inl:106
const XYZ majorAxis() const
determines the major axis of the normal vector.
Definition plane_3d.inl:179
cyclic iterator over xyz indices
Definition xyz.h:62
set of geometrical primitives
Definition aabb_2d.h:81
Side
Different sides of a surface.
Definition side.h:79
Library for Assembled Shared Sources.
Definition config.h:53
binder of equation policy to lass::prim::Plane3D implementation