root/cgm/trunk/geom/AnalyticGeometryTool.hpp

Revision 1040, 52.0 KB (checked in by tautges, 2 years ago)

Version 10.2 of cgm.

  • Property svn:executable set to *
Line 
1//-------------------------------------------------------------------------
2// COPYRIGHT 1998  CATERPILLAR INC.  ALL RIGHTS RESERVED
3//
4// Filename      : AnalyticGeometryTool.hpp
5//
6// Purpose       : This class performs calculations on analytic geometry
7//                 (points, lines, arcs, planes, polygons).  Capabilities
8//                 include vector and point math, matrix operations,
9//                 measurements, intersections and comparison/containment checks.
10//
11// Special Notes : As most of these functions were taken from Caterpillar's
12//                 Cmath library with minimal modification for this class,
13//                 the vectors, planes, etc. are represented in non-CUBIT
14//                 format.  These could be converted with some effort.
15//
16//                 Other Notes:
17//                 ------------
18//                 1. Points and vectors are represented as double[3].
19//
20//                 2. Lines (unless denoted as 'segments') are defined as
21//                    a point and a vector (point-direction form).  The parametric
22//                    equations of a line are:
23//
24//                         x = xo + t*a
25//                         y = yo + t*a
26//                         z = zo + t*a
27//
28//                 3. Planes are also defined as a point and a vector
29//                    (point-normal form).  The equation of a plane is:
30//
31//                         a*(x-xo) + b*(y-yo) + c*(z-zo) = 0
32//                     
33//                     For example, the equation of a plane passing through the
34//                     point (3,-1,7) and perpendicular to the vector n = (4,2,-5)
35//                     is: 4(x-3) + 2(y+1) -5(z-7) = 0
36//
37//                     This can be reduced to:
38//
39//                         A*x + B*y + C*z + D = 0
40// 
41//                     For the example, the equation is: 4x + 2y -5z + 25 = 0
42//
43//                 4. Most functions which can accept a 3x3 matrix have
44//                    an analogous 4x4 function.  This is for convenience
45//                    only (the extra rows/columns are ignored within the function).
46//                 
47//
48// Creator       : Steve Storm
49//
50// Creation Date : 10/16/98
51//-------------------------------------------------------------------------
52
53#ifndef ANALYTIC_GEOMETRY_TOOL_HPP
54#define ANALYTIC_GEOMETRY_TOOL_HPP
55
56#include <math.h>
57#include "CubitDefines.h"
58#include "CubitGeomConfigure.h"
59
60#include <iostream>
61
62class CubitBox;
63class CubitPlane;
64class CubitVector;
65template <class X> class DLIList;
66
67  // Multiplication constants
68  const double AGT_E =             2.7182818284590452354;       // e
69  const double AGT_LOG_2E =        1.4426950408889634074;       // log2(e)
70  const double AGT_LOG_10E =       0.43429448190325182765; // log10(e)
71  const double AGT_LN_2 =          0.69314718055994530942; // ln(2)
72  const double AGT_LN_10 =         2.30258509299404568402; // ln(10)
73  const double AGT_PI  =           3.14159265358979323846; // PI
74  const double AGT_PI_DIV_2 =      1.57079632679489661923; // PI/2
75  const double AGT_PI_DIV_4 =      0.78539816339744830962; // PI/4
76  const double AGT_1_DIV_PI =      0.31830988618379067154; // 1/PI
77  const double AGT_2_DIV_PI =      0.63661977236758134308; // 2/PI
78  const double AGT_2_DIV_SQRT_PI = 1.12837916709551257390; // 2/(sqrt(PI))
79  const double AGT_SQRT_2 =        1.41421356237309504880; // sqrt(2)
80  const double AGT_SQRT_1_DIV_2 =  0.70710678118654752440; // sqrt(1/2)
81  const double AGT_PI_DIV_180 =    0.017453292519943295;   // PI/180
82  const double AGT_180_DIV_PI =    57.295779513082323;     // 180/PI
83
84  const double DEGtoRAD = AGT_PI_DIV_180;
85  const double RADtoDEG = AGT_180_DIV_PI;
86
87  typedef struct {
88     double Vec1[3];    /* First vector that defines plane of arc */
89     double Vec2[3];    /* Second vector that defines plane of arc */
90     double Origin[3];  /* Center of arc (on plane) */
91     double StartAngle; /* Starting angle (in radians) of arc */
92     double EndAngle;   /* End angle (in radians) of arc */
93     double Radius;     /* Radius of arc */
94  } AGT_3D_Arc;
95
96  // Return values */
97  enum AgtEquality {
98     AGT_EQUAL       = 0, // define for comparisons
99     AGT_LESSTHAN    = 1, // define for comparisons
100     AGT_GREATERTHAN = 2  // define for comparisons
101  };
102
103  enum AgtSide {
104     AGT_ON_PLANE =  0,  // define for which side of plane
105     AGT_POS_SIDE =  1,  // define for which side of plane
106     AGT_NEG_SIDE =  2,  // define for which side of plane
107     AGT_INT_PLANE = 3,  // define for intersects plane
108     AGT_CROSS = 4       // define for line crossing plane
109  };
110
111  enum AgtOrientation {
112    AGT_OPP_DIR = 0,  // define for vector direction comparision
113    AGT_SAME_DIR = 1  // define for vector direction comparision
114  };
115
116  enum AgtDistanceMethod {
117    AGT_FRACTION = 0,  // define for distance along a curve
118    AGT_ABSOLUTE = 1   // define for distance along a curve
119  };
120
121// Macros
122#define number_sign(number) (number<0 ? -1 : 1)
123#define copy_vec(vec1,vec2) copy_pnt(vec1,vec2)
124#define set_vec(pnt,x,y,z) set_pnt(pnt,x,y,z)
125
126///////////////////////////////////////////////////////////////////////////////
127//                               MAGIC SOFTWARE                              //
128// See note later in file regarding MAGIC softare.                           //
129///////////////////////////////////////////////////////////////////////////////
130// Minimal 2D bounding box - parameters
131const int maxPartition = 32;
132const int invInterp = 32;
133const double angleMin = -0.25*AGT_PI;
134const double angleMax = +0.25*AGT_PI;
135const double angleRange = 0.5*AGT_PI;
136
137typedef struct
138{
139    double x, y;
140}
141Point2;
142
143typedef struct
144{
145    double x, y, z;
146}
147Point3;
148
149typedef struct
150{
151    Point2 center;
152    Point2 axis[2];
153    double extent[2];
154}
155OBBox2;
156
157typedef struct
158{
159    Point3 center;
160    Point3 axis[3];
161    double extent[3];
162}
163OBBox3;
164
165// threshold on determinant to conclude lines/rays/segments are parallel
166const double par_tolerance = 1e-06;
167#ifndef INFINITY
168const double INFINITY = CUBIT_DBL_MAX;
169#endif
170const Point3 PT_INFINITY = { INFINITY, INFINITY, INFINITY };
171#define DIST(x) (Sqrt(Abs(x)))
172
173// Line in 2D
174typedef struct
175{
176    // line is Dot(N,X) = c, N not necessarily unit length
177    Point2 N;
178    double c;
179}
180AgtLine;
181
182// Triangle in 2D
183typedef struct
184{
185    Point2 v[3];
186}
187Triangle;
188
189// Linked list of triangle
190typedef struct AgtTriList
191{
192    Triangle* tri;
193    AgtTriList* next;
194}
195AgtTriList;
196
197//---------------------------------------------------------------------------
198// Lines in 3D
199//---------------------------------------------------------------------------
200typedef struct
201{
202    // Line is L(t) = b+t*m for any real-valued t
203    // Ray has constraint t >= 0, b is the origin of the ray
204    // Line segment has constraint 0 <= t <= 1, b and b+m are end points
205
206    Point3 b, m;
207}
208Line3;
209//---------------------------------------------------------------------------
210
211//---------------------------------------------------------------------------
212// Circles in 3D
213//---------------------------------------------------------------------------
214typedef struct
215{
216    // Plane containing circle is Dot(N,X-C) = 0 where X is any point in the
217    // plane.  Vectors U, V, and N form an orthonormal right-handed set
218    // (matrix [U V N] is orthonormal and has determinant 1).  Circle within
219    // the plane is parameterized by X = C + R*(cos(A)*U + sin(A)*V) where
220    // A is an angle in [0,2*pi).
221
222    Point3 U, V, N;  // coordinate system of plane containing circle
223    Point3 C;  // center
224    double R;  // radius > 0
225}
226Circle3;
227//---------------------------------------------------------------------------
228
229//---------------------------------------------------------------------------
230// Triangles in 3D
231//---------------------------------------------------------------------------
232typedef struct
233{
234    // Triangle points are tri(s,t) = b+s*e0+t*e1 where 0 <= s <= 1,
235    // 0 <= t <= 1, and 0 <= s+t <= 1.
236
237    // If the vertices of the triangle are v0, v1, and v2, then b = v0,
238    // e0 = v1 - v0, and e1 = v2 - v0.
239
240    Point3 b, e0, e1;
241}
242Triangle3;
243//---------------------------------------------------------------------------
244
245//---------------------------------------------------------------------------
246// Parallelograms in 3D
247//---------------------------------------------------------------------------
248typedef struct
249{
250    // Rectoid points are rect(s,t) = b+s*e0+t*e1 where 0 <= s <= 1
251    // and 0 <= t <= 1.  Could have called this a parallelogram, but
252    // I do not like typing long words...
253
254    Point3 b, e0, e1;
255}
256Rectoid3;
257//---------------------------------------------------------------------------
258
259//---------------------------------------------------------------------------
260// Planes in 3D
261//---------------------------------------------------------------------------
262typedef struct
263{
264    // plane is Dot(N,X) = d
265    Point3 N;
266    double d;
267}
268Plane3;
269//---------------------------------------------------------------------------
270
271// END OF MAGIC SOFTWARE
272///////////////////////////////////////////////////////////////////////////////
273
274class CUBIT_GEOM_EXPORT AnalyticGeometryTool
275{
276public:
277
278   ~AnalyticGeometryTool();
279   static AnalyticGeometryTool* instance();
280
281   //*********************************************************
282   // Double numbers
283   //*********************************************************
284   CubitBoolean dbl_eq( double val_1, double val_2 );
285   // Check to see if double numbers are equal within epsilon.
286   // Values are equal if fabs(val_1 - val_2) < epsilon.
287   // Epsilon is determined by next two functions.
288   double get_epsilon();
289   double set_epsilon( double new_epsilon );
290   // Get/set epsilon used for double number comparisons.
291   // Default value is 1e-6.
292#ifdef BOYD14
293   void swap_dbl(double& dbl1,double& dbl2);
294   // Swap two double number memory locations.
295   double min_array( const double *array, int len, int &pos );
296   double max_array( const double *array, int len, int &pos );
297   // Find minimum or maximum of an array of double numbers.
298   // Position in array is returned as well.
299#endif
300   void round_near_val( double& val );
301   // Round value to either -1, 0, or 1 if within epsilon to
302   // to one of these.  Epsilon determined by get_epsilon/set_epsilon
303   // functions.
304
305   //**************************************************************************
306   // Matrices & Transforms
307   //**************************************************************************
308   // Note: For these functions the matrix format is defined as follows:
309   //   
310   //    Consider the transformation from [x,y,z] to [x',y',z']:   
311   //                             _          _
312   //                            | x1 y1 z1 0 |
313   //    [x',y',z',1] = [x,y,z,1]| x2 y2 z2 0 |
314   //                            | x3 y3 z3 0 |
315   //                                        | ox oy oz 1 |
316   //                                         -          -
317   void transform_pnt( double m[4][4], double pin[3], double pout[3] );
318   // This functions applies the transformation matrix to the specified
319   // point and returns the new point coordinates through the call list.
320   // Point in and point out can be the same memory address or different.
321#ifdef BOYD14
322   void transform_pnt_arr( double m[4][4], double pin_arr[][3], 
323                           size_t num_pnts, double pout_arr[][3] );
324   // Transform a point array.  Points can be transformed in place.
325#endif
326   void transform_vec( double m3[3][3], double vin[3], double vout[3] );
327   void transform_vec( double m4[4][4], double vin[3], double vout[3] );
328   // This routine applies a transformation matrix to a specified vector
329   // and returns the new vector orientation.  Vector in and vector out can
330   // be the same memory address or different.
331#ifdef BOYD14
332   double transform_dist( double m3[3][3], double distance, double v[3] );
333   double transform_dist( double m4[4][4], double distance, double v[3] );
334   // Transforms a distance with given transform matrix
335   // The routine can accept the vector direction (in non-transformed system)
336   // of the distance.  This is probably a very unusual case - meaning that,
337   // compared to the old system, the new system is not square (a different
338   // scale factor can apply to each component direction - ie., the distance
339   // 6 units covers in the x-direction may not equal the distance 6 units
340   // covers in the y-direction - a rectangular system!).
341#endif
342   void transform_line( double rot_mtx[4][4], double origin[3], double axis[3] );
343   void transform_line( double rot_mtx[4][4], CubitVector &origin, CubitVector &axis );
344   // Transforms a line using the given transformation mtx.  The mtx is typically
345   // built using add_origin_to_rotation_mtx.
346   void copy_mtx( double from[3][3],double to[3][3] );
347   void copy_mtx( double from[4][4], double to[4][4] );
348   void copy_mtx( double from[4][4], double to[3][3] );
349   void copy_mtx(double from[3][3], double to[4][4], double *origin = NULL );
350   // This routine simply copies one matrix to another.  If a NULL is passed in
351   // for the from matrix, then the identity matrix is copied into the out matrix.
352   // Last function allows you to specify 1st 3 doubles of row 4 (origin) of the
353   // 4x4 matrix.
354   void create_rotation_mtx( double theta, double v[3], double mtx3x3[3][3] );
355   void create_rotation_mtx( double theta, double v[3], double mtx4x4[4][4] );
356   // This routine determines the tranformation matrix given the theta and
357   // the vector to cross through.
358   void add_origin_to_rotation_mtx( double rot_mtx[4][4], double origin[3] );
359   // Adds origin to rotation matrix, so you can rotate points about a line.
360   // Line is defined as original vector used in create_rotation_mtx and
361   // the origin.
362   void identity_mtx( double mtx3x3[3][3] );
363   void identity_mtx( double mtx4x4[4][4] );
364   // Simply sets the given matrix to the identity matrix.
365   void mtx_to_angs( double mtx3x3[3][3], double &ax, double &ay, double &az );
366   void mtx_to_angs( double mtx4x4[4][4], double &ax, double &ay, double &az );
367   // Gets rotation angles to rotate one system to another - returned rotation
368   // angles are about global system.
369   // To use the result from this function, align the unoriented object's origin
370   // with the global origin, then apply the rotation angles returned from this
371   // routine to the object in the order of ax,ay,az about the global origin. 
372   // The object will be oriented such that its xyz axes will point in the same
373   // direction as the object whose transformation matrix was given.  The object
374   // can then be translated.
375   void rotate_system( double mtx[3][3], double sys_in[3][3], 
376                       double sys_out[3][3] );
377   void rotate_system( double mtx[4][4], double sys_in[4][4], 
378                       double sys_out[4][4] );
379   // This routine rotates a 3x3 system given a transformation matrix.  The
380   // matrix can be rotated in place by sending same variable in & out, or a
381   // new matrix can be created.  In the 4x4 case, the translation portion
382   // of the matrix is unchanged.
383#ifdef BOYD14
384   double mtx_to_ratio( double m3[3][3] );
385   double mtx_to_ratio( double m4[4][4] );
386   // This function returns the ratio of a length in the second system to a
387   // length in the first system.  Multiply the length in system 1 by this
388   // ratio to get the length in system 2.
389#endif
390   double det_mtx( double m[3][3] );
391   // Find determinant of matrix.
392   void mult_mtx( double a[3][3],double b[3][3], double d[3][3] );
393   void mult_mtx( double a[4][4], double b[4][4], double d[4][4] );
394   // Multiply matrices together.  If any input is NULL, the identity
395   // matrix is used in its place.
396   CubitStatus inv_mtx_adj( double mtx[3][3], double inv_mtx[3][3] );
397   //This routine inverts a 3x3 matrix using the adjoint method.  If NULL
398   // is sent in for first matrix, the second matrix is set to the identity
399   // matrix.  If the same memory address is passed in for both incoming and
400   // outgoing matrices, the matrix is inverted in place.  Returns CUBIT_FAILURE
401   // if no inverse exists.
402   CubitStatus inv_trans_mtx( double transf[4][4], double inv_transf[4][4] );
403   // This routine inverts a 4x4 transformation matrix.  If NULL is sent in
404   // for first matrix, the second matrix is set to the identity matrix.  If
405   // the same memory address is passed in for both incoming and outgoing matrices,
406   // the matrix is inverted in place.  Uses LU decomposition.
407   void vecs_to_mtx( double xvec[3], double yvec[3], double zvec[3], 
408                     double matrix[3][3] );
409   void vecs_to_mtx( double xvec[3], double yvec[3], double zvec[3], 
410                     double origin[3], double matrix[4][4] );
411   // Creates a transformation matrix given three vectors (and origin
412   // for 4x4 case).
413#ifdef BOYD14
414   void mtx_to_vecs( double matrix[3][3], double xvec[3], double yvec[3], 
415                     double zvec[3] );
416   void mtx_to_vecs( double matrix[4][4], double xvec[3], double yvec[3], 
417                     double zvec[3], double origin[3] );
418   // Extract vectors from a matrix.  NULL can be input for any of the
419   // arguments and the routine will not extract that vector.  NULL can
420   // also be input for the matrix, in which case the function assumes
421   // the identity matrix.
422#endif
423
424   void print_mtx( double mtx[3][3] );
425   void print_mtx( double mtx[4][4] );
426   // Prints matrix values, for debugging.
427
428   //**************************************************************************
429   // 3D Points
430   //**************************************************************************
431   void copy_pnt( double pnt_in[3], double pnt_out[3] );
432   // Copy one double[3] point to another double[3] point (uses memcpy).
433   // If first point in NULL then second point is set to 0,0,0.
434   void copy_pnt( double pnt_in[3], CubitVector &cubit_vec );
435   void copy_pnt( CubitVector &cubit_vec, double pnt_out[3] );
436   // For going back and forth from CubitVectors
437   void set_pnt( double pnt[3], double x, double y, double z );
438   // Sets the value of pnt to x,y,z (inline function).
439#ifdef BOYD14
440   void swap_pnt(double pnt1[3],double pnt2[3]);
441   // Swaps two double[3] points with each other.
442#endif
443   CubitBoolean pnt_eq( double pnt1[3],double pnt2[3] );
444   // Compares two points to determine if they are equivalent.  The
445   // equivalence is based on epsilon (get_epsilon, set_epsilon).
446   // If the distance between them is less than epsilon, the points
447   // are considered equal.
448#ifdef BOYD14
449   CubitBoolean pnt_arr_eq( double **pnt_arr1, long num1, double **pnt_arr2,
450                           long num2, long start_pos1 = 0, long start_pos2 = 0,
451                           long num_to_check = -1 );
452   // Compares two point arrays or portions of two point arrays to
453   // determine if they are equivalent within epsilon (get_epsilon,
454   // set_epsilon).  Checking will stop when either of the array ends
455   // is encountered or num_to_check is exceeded.  Note that he function
456   // can return CUBIT_TRUE even if the arrays are of a different length.
457#endif
458   CubitStatus mirror_pnt( double pnt[3], double pln_orig[3], 
459                           double pln_norm[3], double m_pnt[3]);
460   // Function to mirror a point about a plane.  The mirror point
461   // is the same distance from the plane as the original, but on
462   // the opposite side of the plane.  Function returns CUBIT_FAILURE
463   // if the point is on the plane - in which case the point is
464   // just copied.
465#ifdef BOYD14
466   double ** mirror_pnt_arr( double **pnt_arr, long num_pnts, 
467                             double pln_orig[3], double pln_norm[3],
468                             double **mirror_arr );
469   // Mirrors an array of points about a plane.  If mirror_arr is
470   // non-NULL, function assumes it was allocated to correct lenght.
471   // If NULL, function allocates the array.
472#endif
473   CubitStatus next_pnt( double str_pnt[3], double vec_dir[3], double len,
474                         double new_pnt[3]);
475   // Given start pnt, vec dir and length find next point in space.  The
476   // vector direction is first unitized then the following formula is used:
477   //  new_point[] = start_point[] + (length * unit_vector[])
478   // new_pnt can be the same as input point (overwrites old location).
479#ifdef BOYD14
480   CubitStatus pnt_between2pnts( double pnt1[3], double pnt2[3], 
481                                 AgtDistanceMethod dist_meth, double dist,
482                                 double out_pnt[3] );
483   // This routine creates a point between two other points, at a specified
484   // distance between the two given points.  The distance can be either
485   // absolute (meaning an actual distance, ie. in mm), or a normalized distance
486   // (ie., 50% or 0.5 between the other two points).  The reference point for
487   // the distance is always the first point.
488   // - The normalized distance does not need to be between 0.0 & 1.0.  For example,
489   // a 1.25 normalized distance would result in a point 25% beyond the second
490   // point (not actually "between" the two points).   
491   // - The distances can also be negative.  For example, a -1.25 normalized
492   // distance would result in a point 25% before the first point.  A -50.0
493   // absolute distance would extend 50.0 from the first point in the opposite
494   // direction of the second point.
495#endif
496
497   //***************************************************************************
498   // 3D Vectors
499   //***************************************************************************
500   CubitStatus unit_vec( double vin[3], double vout[3] );
501   // Finds unit vector of input vector (vout can equal vin - converts in place).
502   double dot_vec( double uval[3], double vval[3] );
503   // Dots two vectors.  Property of dot product is:
504   //   angle between vectors acute if dot product > 0
505   //   angle between vectors obtuse if dot product < 0
506   //   angle between vectors 90 deg if dot product = 0
507   void cross_vec( double uval[3], double vval[3], double cross[3] );
508   // Finds cross product of two vectors:
509   //    cross[0] = u[1] * v[2] - u[2] * v[1];
510   //    cross[1] = u[2] * v[0] - u[0] * v[2];
511   //    cross[2] = u[0] * v[1] - u[1] * v[0];
512   void cross_vec_unit( double uval[3], double vval[3], double cross[3] );
513   // Finds unit vector that is cross product of two vectors.
514   void orth_vecs( double uvect[3], double vvect[3], double wvect[3] );
515   // Finds 2 arbitrary orthoganal vectors to the first.
516   double mag_vec( double vec[3] );
517   // Finds the magnitude of a vector:
518   //    magnitude = sqrt (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);
519   CubitStatus get_vec ( double str_pnt[3], double stp_pnt[3],
520                         double vector_out[3] );
521   // Finds a vector from str_pnt to stp_pnt.
522   // Returns CUBIT_FAILURE if points are coincident.
523   CubitStatus get_vec_unit( double str_pnt[3], double stp_pnt[3],
524                             double uv_out[3] );
525   // Finds a unit vector from str_pnt to stp_pnt.
526   // Returns CUBIT_FAILURE if points are coincident.
527   void mult_vecxconst( double constant, double vec[3], double vec_out[3] );
528   // Multiples a vector by a constant (vec_out can equal vec).
529#ifdef BOYD14
530   void add_vec_vec( double vec_1[3], double vec_2[3], double vec_out[3]);
531   // Adds two vectors (vec_out can equal vec_1 or vec_2)
532   void sub_vec_vec( double vec_1[3], double vec_2[3], double vec_out[3] );
533   // Subtracts two vectors (vec_out can equal vec_1 or vec_2).
534#endif
535#ifdef BOYD14
536   void rotate_vec( double v1[3], double v2[3], double angle, double v_out[3] );
537   // Rotate a vector about another vector a given angle.  v_out can equal
538   // v1 (v_out replaces v1) or be a new vector.
539#endif
540   void reverse_vec( double vin[3],double vout[3] );
541   // Multiples -1.0 by a vector (vout can equal vin).
542   double angle_vec_vec( double v1[3],double v2[3] );
543   // Finds angle in radians between two vectors.  Angle will always be
544   // between 0.0 and PI.  For accuracy, the routine uses the cosine for large
545   // angles and the sine for small angles.
546   
547   //***************************************************************************
548   // Distances
549   //***************************************************************************
550   double dist_pnt_pnt( double pnt1[3], double pnt2[3] );
551   // Determines distance between two points in space.
552#ifdef BOYD14
553   double dist_ln_ln( double ln_1_orig[3], double ln_1_vec[3],
554                      double ln_2_orig[3], double ln_2_vec[3],
555                      unsigned short *num_ints = NULL, double int_pnt1[3] = NULL,
556                      double int_pnt2[3] = NULL );
557   // Determines shortest distance between two infinite lines.  Optional
558   // output also includes intersection points.  The num_ints will be zero
559   // if the lines are parallel, one if they physically cross and two if
560   // they are non-parallel and non-crossing.
561   double dist_pnt_pln( double pnt[3], double pln_orig[3], double pln_norm[3], 
562                        AgtSide *side = NULL, double pln_int[3] = NULL );
563   // This routine determines the shortest distance between a point and a
564   // plane.  This is the perpendicular distance from the point to the plane.
565   // Optionally you can find which side of the plane the point is on and
566   // the plane intersection with the point.
567#endif
568   double dist_pln_pln( double pln_1_orig[3], double pln_1_norm[3], 
569                        double pln_2_orig[3], double pln_2_norm[3],
570                        AgtSide *side = NULL, AgtOrientation *orien = NULL,
571                        unsigned short *status = NULL );
572   // This routine determines the shortest distance between two planes.  This
573   // is the perpendicular distance between the two planes.  Note that if the
574   // two planes are not parallel, the returned distance is zero.  The routine
575   // can also be used to determine which side of the first plane the second
576   // plane is on, and the orientation of the two planes to each other.
577#ifdef BOYD14
578   double dist_ln_pln( double ln_orig[3], double ln_vec[3], double pln_orig[3],
579                       double pln_norm[3], AgtSide *side = NULL, 
580                       unsigned short *status = NULL );
581   // This routine determines the shortest distance between a line and a plane. 
582   // This is the perpendicular distance between the line and the plane.  Note
583   // that if the line is not parallel to the plane, the returned distance is
584   // zero.  You can also find which side of the plane the line is on and
585   // the status (= 0 if line & plane not parallel).
586   double dist_pnt_ln( double pnt[3], double ln_orig[3], double ln_vec[3],
587                       double int_pnt[3] = NULL );
588   // This routine determines the shortest distance between a point and a line. 
589   // This is the perpendicular distance between the point and the line.  You
590   // can optionally get the intersection point of the point and line.
591#endif
592   
593   //***************************************************************************
594   // Intersections
595   //***************************************************************************
596   CubitStatus int_ln_pln( double ln_orig[3], double ln_vec[3], double pln_orig[3],
597                           double pln_norm[3], double int_pnt[3] );
598   // This routine calculates the intersection point of a line and a plane.
599   // Returns CUBIT_FAILURE if no intersection exists (line is parallel to the
600   // plane).
601   int int_ln_ln( double p1[3], double v1[3], double p2[3], double v2[3], 
602                  double int_pnt1[3], double int_pnt2[3] );
603   // This function finds the intersection of two lines.  If the lines cross,
604   // it finds the one unique point.  If the lines do not cross (but are non-
605   // parallel), it finds the nearest intersection points (a line drawn from
606   // each of these intersections would be perpendicular to both lines).
607   // Returns number of intersections found:
608   //   0 intersections found, lines are parallel
609   //   1 intersection found, lines physically intersect
610        //   2 intersections found, lines do not intersect but nearest
611        //     intersections found
612   int int_pnt_ln( double pnt[3], double ln_orig[3],  double ln_vec[3],
613                            double int_pnt[3] );
614   // This routine finds the perpendicular intersection of a point & line.  This
615   // point will lie on the line.
616   // Returns 0 if point is not on the line, otherwise 1.
617   int int_pnt_pln( double pnt[3], double pln_orig[3], double pln_norm[3], 
618                             double pln_int[3] );
619   // This routine determines the perpendicular intersection of a point and a
620   // plane.  This is the perpendicular intersection point on the plane.
621   // Returns 0 if point is not on the plane, otherwise 1. 
622   CubitStatus int_pln_pln( double pln_1_orig[3], double pln_1_norm[3],
623                            double pln_2_orig[3], double pln_2_norm[3],
624                            double ln_orig[3], double ln_vec[3] );
625   // This routine finds intersection of two planes.  This intersection results
626   // in a line.  Returns CUBIT_FAILURE if planes are parallel.
627#ifdef BOYD14
628   CubitStatus int_pln_pln_pln( double pln_1_orig[3], double pln_1_norm[3],
629                                double pln_2_orig[3], double pln_2_norm[3],
630                                double pln_3_orig[3], double pln_3_norm[3],
631                                double int_pnt[3] );
632   // This routine finds the intersection of three orthoganal planes.  This
633   // intersection is a point.  Returns CUBIT_FAILURE if no point intersection
634   // exists.
635#endif
636   
637   //**************************************************************************
638   // Comparison/Containment Tests
639   //**************************************************************************
640   CubitBoolean is_vec_par( double vec_1[3], double vec_2[3] );
641   // This routine checks to see if two vectors are parallel.  Two vectors
642   // are considered parallel if they are pointing in the same direction or
643   // opposite directions.
644   CubitBoolean is_vec_perp( double vec_1[3],double vec_2[3]);
645   // This routine checks to see if two vectors are perpendicular.  Two vectors
646   // are considered perpendicular if they are PI/2 radians to each other.
647   CubitBoolean is_vecs_same_dir( double vec_1[3], double vec_2[3] );
648   // This routine checks to see if two vectors point in the same direction.
649   // The vector magnitudes do not have to be equal for a successful return.
650   CubitBoolean is_pnt_on_ln( double pnt[3], double ln_orig[3], double ln_vec[3] );
651   // This routined determines if a specified point is on a given infinite line
652   // defined by a point and a vector.
653   CubitBoolean is_pnt_on_ln_seg( double pnt1[3], double end1[3], double end2[3] );
654   // This routine determines if a specified point is on a given line segment
655   // defined by two endpoints.  The point is on the line only if it lies on
656   // the line between or on the two endpoints.
657   CubitBoolean is_pnt_on_pln( double pnt[3], double pln_orig[3], double pln_norm[3] );
658   // This routined determines if a specified point is on a given plane
659   // which is defined by an origin and three vectors.
660   CubitBoolean is_ln_on_pln( double ln_orig[3], double ln_vec[3],
661                              double pln_orig[3], double pln_norm[3] );
662   // This routine determines if a specified line (defined by a point and
663   // a vector) is in a given plane (defined by the two vectors in the plane
664   // and the normal to that plane).
665#ifdef BOYD14
666   CubitBoolean do_rays_converge( double ray_1_orig[3], double ray_1_vec[3],
667                                  double ray_2_orig[3], double ray_2_vec[3] );
668   // This routine checks to see if two rays converge or diverge towards each
669   // other.  A ray is a line that is not infinite (consists of an origin and
670   // a vector direction).  Rays are defined to converge if they intersect
671   // within a common plane to each ray (ie., if the rays do not lie in a
672   // common plane, one of the rays is temporarily translated into the common
673   // plane for checking).  If the rays are parallel, no one common plane exists,
674   // so they are checked as-is.  See the following examples for a clearer
675   // picture of how this routine works.  Assume that the rays in the first row
676   // are in planes that are parallel to this document but not in planes that are
677   // necessarily coincident.  Assume that the rays in the second row are in the
678   // same plane.  Note that rays may converge even if they are not in the same
679   // plane.
680   //   
681   //    Examples:
682   //   
683   //      *---->          <----*           <----*                     
684   //              ^               ^             ^            ^
685   //              |               |             |            |     
686   //              |               |             |            |
687   //              *               *             *            *---->
688   //       
689   //      converge        diverge           converge        converge   
690   //     
691   //     
692   //      *--->  *--->    *--->  <---*    *--->            *--->   
693   //                                            <---*         *--->
694   //        converge        converge        diverge         diverge
695   CubitBoolean is_ln_on_ln( double ln_orig1[3], double ln_vec1[3],
696                             double ln_orig2[3], double ln_vec2[3] );
697   // This routine checks to see if two lines are colinear.  Two lines are
698   // considered colinear if they are parallel and the origin of one line is on
699   // the other line.
700#endif
701   CubitBoolean is_pln_on_pln( double pln_orig1[3], double pln_norm1[3],
702                               double pln_orig2[3], double pln_norm2[3] );
703   // This routine checks to see if two infinite planes are coincident.
704
705   //**************************************************************************
706   // Arcs/Circles
707   //**************************************************************************
708   void setup_arc( double vec_1[3], double vec_2[3], double origin[3],
709                  double start_angle, double end_angle, // Angles in radians
710                  double radius, AGT_3D_Arc &arc );
711   void setup_arc( CubitVector& vec_1, CubitVector& vec_2, 
712                   CubitVector origin, double start_angle, // Angles in radians
713                   double end_angle, double radius,
714                   AGT_3D_Arc &arc );
715   // Functions to populate an arc structure.  The arc is defined with two
716   // orthogonal vectors in a plane, the arc origin, the beginning angle
717   // in radians to rotate from the start vector (towards second vector), the
718   // ending angle in radians to rotate from the start vector, and the radius
719   // of the arc.  The arc is parameterized from 0 to 1.
720   void get_arc_xyz( AGT_3D_Arc &arc, double param, double pnt[3] );
721   void get_arc_xyz( AGT_3D_Arc &arc, double param, CubitVector& pnt );
722   // Given a parameter value from 0 to 1 on the arc, return the xyz location.
723   // Arc is assumed to be parameterized from 0 to 1.
724
725   int get_num_circle_tess_pnts( double radius, double len_tolerance = 1e-4 );
726   // Get number of tessellation points on the circle required to
727   // approximate the length of the circle within len_tolerance.  Can
728   // be used to find the number of tessellations points to display a
729   // circle - smaller circles will have fewer tessellation points, larger
730   // circles will have more tessellation points with the same tolerance.
731   // Minimum number of tessellations points returned is 8.
732
733   //**************************************************************************
734   // Miscellaneous
735   //**************************************************************************
736   void get_pln_orig_norm( double A, double B, double C, double D, 
737                           double pln_orig[3], double pln_norm[3] = NULL );
738   // Finds an origin-normal format plane from reduced form
739   //   A*x + B*y + C*z + D = 0
740   void get_box_corners( double box_min[3],double box_max[3],double c[8][3] );
741   // Find 8 corners of a box given minimum and maximum points.  Box is
742   // defined starting from left-bottom-front clockwise (at front of box),
743   // then to the rear in same order.
744   CubitStatus min_pln_box_int_corners( const CubitPlane& plane, 
745                                        const CubitBox& box,
746                                        int extension_type, double extension,
747                                        CubitVector& p1, CubitVector& p2,
748                                        CubitVector& p3, CubitVector& p4,
749                                        CubitBoolean silent = CUBIT_FALSE );
750   CubitStatus min_pln_box_int_corners( CubitVector& vec1,
751                                        CubitVector& vec2,
752                                        CubitVector& vec3,
753                                        CubitVector& box_min, CubitVector& box_max,
754                                        int extension_type, double extension,
755                                        CubitVector& p1, CubitVector& p2, 
756                                        CubitVector& p3, CubitVector& p4,
757                                        CubitBoolean silent = CUBIT_FALSE );
758   CubitStatus min_pln_box_int_corners( double plane_norm[3], double plane_coeff,
759                                       double box_min[3], double box_max[3],
760                                       int extension_type, double extension,
761                                       double p1[3], double p2[3],   // OUT
762                                       double p3[3], double p4[3],   // OUT
763                                       CubitBoolean silent = CUBIT_FALSE); 
764   // Finds the 4 corner points of the input infinite plane that just
765   // intersects the input box (defined by bottom-left and top-right corners,
766   // axis aligned with the cubit coordinate system) - plane should have
767   // minimal area.  The resultant plane's corner points can be extended out
768   // by a percentage of diagonal or absolute (making it bigger than the minimal
769   // area plane).  extension_type - 0=none, 1=percentage, 2=absolute
770   // If silent is CUBIT_TRUE, no error messages are given.
771
772   CubitStatus get_tight_bounding_box( DLIList<CubitVector*> &point_list,                                       
773                                       CubitVector& p1, CubitVector& p2,
774                                       CubitVector& p3, CubitVector& p4,
775                                       CubitVector& p5, CubitVector& p6,
776                                       CubitVector& p7, CubitVector& p8);
777   CubitStatus get_tight_bounding_box( DLIList<CubitVector*> &point_list,                                             
778                                       CubitVector &center,
779                                       CubitVector axes[3],
780                                       CubitVector &extension );
781   // Finds the minimum size bounding box that fits around the points.  Box
782   // will not necessarily be oriented in xyz directions.
783
784   CubitStatus min_cyl_box_int( double radius, CubitVector& axis, CubitVector& center,
785                                CubitBox& box,
786                                int extension_type, double extension,
787                                CubitVector &start, CubitVector &end,
788                                int num_tess_pnts = 2048 );
789   CubitStatus min_cyl_box_int( double radius, double axis[3], double center[3], 
790                                double box_min[3], double box_max[3], 
791                                int extension_type, double extension, 
792                                double start[3], double end[3],
793                                int num_tess_pnts = 2048 );
794   // Finds the start and end of a cylinder that just intersects the input
795   // box (defined by bottom-left and top-right corners, axis aligned with
796   // the cubit coordinate system).  The resultant cylinder's start and end
797   // points can be extended out by a percentage of cylinder's length or
798   // absolute (making it longer in both directions).
799   //   extension_type - 0=none, 1=percentage, 2=absolute
800   // The num_tess_pnts is the number of line points along the circle the
801   // function projects to the box to calculate the minimum intersection
802   // (more points could give a more accurate result for non-axis aligned
803   // cylinders).
804
805   double MinTriangleTriangle (Triangle3& tri0, Triangle3& tri1, double& s, double& t, double& u, double& v);
806   // Finds minimum distance between two triangles in 3D (MAGIC)
807   
808   double AreaIntersection (Triangle &tri1, Triangle &tri2 );
809   // Finds area of intersection between two triangles (MAGIC)
810
811   double Angle( Triangle3& tri1, Triangle3& tri2 );
812   // Finds angle between normals of the two triangles (radians)
813
814   double MinPointTriangle (const Point3& p, const Triangle3& tri, double& s, double& t);
815   // Finds minimum distance beween a triange and point in 3D (MAGIC)
816
817#ifdef BOYD14
818   void Center( Triangle3& tri, double center[3] );
819   // Finds center position of given triangle
820#endif
821
822   void Normal( Triangle3& tri, double normal[3] );
823   // Finds normal vector of given triangle
824
825   double ProjectedOverlap( Triangle3& tri1, Triangle3& tri2 );
826   // Projects tri2 to the plane of tri1 and finds the overlap area
827
828protected:
829   AnalyticGeometryTool();
830   //- Class Constructor. (Not callable by user code. Class is constructed
831   //- by the {instance()} member function.
832   
833private:
834   
835   static AnalyticGeometryTool* instance_;
836
837   double agtEpsilon;  // default = 1e-6
838
839
840///////////////////////////////////////////////////////////////////////////////
841//                               MAGIC SOFTWARE
842//This code was obtained from Dave Eberly, at www.magic-software.com.  It
843//has been modified only to be placed into AnalyticGeometryTool.  This was
844//done for convenience only.  An alternate solution would be to create a
845//separate library for these functions.
846//
847//Steve Storm, storm@CAT.com, 3-27-99
848///////////////////////////////////////////////////////////////////////////////
849//MAGIC is an acronym for My Alternate Graphics and Image Code. The
850//initial code base originated in 1991 as an attempt to answer questions that
851//arise in my favorite news group, comp.graphics.algorithms, and has been
852//growing ever since. Magic is intended to provide free source code for solving
853//problems that commonly arise in computer graphics and image analysis. While
854//the code at this web site is free, additional conditions are:
855//
856// *  You may distribute the original source code to others at no charge. You
857//    got it for free, so do not charge others for it.
858// *  You may modify the original source code and distribute it to others at no
859//    charge. The modified code must be documented to indicate that it is not
860//    part of the original package. I do not want folks to blame me for bugs
861//    introduced by modifications. I do accept blame for bugs that are my
862//    doing and will do my best to fix them.
863// *  You may use this code for non-commercial purposes. You may also
864//    incorporate this code into commercial packages. However, you may not
865//    sell any of your source code which contains my original and/or modified
866//    source code (see items 1 and 2 in this list of conditions). In such a case,
867//    you would need to factor out my code and freely distribute it. Send me
868//    email if you use it. I am always interested in knowing where and how
869//    my code is being used.
870// *  The original code comes with absolutely no warranty and no guarantee is
871//    made that the code is bug-free. Caveat emptor.
872//
873// Dave Eberly, eberly@magic-software.com, www.magic-software.com
874///////////////////////////////////////////////////////////////////////////////
875//FILE: minbox2.h
876   double Area (int N, Point2* pt, double angle);
877   void MinimalBoxForAngle (int N, Point2* pt, double angle, OBBox2& box);
878   OBBox2 MinimalBox2 (int N, Point2* pt);
879   // Functions to find minimal area rectangle that surrounds a set of points.
880
881#if 1
882//FILE: minbox3.h
883   void MatrixToAngleAxis( double** R, double& angle, double axis[3] );
884   void AngleAxisToMatrix( double angle, double axis[3], double R[3][3] );
885   double Volume( int N, Point3* pt, double angle[3] );
886   void MinimalBoxForAngles( int N, Point3* pt, double angle[3], OBBox3& box );
887   void GetInterval( double A[3], double D[3], double& tmin, double& tmax );
888   void Combine( double result[3], double A[3], double t, double D[3] );
889   double MinimizeOnInterval( int N, Point3* pt, double A[3], double D[3] );
890   double MinimizeOnLattice( int N, Point3* pt, double A[3], int layers,
891                             double thickness );
892   void InitialGuess( int N, Point3* pt, double angle[3] );
893   OBBox3 MinimalBox3( int N, Point3* pt );
894   // Functions to find minimal volume box that surrounds a set of points.
895#endif
896
897   double Abs (double x);
898   double ACos (double x);
899   double ATan2 (double y, double x);
900   double Cos (double x);
901   double Sign (double x);
902   double Sin (double x);
903   double Sqrt (double x);
904   double UnitRandom ();
905   double Dot (const Point2& p, const Point2& q);
906#ifdef BOYD14
907   Point2 Perp (const Point2& p);
908#endif
909   double Length (const Point2& p);
910   CubitBoolean Unitize (Point2& p );
911   double Dot (const Point3& p, const Point3& q);
912   Point3 Cross (const Point3& p, const Point3& q);
913   double Length (const Point3& p);
914   CubitBoolean Unitize (Point3& p );
915   // Supporting code for triangle calculations
916
917#ifdef BOYD14
918// FILE: lin3lin3.cpp
919   double MinLineLine (const Line3& line0, const Line3& line1, double& s, double& t);
920   double MinLineRay (const Line3& line, const Line3& ray, double& s, double& t);
921   double MinLineLineSegment (const Line3& line, const Line3& seg, double& s, double& t);
922   double MinRayRay (const Line3& ray0, const Line3& ray1, double& s, double& t);
923   double MinRayLineSegment (const Line3& ray, const Line3& seg, double& s, double& t);
924#endif
925   double MinLineSegmentLineSegment (const Line3& seg0, const Line3& seg1, double& s, double& t);
926
927   //get intersection between bounding box and plane
928   int get_plane_bbox_intersections( double box_min[3],
929                                     double box_max[3],
930                                     double pln_orig[3],
931                                     double pln_norm[3],
932                                     double int_array[6][3] );
933// FILE: pt3tri3.cpp
934
935
936// FILE: lin3tri3.cpp
937   double MinLineSegmentTriangle (const Line3& seg, const Triangle3& tri, double& r, double& s, double& t);
938   // Code to support distance between triangles
939
940//FILE: triasect.cpp
941   AgtLine EdgeToLine (Point2* v0, Point2* v1);
942   void TriangleLines (Triangle* T, AgtLine line[3]);
943   AgtTriList* SplitAndDecompose (Triangle* T, AgtLine* line);
944   AgtTriList* Intersection (Triangle* T0, Triangle* T1);
945   double AreaTriangle (Triangle* T);
946   double Area (AgtTriList* list);
947   double Area (Triangle &tri1, Triangle &tri2 );
948   // Code to support area of overlap of two triangles
949};
950
951#if 1
952// FILE: eigen.h
953class mgcEigen
954{
955public:
956        mgcEigen (int _size);
957        ~mgcEigen ();
958
959        mgcEigen& Matrix (float** inmat);
960
961#ifdef BOYD14
962        // solve eigensystem
963        void EigenStuff2 ();  // uses TriDiagonal2
964        void EigenStuff3 ();  // uses TriDiagonal3
965        void EigenStuff4 ();  // uses TriDiagonal4
966        void EigenStuffN ();  // uses TriDiagonalN
967        void EigenStuff  ();  // uses switch statement
968#endif
969
970#ifdef BOYD14
971        // solve eigensystem, use decreasing sort on eigenvalues
972        void DecrSortEigenStuff2 ();
973        void DecrSortEigenStuff3 ();
974        void DecrSortEigenStuff4 ();
975        void DecrSortEigenStuffN ();
976        void DecrSortEigenStuff  ();
977#endif
978
979#ifdef BOYD14
980        // solve eigensystem, use increasing sort on eigenvalues
981        void IncrSortEigenStuff2 ();
982        void IncrSortEigenStuff3 ();
983        void IncrSortEigenStuff4 ();
984        void IncrSortEigenStuffN ();
985        void IncrSortEigenStuff  ();
986#endif
987
988private:
989        int size;
990        float** mat;
991        float* diag;
992        float* subd;
993
994        // Householder reduction to tridiagonal form
995        void Tridiagonal2 (float** pmat, float* pdiag, float* psubd);
996        void Tridiagonal3 (float** pmat, float* pdiag, float* psubd);
997        void Tridiagonal4 (float** pmat, float* pdiag, float* psubd);
998        void TridiagonalN (int n, float** mat, float* diag, float* subd);
999
1000        // QL algorithm with implicit shifting, applies to tridiagonal matrices
1001        void QLAlgorithm (int n, float* pdiag, float* psubd, float** pmat);
1002
1003        // sort eigenvalues from largest to smallest
1004        void DecreasingSort (int n, float* eigval, float** eigvec);
1005
1006        // sort eigenvalues from smallest to largest
1007        void IncreasingSort (int n, float* eigval, float** eigvec);
1008
1009// error handling
1010public:
1011        static int verbose1;
1012        static unsigned error;
1013        static void Report (std::ostream& ostr);
1014private:
1015        static const unsigned invalid_size;
1016        static const unsigned allocation_failed;
1017        static const unsigned ql_exceeded;
1018        static const char* message[3];
1019        static int Number (unsigned single_error);
1020        static void Report (unsigned single_error);
1021};
1022
1023// FILE: eigen.h
1024class mgcEigenD
1025{
1026public:
1027        mgcEigenD (int _size);
1028        ~mgcEigenD ();
1029
1030    // set the matrix for eigensolving
1031        double& Matrix (int row, int col) { return mat[row][col]; }
1032        mgcEigenD& Matrix (double** inmat);
1033
1034        // get the results of eigensolving
1035        double Eigenvector (int row, int col) { return mat[row][col]; }
1036        const double** Eigenvector () { return (const double**) mat; }
1037
1038#ifdef BOYD14
1039        // solve eigensystem
1040        void EigenStuff2 ();  // uses TriDiagonal2
1041#endif
1042        void EigenStuff3 ();  // uses TriDiagonal3
1043#ifdef BOYD14
1044        void EigenStuff4 ();  // uses TriDiagonal4
1045        void EigenStuffN ();  // uses TriDiagonalN
1046        void EigenStuff  ();  // uses switch statement
1047#endif
1048
1049#ifdef BOYD14
1050        // solve eigensystem, use decreasing sort on eigenvalues
1051        void DecrSortEigenStuff2 ();
1052        void DecrSortEigenStuff3 ();
1053        void DecrSortEigenStuff4 ();
1054        void DecrSortEigenStuffN ();
1055        void DecrSortEigenStuff  ();
1056#endif
1057
1058#ifdef BOYD14
1059        // solve eigensystem, use increasing sort on eigenvalues
1060        void IncrSortEigenStuff2 ();
1061        void IncrSortEigenStuff3 ();
1062        void IncrSortEigenStuff4 ();
1063        void IncrSortEigenStuffN ();
1064        void IncrSortEigenStuff  ();
1065#endif
1066
1067private:
1068        int size;
1069        double** mat;
1070        double* diag;
1071        double* subd;
1072
1073        // Householder reduction to tridiagonal form
1074        void Tridiagonal2 (double** mat, double* diag, double* subd);
1075        void Tridiagonal3 (double** mat, double* diag, double* subd);
1076        void Tridiagonal4 (double** mat, double* diag, double* subd);
1077        void TridiagonalN (int n, double** mat, double* diag, double* subd);
1078
1079        // QL algorithm with implicit shifting, applies to tridiagonal matrices
1080        void QLAlgorithm (int n, double* diag, double* subd, double** mat);
1081
1082        // sort eigenvalues from largest to smallest
1083        void DecreasingSort (int n, double* eigval, double** eigvec);
1084
1085        // sort eigenvalues from smallest to largest
1086        void IncreasingSort (int n, double* eigval, double** eigvec);
1087
1088// error handling
1089public:
1090        static int verbose1;
1091        static unsigned error;
1092        static void Report (std::ostream& ostr);
1093private:
1094        static const unsigned invalid_size;
1095        static const unsigned allocation_failed;
1096        static const unsigned ql_exceeded;
1097        static const char* message[3];
1098        static int Number (unsigned single_error);
1099        static void Report (unsigned single_error);
1100};
1101#endif
1102
1103///// MAGIC SOFTWARE - INLINE FUNCTIONS
1104//---------------------------------------------------------------------------
1105// Wrapped math functions
1106//---------------------------------------------------------------------------
1107inline double AnalyticGeometryTool::Abs (double x)
1108{
1109    return double(fabs(x));
1110}
1111
1112inline double AnalyticGeometryTool::ATan2 (double y, double x)
1113{
1114    return double(atan2(y,x));
1115}
1116
1117inline double AnalyticGeometryTool::Sqrt (double x)
1118{
1119    return double(sqrt(x));
1120}
1121
1122inline double AnalyticGeometryTool::UnitRandom ()
1123{
1124    return double(rand())/double(RAND_MAX);
1125}
1126
1127//---------------------------------------------------------------------------
1128// Points in 2D
1129//---------------------------------------------------------------------------
1130
1131inline double AnalyticGeometryTool::Dot (const Point3& p, const Point3& q)
1132{
1133    return double(p.x*q.x + p.y*q.y + p.z*q.z);
1134}
1135
1136
1137inline double AnalyticGeometryTool::set_epsilon( double new_epsilon )
1138{ 
1139   double old_epsilon = agtEpsilon;
1140   agtEpsilon = new_epsilon;
1141   return old_epsilon;
1142}
1143
1144inline CubitBoolean AnalyticGeometryTool::dbl_eq(double val_1,double val_2)
1145{ 
1146   CubitBoolean result;
1147   if (fabs(val_1 - val_2) < agtEpsilon)
1148      result = CUBIT_TRUE;
1149   else
1150      result = CUBIT_FALSE;
1151   return result;
1152}
1153
1154#endif
Note: See TracBrowser for help on using the browser.