00001
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
00014
00015
00016
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
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;
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
00052
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
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 Vector dir = n1().cross(axis());
00078
00079
00080
00081
00082
00083 double n = dir*n2();
00084 if (n<0)
00085 dir = -dir;
00086
00087
00088
00089 n = r*dir;
00090
00091 return (n>0)? d1:-line;
00092
00093 }
00094 else if (pl1 && !pl2)
00095 {
00096
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
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;
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