Files Classes Functions Hierarchy
00001 #ifndef HALFSPACED2_H 00002 #define HALFSPACED2_H 00003 00004 #include <cassert> 00005 #include <sstream> 00006 using namespace std; 00007 00008 #include <typedefs.h> 00009 #include <partitionspace.h> 00010 #include <mathlib.h> 00011 #include <zero.h> 00012 00026 template< typename PT, typename PD > 00027 class halfspaceD2 : public partitionspace<PT> 00028 { 00029 public: 00030 00032 PT p0; 00034 PT p1; 00036 PT normal; 00037 00039 halfspaceD2() {} 00040 00044 halfspaceD2( PT const & p0_, PT const & p1_ ) 00045 { set(p0_,p1_); } 00048 void set( PT const & p0_, PT const & p1_ ); 00049 00050 // Problems with template, tried explicit copy constructor. 00051 // halfspaceD2( halfspaceD2<PT,PD> const & h) 00052 // : p0(h.p0), p1(h.p1), normal(h.normal) {} 00053 00055 void normalcalculate() 00056 { 00057 PT t(p1-p0); 00058 normal.x = -t.y; 00059 normal.y = t.x; 00060 } 00061 00063 boolc isInside( PT const & x ) const 00064 { return 0 < (x.x-p0.x)*normal.x + (x.y-p0.y)*normal.y; } 00065 00067 boolc isInsideOrOnBoundary( PT const & x ) const 00068 { return 0 < zero<PD>::val+(x.x-p0.x)*normal.x + (x.y-p0.y)*normal.y; } 00069 //{ return 0 < zero+(x.x-p0.x)*normal.x + (x.y-p0.y)*normal.y; } 00070 00072 template< typename U > 00073 void pointOnLine 00074 ( 00075 PT & x, 00076 U const t 00077 ) const 00078 { x = p0 + (p1-p0)*t; } 00079 00081 boolc intersectionIn_t 00082 ( 00083 PT & t, 00084 PT const & a, 00085 PT const & b 00086 ) const; 00087 00090 boolc intersection 00091 ( 00092 PT & p, 00093 PT const & a, 00094 PT const & b 00095 ) const; 00096 00099 boolc isOnBoundary(PT const & w) const 00100 { 00101 PD x = (p1.y-p0.y)*(w.x-p0.x) - (p1.x-p0.x)*(w.y-p0.y); 00102 if ( 0 < (x + zero<PD>::val) ) 00103 { 00104 if (x < zero<PD>::val) 00105 return true; 00106 } 00107 00108 return false; 00109 } 00110 00114 boolc clip( PD & t0, PD & t1, PT const & a, PT const & m ) const; 00115 00117 boolc clipNeg( PD & t0, PD & t1, PT const & a, PT const & m ) const; 00118 00120 void minimizepointtoline(PD & t, PT const & w) const 00121 { 00122 PT z(p1-p0); 00123 t=((w.x-p0.x)*z.x+(w.y-p0.y)*z.y)/(z.x*z.x+z.y*z.y); 00124 } 00125 00128 PD const distancefromhalfspace(PT const & w) const; 00129 00131 operator stringc () const 00132 { stringstream ss; ss << p0 << " " << p1; return ss.str(); } 00133 00135 stringc print() const 00136 { 00137 stringstream ss; 00138 ss << SHOW(p0) << " " << SHOW(p1) << " " << SHOW(normal); 00139 return ss.str(); 00140 } 00141 00142 }; 00143 00144 //--------------------------------------------------------- 00145 // Implementation. 00146 00147 template< typename PT, typename PD > 00148 PD const halfspaceD2<PT,PD>::distancefromhalfspace(PT const & w) const 00149 { 00150 PD t; 00151 minimizepointtoline(t,w); 00152 PT w2; 00153 pointOnLine(w2,t); 00154 PT w3(w2.x-w.x,w2.y-w.y); 00155 return w3.x*w3.x+w3.y*w3.y; 00156 } 00157 00158 00159 00160 template< typename PT, typename PD > 00161 void halfspaceD2<PT,PD>::set( PT const & p0_, PT const & p1_ ) 00162 { 00163 p0 = p0_; 00164 p1 = p1_; 00165 normalcalculate(); 00166 } 00167 00168 template< typename PT, typename PD > 00169 boolc halfspaceD2<PT,PD>::intersection 00170 ( 00171 PT & p, 00172 PT const & a, 00173 PT const & b 00174 ) const 00175 { 00176 PT const u(b-a); 00177 PT const v(p0-p1); 00178 PT const w(p0-a); 00179 // t0*u+t1*v=w 00180 PT t; 00181 bool res = d2matsolve(t,u,v,w); 00182 if (res==false) 00183 return false; 00184 00185 pointOnLine(p,t.y); 00186 00187 return true; 00188 } 00189 00190 template< typename PT, typename PD > 00191 boolc halfspaceD2<PT,PD>::intersectionIn_t 00192 ( 00193 PT & t, 00194 PT const & a, 00195 PT const & b 00196 ) const 00197 { 00198 PT const u(b-a); 00199 PT const v(p0-p1); 00200 PT const w(p0-a); 00201 // t0*u+t1*v=w 00202 00203 return d2matsolve(t,u,v,w); 00204 } 00205 00206 template< typename PT, typename PD > 00207 boolc halfspaceD2<PT,PD>::clipNeg 00208 ( 00209 PD & t0, 00210 PD & t1, 00211 PT const & a, 00212 PT const & m 00213 ) const 00214 { 00215 00216 int k=0; 00217 if (!isInside(a+m*t0)) 00218 k += 1; 00219 if (!isInside(a+m*t1)) 00220 k += 2; 00221 00222 switch (k) 00223 { 00224 case 0: return false; 00225 case 1: 00226 { 00227 point2<PD> t; 00228 if ( solver<PD>::d2linearequ(t,m,p0-p1,p0-a) == false ) 00229 return !isInside(a); 00230 t1=t[0]; 00231 break; 00232 } 00233 case 2: 00234 { 00235 point2<PD> t; 00236 if ( solver<PD>::d2linearequ(t,m,p0-p1,p0-a) == false ) 00237 return !isInside(a); 00238 t0=t[0]; 00239 break; 00240 } 00241 case 3: return true; 00242 } 00243 00244 return true; 00245 } 00246 00247 00248 template< typename PT, typename PD > 00249 boolc halfspaceD2<PT,PD>::clip 00250 ( 00251 PD & t0, 00252 PD & t1, 00253 PT const & a, 00254 PT const & m 00255 ) const 00256 { 00257 int k=0; 00258 if (isInside(a+m*t0)) 00259 k += 1; 00260 if (isInside(a+m*t1)) 00261 k += 2; 00262 00263 switch (k) 00264 { 00265 case 0: return false; 00266 case 1: 00267 { 00268 point2<PD> t; 00269 if ( solver<PD>::d2linearequ(t,m,p0-p1,p0-a) == false ) 00270 return isInside(a); 00271 t1=t[0]; 00272 break; 00273 } 00274 case 2: 00275 { 00276 point2<PD> t; 00277 if ( solver<PD>::d2linearequ(t,m,p0-p1,p0-a) == false ) 00278 return isInside(a); 00279 t0=t[0]; 00280 break; 00281 } 00282 case 3: return true; 00283 } 00284 00285 return true; 00286 } 00287 00288 00289 00290 #endif 00291 00292
1.5.8