MOAB: Mesh Oriented datABase  (version 5.2.1)
VerdictVector.hpp
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Module:    $RCSfile: VerdictVector.hpp,v $
00004 
00005   Copyright (c) 2006 Sandia Corporation.
00006   All rights reserved.
00007   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00008 
00009      This software is distributed WITHOUT ANY WARRANTY; without even
00010      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00011      PURPOSE.  See the above copyright notice for more information.
00012 
00013 =========================================================================*/
00014 
00015 /*
00016  *
00017  * VerdictVector.hpp contains declarations of vector operations
00018  *
00019  * This file is part of VERDICT
00020  *
00021  */
00022 
00023 #ifndef VERDICTVECTOR_HPP
00024 #define VERDICTVECTOR_HPP
00025 
00026 #include "moab/verdict.h"
00027 #include <cassert>
00028 #include <cmath>
00029 
00030 class VerdictVector;
00031 typedef void ( VerdictVector::*transform_function )( double gamma, double gamma2 );
00032 // a pointer to some function that transforms the point,
00033 // taking a double parameter.  e.g. blow_out, rotate, and scale_angle
00034 
00035 class VerdictVector
00036 {
00037   public:
00038     //- Heading: Constructors and Destructor
00039     VerdictVector();  //- Default constructor.
00040 
00041     VerdictVector( const double x, const double y, const double z );
00042     //- Constructor: create vector from three components
00043 
00044     VerdictVector( const double xyz[3] );
00045     //- Constructor: create vector from tuple
00046 
00047     VerdictVector( const VerdictVector& tail, const VerdictVector& head );
00048     //- Constructor for a VerdictVector starting at tail and pointing
00049     //- to head.
00050 
00051     VerdictVector( const VerdictVector& copy_from );  //- Copy Constructor
00052 
00053     //- Heading: Set and Inquire Functions
00054     void set( const double xv, const double yv, const double zv );
00055     //- Change vector components to {x}, {y}, and {z}
00056 
00057     void set( const double xyz[3] );
00058     //- Change vector components to xyz[0], xyz[1], xyz[2]
00059 
00060     void set( const VerdictVector& tail, const VerdictVector& head );
00061     //- Change vector to go from tail to head.
00062 
00063     void set( const VerdictVector& to_copy );
00064     //- Same as operator=(const VerdictVector&)
00065 
00066     double x() const;  //- Return x component of vector
00067 
00068     double y() const;  //- Return y component of vector
00069 
00070     double z() const;  //- Return z component of vector
00071 
00072     void get_xyz( double& x, double& y, double& z );  //- Get x, y, z components
00073     void get_xyz( double xyz[3] );                    //- Get xyz tuple
00074 
00075     double& r();  //- Return r component of vector, if (r,theta) format
00076 
00077     double& theta();  //- Return theta component of vector, if (r,theta) format
00078 
00079     void x( const double xv );  //- Set x component of vector
00080 
00081     void y( const double yv );  //- Set y component of vector
00082 
00083     void z( const double zv );  //- Set z component of vector
00084 
00085     void r( const double xv );  //- Set r component of vector, if (r,theta) format
00086 
00087     void theta( const double yv );  //- Set theta component of vector, if (r,theta) format
00088 
00089     void xy_to_rtheta();
00090     //- convert from cartesian to polar coordinates, just 2d for now
00091     //- theta is in [0,2 PI)
00092 
00093     void rtheta_to_xy();
00094     //- convert from  polar to cartesian coordinates, just 2d for now
00095 
00096     void scale_angle( double gamma, double );
00097     //- tranform_function.
00098     //- transform  (x,y) to (r,theta) to (r,gamma*theta) to (x',y')
00099     //- plus some additional scaling so long chords won't cross short ones
00100 
00101     void blow_out( double gamma, double gamma2 = 0.0 );
00102     //- transform_function
00103     //- blow points radially away from the origin,
00104 
00105     void rotate( double angle, double );
00106     //- transform function.
00107     //- transform  (x,y) to (r,theta) to (r,theta+angle) to (x',y')
00108 
00109     void reflect_about_xaxis( double dummy, double );
00110     //- dummy argument to make it a transform function
00111 
00112     double normalize();
00113     //- Normalize (set magnitude equal to 1) vector - return the magnitude
00114 
00115     VerdictVector& length( const double new_length );
00116     //- Change length of vector to {new_length}. Can be used to move a
00117     //- location a specified distance from the origin in the current
00118     //- orientation.
00119 
00120     double length() const;
00121     //- Calculate the length of the vector.
00122     //- Use {length_squared()} if only comparing lengths, not adding.
00123 
00124     double distance_between( const VerdictVector& test_vector );
00125     //- Calculate the distance from the head of one vector
00126     //  to the head of the test_vector.
00127 
00128     double length_squared() const;
00129     //- Calculate the squared length of the vector.
00130     //- Faster than {length()} since it eliminates the square root if
00131     //- only comparing other lengths.
00132 
00133     double interior_angle( const VerdictVector& otherVector );
00134     //- Calculate the interior angle: acos((a%b)/(|a||b|))
00135     //- Returns angle in degrees.
00136 
00137     double vector_angle_quick( const VerdictVector& vec1, const VerdictVector& vec2 );
00138     //- Calculate the interior angle between the projections of
00139     //- {vec1} and {vec2} onto the plane defined by the {this} vector.
00140     //- The angle returned is the right-handed angle around the {this}
00141     //- vector from {vec1} to {vec2}. Angle is in radians.
00142 
00143     double vector_angle( const VerdictVector& vector1, const VerdictVector& vector2 ) const;
00144     //- Compute the angle between the projections of {vector1} and {vector2}
00145     //- onto the plane defined by *this. The angle is the
00146     //- right-hand angle, in radians, about *this from {vector1} to {vector2}.
00147 
00148     void perpendicular_z();
00149     //- Transform this vector to a perpendicular one, leaving
00150     //- z-component alone. Rotates clockwise about the z-axis by pi/2.
00151 
00152     void print_me();
00153     //- Prints out the coordinates of this vector.
00154 
00155     void orthogonal_vectors( VerdictVector& vector2, VerdictVector& vector3 );
00156     //- Finds 2 (arbitrary) vectors that are orthogonal to this one
00157 
00158     void next_point( const VerdictVector& direction, double distance, VerdictVector& out_point );
00159     //- Finds the next point in space based on *this* point (starting point),
00160     //- a direction and the distance to extend in the direction. The
00161     //- direction vector need not be a unit vector.  The out_point can be
00162     //- "*this" (i.e., modify point in place).
00163 
00164     bool within_tolerance( const VerdictVector& vectorPtr2, double tolerance ) const;
00165     //- Compare two vectors to see if they are spatially equal.  They
00166     //- compare if x, y, and z are all within tolerance.
00167 
00168     //- Heading: Operator Overloads  *****************************
00169     VerdictVector& operator+=( const VerdictVector& vec );
00170     //- Compound Assignment: addition: {this = this + vec}
00171 
00172     VerdictVector& operator-=( const VerdictVector& vec );
00173     //- Compound Assignment: subtraction: {this = this - vec}
00174 
00175     VerdictVector& operator*=( const VerdictVector& vec );
00176     //- Compound Assignment: cross product: {this = this * vec},
00177     //- non-commutative
00178 
00179     VerdictVector& operator*=( const double scalar );
00180     //- Compound Assignment: multiplication: {this = this * scalar}
00181 
00182     VerdictVector& operator/=( const double scalar );
00183     //- Compound Assignment: division: {this = this / scalar}
00184 
00185     VerdictVector operator-() const;
00186     //- unary negation.
00187 
00188     friend VerdictVector operator~( const VerdictVector& vec );
00189     //- normalize. Returns a new vector which is a copy of {vec},
00190     //- scaled such that {|vec|=1}. Uses overloaded bitwise NOT operator.
00191 
00192     friend VerdictVector operator+( const VerdictVector& v1, const VerdictVector& v2 );
00193     //- vector addition
00194 
00195     friend VerdictVector operator-( const VerdictVector& v1, const VerdictVector& v2 );
00196     //- vector subtraction
00197 
00198     friend VerdictVector operator*( const VerdictVector& v1, const VerdictVector& v2 );
00199     //- vector cross product, non-commutative
00200 
00201     friend VerdictVector operator*( const VerdictVector& v1, const double sclr );
00202     //- vector * scalar
00203 
00204     friend VerdictVector operator*( const double sclr, const VerdictVector& v1 );
00205     //- scalar * vector
00206 
00207     friend double operator%( const VerdictVector& v1, const VerdictVector& v2 );
00208     //- dot product
00209 
00210     friend VerdictVector operator/( const VerdictVector& v1, const double sclr );
00211     //- vector / scalar
00212 
00213     friend int operator==( const VerdictVector& v1, const VerdictVector& v2 );
00214     //- Equality operator
00215 
00216     friend int operator!=( const VerdictVector& v1, const VerdictVector& v2 );
00217     //- Inequality operator
00218 
00219     friend VerdictVector interpolate( const double param, const VerdictVector& v1, const VerdictVector& v2 );
00220     //- Interpolate between two vectors. Returns (1-param)*v1 + param*v2
00221 
00222     VerdictVector& operator=( const VerdictVector& from );
00223 
00224   private:
00225     double xVal;  //- x component of vector.
00226     double yVal;  //- y component of vector.
00227     double zVal;  //- z component of vector.
00228 };
00229 
00230 VerdictVector vectorRotate( const double angle, const VerdictVector& normalAxis, const VerdictVector& referenceAxis );
00231 //- A new coordinate system is created with the xy plane corresponding
00232 //- to the plane normal to {normalAxis}, and the x axis corresponding to
00233 //- the projection of {referenceAxis} onto the normal plane.  The normal
00234 //- plane is the tangent plane at the root point.  A unit vector is
00235 //- constructed along the local x axis and then rotated by the given
00236 //- ccw angle to form the new point.  The new point, then is a unit
00237 //- distance from the global origin in the tangent plane.
00238 //- {angle} is in radians.
00239 
00240 inline double VerdictVector::x() const
00241 {
00242     return xVal;
00243 }
00244 inline double VerdictVector::y() const
00245 {
00246     return yVal;
00247 }
00248 inline double VerdictVector::z() const
00249 {
00250     return zVal;
00251 }
00252 inline void VerdictVector::get_xyz( double xyz[3] )
00253 {
00254     xyz[0] = xVal;
00255     xyz[1] = yVal;
00256     xyz[2] = zVal;
00257 }
00258 inline void VerdictVector::get_xyz( double& xv, double& yv, double& zv )
00259 {
00260     xv = xVal;
00261     yv = yVal;
00262     zv = zVal;
00263 }
00264 inline double& VerdictVector::r()
00265 {
00266     return xVal;
00267 }
00268 inline double& VerdictVector::theta()
00269 {
00270     return yVal;
00271 }
00272 inline void VerdictVector::x( const double xv )
00273 {
00274     xVal = xv;
00275 }
00276 inline void VerdictVector::y( const double yv )
00277 {
00278     yVal = yv;
00279 }
00280 inline void VerdictVector::z( const double zv )
00281 {
00282     zVal = zv;
00283 }
00284 inline void VerdictVector::r( const double xv )
00285 {
00286     xVal = xv;
00287 }
00288 inline void VerdictVector::theta( const double yv )
00289 {
00290     yVal = yv;
00291 }
00292 inline VerdictVector& VerdictVector::operator+=( const VerdictVector& vector )
00293 {
00294     xVal += vector.x();
00295     yVal += vector.y();
00296     zVal += vector.z();
00297     return *this;
00298 }
00299 
00300 inline VerdictVector& VerdictVector::operator-=( const VerdictVector& vector )
00301 {
00302     xVal -= vector.x();
00303     yVal -= vector.y();
00304     zVal -= vector.z();
00305     return *this;
00306 }
00307 
00308 inline VerdictVector& VerdictVector::operator*=( const VerdictVector& vector )
00309 {
00310     double xcross, ycross, zcross;
00311     xcross = yVal * vector.z() - zVal * vector.y();
00312     ycross = zVal * vector.x() - xVal * vector.z();
00313     zcross = xVal * vector.y() - yVal * vector.x();
00314     xVal   = xcross;
00315     yVal   = ycross;
00316     zVal   = zcross;
00317     return *this;
00318 }
00319 
00320 inline VerdictVector::VerdictVector( const VerdictVector& copy_from )
00321     : xVal( copy_from.xVal ), yVal( copy_from.yVal ), zVal( copy_from.zVal )
00322 {
00323 }
00324 
00325 inline VerdictVector::VerdictVector() : xVal( 0 ), yVal( 0 ), zVal( 0 ) {}
00326 
00327 inline VerdictVector::VerdictVector( const VerdictVector& tail, const VerdictVector& head )
00328     : xVal( head.xVal - tail.xVal ), yVal( head.yVal - tail.yVal ), zVal( head.zVal - tail.zVal )
00329 {
00330 }
00331 
00332 inline VerdictVector::VerdictVector( const double xIn, const double yIn, const double zIn )
00333     : xVal( xIn ), yVal( yIn ), zVal( zIn )
00334 {
00335 }
00336 
00337 // This sets the vector to be perpendicular to it's current direction.
00338 // NOTE:
00339 //      This is a 2D function.  It only works in the XY Plane.
00340 inline void VerdictVector::perpendicular_z()
00341 {
00342     double temp = x();
00343     x( y() );
00344     y( -temp );
00345 }
00346 
00347 inline void VerdictVector::set( const double xv, const double yv, const double zv )
00348 {
00349     xVal = xv;
00350     yVal = yv;
00351     zVal = zv;
00352 }
00353 
00354 inline void VerdictVector::set( const double xyz[3] )
00355 {
00356     xVal = xyz[0];
00357     yVal = xyz[1];
00358     zVal = xyz[2];
00359 }
00360 
00361 inline void VerdictVector::set( const VerdictVector& tail, const VerdictVector& head )
00362 {
00363     xVal = head.xVal - tail.xVal;
00364     yVal = head.yVal - tail.yVal;
00365     zVal = head.zVal - tail.zVal;
00366 }
00367 
00368 inline VerdictVector& VerdictVector::operator=( const VerdictVector& from )
00369 {
00370     xVal = from.xVal;
00371     yVal = from.yVal;
00372     zVal = from.zVal;
00373     return *this;
00374 }
00375 
00376 inline void VerdictVector::set( const VerdictVector& to_copy )
00377 {
00378     *this = to_copy;
00379 }
00380 
00381 // Scale all values by scalar.
00382 inline VerdictVector& VerdictVector::operator*=( const double scalar )
00383 {
00384     xVal *= scalar;
00385     yVal *= scalar;
00386     zVal *= scalar;
00387     return *this;
00388 }
00389 
00390 // Scales all values by 1/scalar
00391 inline VerdictVector& VerdictVector::operator/=( const double scalar )
00392 {
00393     assert( scalar != 0 );
00394     xVal /= scalar;
00395     yVal /= scalar;
00396     zVal /= scalar;
00397     return *this;
00398 }
00399 
00400 // Returns the normalized 'this'.
00401 inline VerdictVector operator~( const VerdictVector& vec )
00402 {
00403     double mag = sqrt( vec.xVal * vec.xVal + vec.yVal * vec.yVal + vec.zVal * vec.zVal );
00404 
00405     VerdictVector temp = vec;
00406     if( mag != 0.0 ) { temp /= mag; }
00407     return temp;
00408 }
00409 
00410 // Unary minus.  Negates all values in vector.
00411 inline VerdictVector VerdictVector::operator-() const
00412 {
00413     return VerdictVector( -xVal, -yVal, -zVal );
00414 }
00415 
00416 inline VerdictVector operator+( const VerdictVector& vector1, const VerdictVector& vector2 )
00417 {
00418     double xv = vector1.x() + vector2.x();
00419     double yv = vector1.y() + vector2.y();
00420     double zv = vector1.z() + vector2.z();
00421     return VerdictVector( xv, yv, zv );
00422     //  return VerdictVector(vector1) += vector2;
00423 }
00424 
00425 inline VerdictVector operator-( const VerdictVector& vector1, const VerdictVector& vector2 )
00426 {
00427     double xv = vector1.x() - vector2.x();
00428     double yv = vector1.y() - vector2.y();
00429     double zv = vector1.z() - vector2.z();
00430     return VerdictVector( xv, yv, zv );
00431     //  return VerdictVector(vector1) -= vector2;
00432 }
00433 
00434 // Cross products.
00435 // vector1 cross vector2
00436 inline VerdictVector operator*( const VerdictVector& vector1, const VerdictVector& vector2 )
00437 {
00438     return VerdictVector( vector1 ) *= vector2;
00439 }
00440 
00441 // Returns a scaled vector.
00442 inline VerdictVector operator*( const VerdictVector& vector1, const double scalar )
00443 {
00444     return VerdictVector( vector1 ) *= scalar;
00445 }
00446 
00447 // Returns a scaled vector
00448 inline VerdictVector operator*( const double scalar, const VerdictVector& vector1 )
00449 {
00450     return VerdictVector( vector1 ) *= scalar;
00451 }
00452 
00453 // Returns a vector scaled by 1/scalar
00454 inline VerdictVector operator/( const VerdictVector& vector1, const double scalar )
00455 {
00456     return VerdictVector( vector1 ) /= scalar;
00457 }
00458 
00459 inline int operator==( const VerdictVector& v1, const VerdictVector& v2 )
00460 {
00461     return ( v1.xVal == v2.xVal && v1.yVal == v2.yVal && v1.zVal == v2.zVal );
00462 }
00463 
00464 inline int operator!=( const VerdictVector& v1, const VerdictVector& v2 )
00465 {
00466     return ( v1.xVal != v2.xVal || v1.yVal != v2.yVal || v1.zVal != v2.zVal );
00467 }
00468 
00469 inline double VerdictVector::length_squared() const
00470 {
00471     return ( xVal * xVal + yVal * yVal + zVal * zVal );
00472 }
00473 
00474 inline double VerdictVector::length() const
00475 {
00476     return ( sqrt( xVal * xVal + yVal * yVal + zVal * zVal ) );
00477 }
00478 
00479 inline double VerdictVector::normalize()
00480 {
00481     double mag = length();
00482     if( mag != 0 )
00483     {
00484         xVal = xVal / mag;
00485         yVal = yVal / mag;
00486         zVal = zVal / mag;
00487     }
00488     return mag;
00489 }
00490 
00491 // Dot Product.
00492 inline double operator%( const VerdictVector& vector1, const VerdictVector& vector2 )
00493 {
00494     return ( vector1.x() * vector2.x() + vector1.y() * vector2.y() + vector1.z() * vector2.z() );
00495 }
00496 
00497 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines