Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Wedge.cxx

Go to the documentation of this file.
00001 // Wedge.cxx,v 2.1 1995/05/17 23:54:13 burnett Exp
00002 //
00003 
00004 #include "geometry/Wedge.h"
00005 #include <cfloat>
00006 
00007 Wedge::Wedge(const Point& center, const Vector& axis,  double phi1, double phi2)
00008 :Surface(center, axis )
00009 , _n1( sin(phi1),-cos(phi1), 0)
00010 , _n2(-sin(phi2), cos(phi2), 0)
00011 , dphi(phi2-phi1)
00012 {
00013     // constructor: inside is from phi1 to phi2  ?
00014 
00015     // phi1 is angle from x-axis to first plane
00016     // phi2 is angle from x-axis to second plane
00017         if ( ( phi2 < phi1 ) || ( phi2 >= ( phi1 + 2*M_PI ) ) )
00018           FATAL("Bad parameters for a Wedge");
00019 
00020 }
00021 
00022 const Vector&
00023 Wedge::n1() const {   return _n1; }
00024 
00025 const Vector&
00026 Wedge::n2() const {   return _n2; }
00027 
00028 double
00029 Wedge::how_near( const Point& x ) const
00030 {
00031 
00032     // Initializes planes to test
00033     Plane plane1(origin(), n1(), 0),
00034           plane2(origin(), n2(), 0);
00035 
00036     double d1 = plane1.how_near(x),
00037            d2 = plane2.how_near(x),
00038            line; // distance from the intersection line
00039 
00040     Vector r = x-origin(),
00041            rperp = r - (r*axis())*axis();
00042 
00043     line = rperp.mag();
00044 
00045     int type = (dphi <= M_PI),
00046         pl1  = (d1 > 0),
00047         pl2  = (d2 > 0);
00048 
00049    if (type)
00050    {
00051        // four possibilities: Point is in front of both, behind both,
00052        // or in front of one and not the other(2x)
00053        if (pl1 && pl2)
00054        {
00055            return (d1>d2)? d2:d1;
00056        }
00057        else if (!pl1 && !pl2)
00058        {
00059            return -line;
00060        }
00061        else if (!pl1 && pl2)
00062        {
00063           // Now it gets tricky...
00064 
00065           // distance will not always be the shortest distance of line and plane,
00066           // because only a certain region of the plane exists.
00067           // To decide which to use, we must determine if the point x
00068           // is over the existant part of the plane, or the non-existant part.
00069           // The point will be over the existant part if some vector
00070           // if it lies in front of a plane A that is perpendicular to
00071           // plane1, intersects at the intersection line, and faces the existant
00072           // part of plane1.
00073 
00074           // step 1: find an arbitrary vector that is perpendicular to
00075           // both the normal of 1 and the axis
00076 
00077           Vector dir = n1().cross(axis());
00078 
00079           // Now we need to see if this vector is in the right direction.
00080           // This vector should be the sAme direction as the other normal
00081           // If not, reverse it
00082           // NOte: If dphi > M_PI, then it is reverse of the other normal
00083           double n = dir*n2();
00084           if (n<0)
00085              dir = -dir;
00086 
00087           // Now dir is prepared.
00088 
00089           n = r*dir; // Is r the same direction as n?
00090 
00091           return (n>0)? d1:-line; // If it is, then the distance t the plane is correct.
00092                                 // because it lies over the existant part of the plane
00093        }
00094        else if (pl1 && !pl2)
00095        {
00096           // Same as the procedure above
00097           Vector dir = n2().cross(axis());
00098 
00099           double n = dir*n1();
00100 
00101           if (n<0)
00102              dir = -dir;
00103 
00104           n = r*dir;
00105 
00106           return (n>0)? d2:-line;
00107        }
00108    }
00109    else // this means dphi > M_PI
00110    {
00111        if (pl1 && pl2)
00112        {
00113           return line;
00114        }
00115        else if (!pl1 && !pl2)
00116        {
00117           return (d1>d2)? d2:d1;
00118        }
00119        else if (!pl1 && pl2)
00120        {
00121           Vector dir = n2().cross(axis());
00122 
00123           double n = dir*n1();
00124 
00125           if (n>0)
00126              dir = -dir;
00127 
00128           n = r*dir;
00129 
00130           return (n>0)? d2:line; // Remember: return value must be positive because it is out
00131        }
00132        else if (pl1 && !pl2)
00133        {
00134           Vector dir = n1().cross(axis());
00135 
00136           double n = dir*n2();
00137 
00138           if (n>0)
00139              dir = -dir;
00140 
00141 
00142           n = r*dir;
00143 
00144           return (n>0)? d1:line;
00145        }
00146 
00147     }
00148    return(FLT_MAX);
00149 }
00150 
00151 
00152 double
00153 Wedge::distance(const Point& x, const Vector& v, int inout)const
00154 {
00155 
00156   Plane p[]={Plane(origin(), n1(), 0),
00157              Plane(origin(), n2(), 0)};
00158 
00159   double d[] ={ p[0].distance(x,v,inout),
00160                 p[1].distance(x,v,inout) };
00161 
00162   if( d[0]==FLT_MAX && d[1]==FLT_MAX )
00163      return FLT_MAX;
00164 
00165   unsigned solution = d[0]<d[1]?0:1;
00166   double dist = d[solution];
00167 
00168   if( dphi< M_PI )
00169   {
00170     Point hit(x);
00171     hit += dist*v;
00172     if( p[1-solution].inside(hit) )
00173       return dist;
00174     else
00175       return FLT_MAX;
00176   }
00177   return FLT_MAX;
00178 }
00179 
00180 Vector
00181 Wedge::normal( const Point& x )const
00182 {
00183 
00184     Plane p[]={Plane(origin(), n1(), 0),
00185              Plane(origin(), n2(), 0)};
00186 
00187     double d[] ={ p[0].how_near(x),
00188                 p[1].how_near(x) };
00189 
00190     return fabs(d[0])<fabs(d[1]) ? n1() : n2() ;
00191 }
00192 
00193 
00194 
00195 
00196 
00197 
00198 

Generated at Mon Nov 26 18:18:22 2001 by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000