![]() |
Mesh Oriented datABase
(version 5.4.1)
Array-based unstructured mesh datastructure
|
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
00028 #include
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 )
00407 {
00408 temp /= mag;
00409 }
00410 return temp;
00411 }
00412
00413 // Unary minus. Negates all values in vector.
00414 inline VerdictVector VerdictVector::operator-() const
00415 {
00416 return VerdictVector( -xVal, -yVal, -zVal );
00417 }
00418
00419 inline VerdictVector operator+( const VerdictVector& vector1, const VerdictVector& vector2 )
00420 {
00421 double xv = vector1.x() + vector2.x();
00422 double yv = vector1.y() + vector2.y();
00423 double zv = vector1.z() + vector2.z();
00424 return VerdictVector( xv, yv, zv );
00425 // return VerdictVector(vector1) += vector2;
00426 }
00427
00428 inline VerdictVector operator-( const VerdictVector& vector1, const VerdictVector& vector2 )
00429 {
00430 double xv = vector1.x() - vector2.x();
00431 double yv = vector1.y() - vector2.y();
00432 double zv = vector1.z() - vector2.z();
00433 return VerdictVector( xv, yv, zv );
00434 // return VerdictVector(vector1) -= vector2;
00435 }
00436
00437 // Cross products.
00438 // vector1 cross vector2
00439 inline VerdictVector operator*( const VerdictVector& vector1, const VerdictVector& vector2 )
00440 {
00441 return VerdictVector( vector1 ) *= vector2;
00442 }
00443
00444 // Returns a scaled vector.
00445 inline VerdictVector operator*( const VerdictVector& vector1, const double scalar )
00446 {
00447 return VerdictVector( vector1 ) *= scalar;
00448 }
00449
00450 // Returns a scaled vector
00451 inline VerdictVector operator*( const double scalar, const VerdictVector& vector1 )
00452 {
00453 return VerdictVector( vector1 ) *= scalar;
00454 }
00455
00456 // Returns a vector scaled by 1/scalar
00457 inline VerdictVector operator/( const VerdictVector& vector1, const double scalar )
00458 {
00459 return VerdictVector( vector1 ) /= scalar;
00460 }
00461
00462 inline int operator==( const VerdictVector& v1, const VerdictVector& v2 )
00463 {
00464 return ( v1.xVal == v2.xVal && v1.yVal == v2.yVal && v1.zVal == v2.zVal );
00465 }
00466
00467 inline int operator!=( const VerdictVector& v1, const VerdictVector& v2 )
00468 {
00469 return ( v1.xVal != v2.xVal || v1.yVal != v2.yVal || v1.zVal != v2.zVal );
00470 }
00471
00472 inline double VerdictVector::length_squared() const
00473 {
00474 return ( xVal * xVal + yVal * yVal + zVal * zVal );
00475 }
00476
00477 inline double VerdictVector::length() const
00478 {
00479 return ( sqrt( xVal * xVal + yVal * yVal + zVal * zVal ) );
00480 }
00481
00482 inline double VerdictVector::normalize()
00483 {
00484 double mag = length();
00485 if( mag != 0 )
00486 {
00487 xVal = xVal / mag;
00488 yVal = yVal / mag;
00489 zVal = zVal / mag;
00490 }
00491 return mag;
00492 }
00493
00494 // Dot Product.
00495 inline double operator%( const VerdictVector& vector1, const VerdictVector& vector2 )
00496 {
00497 return ( vector1.x() * vector2.x() + vector1.y() * vector2.y() + vector1.z() * vector2.z() );
00498 }
00499
00500 #endif