moab
measure.cpp
Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 2005 Lawrence Livermore National Laboratory under
00003  * contract number B545069 with the University of Wisconsin - Madison.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  *
00014  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00015  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00016  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00017  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00018  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00019  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00020  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00021  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00022  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00023  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00024  */
00025 
00026 #include <math.h>
00027 
00028 #include "measure.hpp"
00029 
00030 class CartVect {
00031   private:
00032     double coords[3];
00033     
00034   public:
00035   
00036     inline CartVect() {}
00037     
00038     inline CartVect( double tx, double ty, double tz ) { set(tx,ty,tz); }
00039     
00040     inline CartVect( const CartVect& other ) { set( other.coords); }
00041     
00042     inline void set( double tx, double ty, double tz )
00043       { coords[0] = tx; coords[1] = ty; coords[2] = tz; }
00044     
00045     inline void set( const double* c )
00046       { coords[0] = c[0]; coords[1] = c[1]; coords[2] = c[2]; }
00047     
00048     inline double x() const { return coords[0]; }
00049     inline double y() const { return coords[1]; }
00050     inline double z() const { return coords[2]; }
00051   
00052     inline CartVect& operator+=( const CartVect& other )
00053     {
00054       coords[0] += other.coords[0];
00055       coords[1] += other.coords[1];
00056       coords[2] += other.coords[2];
00057       return *this;
00058     }
00059     
00060     inline CartVect& operator-=( const CartVect& other )
00061     {
00062       coords[0] -= other.coords[0];
00063       coords[1] -= other.coords[1];
00064       coords[2] -= other.coords[2];
00065       return *this;
00066     }
00067     
00068     inline CartVect& operator*=( const CartVect& other );
00069 
00070     inline double lensqr() const;
00071     
00072     inline double len() const;
00073     
00074     inline CartVect operator~( ) const;
00075 
00076       
00077     inline CartVect& operator*=( double a )
00078     {
00079       coords[0] *= a;
00080       coords[1] *= a;
00081       coords[2] *= a;
00082       return *this;
00083     }
00084     
00085     inline CartVect& operator/=( double a )
00086     {
00087       coords[0] /= a;
00088       coords[1] /= a;
00089       coords[2] /= a;
00090       return *this;
00091     }
00092    
00093     
00094 };
00095 
00096 inline CartVect operator+( const CartVect& v1, const CartVect& v2 )
00097 {
00098   CartVect rval(v1);
00099   rval += v2;
00100   return rval;
00101 }
00102 
00103 inline CartVect operator-( const CartVect& v1, const CartVect& v2 )
00104 {
00105   CartVect rval(v1);
00106   rval -= v2;
00107   return rval;
00108 }
00109 
00110 inline double operator%( const CartVect& v1, const CartVect& v2 )
00111 {
00112   return v1.x() * v2.x() + v1.y() * v2.y() + v1.z() * v2.z();
00113 }
00114 
00115 inline CartVect operator*( const CartVect& v1, const CartVect& v2 )
00116 {
00117   return CartVect( v1.y() * v2.z() - v1.z() * v2.y(),
00118                    v1.z() * v2.x() - v1.x() * v2.z(),
00119                    v1.x() * v2.y() - v1.y() * v2.x() );
00120 }
00121 
00122 inline CartVect CartVect::operator~() const
00123 {
00124   double invlen = 1.0 / len();
00125   return CartVect( invlen * x(), invlen * y(), invlen * z() );
00126 }
00127      
00128 inline CartVect& CartVect::operator*=( const CartVect& other )
00129       { return *this = *this * other; }
00130 
00131 inline double CartVect::lensqr() const
00132       { return *this % *this; }
00133     
00134 inline double CartVect::len() const
00135       { return sqrt(lensqr()); }
00136  
00137 inline static double tet_volume( const CartVect& v0,
00138                                  const CartVect& v1,
00139                                  const CartVect& v2, 
00140                                  const CartVect& v3 )
00141 {
00142   return 1./6. * ( ((v1 - v0) * (v2 - v0)) % (v3 - v0) );
00143 }
00144 
00145 double edge_length( const double* start_vtx_coords,
00146                     const double*   end_vtx_coords )
00147 {
00148   const CartVect* start = reinterpret_cast<const CartVect*>(start_vtx_coords);
00149   const CartVect*   end = reinterpret_cast<const CartVect*>(  end_vtx_coords);
00150   return (*start - *end).len();
00151 }
00152 
00153 double measure( moab::EntityType type,
00154                 int num_vertices,
00155                 const double* vertex_coordinates )
00156 {
00157   const CartVect* coords = reinterpret_cast<const CartVect*>(vertex_coordinates);
00158   switch( type )
00159   {
00160     case moab::MBEDGE:
00161       return (coords[0] - coords[1]).len();
00162     case moab::MBTRI:
00163       return 0.5 * ((coords[1] - coords[0]) * (coords[2] - coords[0])).len();
00164     case moab::MBQUAD:
00165       num_vertices = 4;
00166     case moab::MBPOLYGON:
00167     {
00168       CartVect mid(0,0,0);
00169       for (int i = 0; i < num_vertices; ++i)
00170         mid += coords[i];
00171       mid /= num_vertices;
00172       
00173       double sum = 0.0;
00174       for (int i = 0; i < num_vertices; ++i)
00175       {
00176         int j = (i+1)%num_vertices;
00177         sum += ((mid - coords[i]) * (mid - coords[j])).len();
00178       }
00179       return 0.5 * sum;
00180     }
00181     case moab::MBTET:
00182       return tet_volume( coords[0], coords[1], coords[2], coords[3] ) ;
00183     case moab::MBPYRAMID:
00184       return tet_volume( coords[0], coords[1], coords[2], coords[4] ) +
00185              tet_volume( coords[0], coords[2], coords[3], coords[4] ) ;
00186     case moab::MBPRISM:
00187       return tet_volume( coords[0], coords[1], coords[2], coords[5] ) +
00188              tet_volume( coords[3], coords[5], coords[4], coords[0] ) +
00189              tet_volume( coords[1], coords[4], coords[5], coords[0] ) ;
00190     case moab::MBHEX:
00191       return tet_volume( coords[0], coords[1], coords[3], coords[4] ) +
00192              tet_volume( coords[7], coords[3], coords[6], coords[4] ) +
00193              tet_volume( coords[4], coords[5], coords[1], coords[6] ) +
00194              tet_volume( coords[1], coords[6], coords[3], coords[4] ) +
00195              tet_volume( coords[2], coords[6], coords[3], coords[1] ) ;
00196     default:
00197       return 0.0;
00198   }
00199 }
00200       
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines