Files Classes Functions Hierarchy
00001 #ifndef TRIANGLE3D_H 00002 #define TRIANGLE3D_H 00003 00004 #include <line.h> 00005 00013 template< typename PT, typename PD > 00014 class triangle3D 00015 { 00016 public: 00017 00018 typedef PT PTtype; 00019 typedef PD PDtype; 00020 00022 PT pi[3]; 00023 00025 triangle3D() {} 00027 triangle3D 00028 ( 00029 PT const & p0_, 00030 PT const & p1_, 00031 PT const & p2_ 00032 ); 00034 void construct 00035 ( 00036 PT const & p0_, 00037 PT const & p1_, 00038 PT const & p2_ 00039 ); 00040 00043 void bisectangle(PT & x, uintc i) const; 00044 00046 void centroid(PT & x) const; 00047 00049 void circumcenter(PT & x) const; 00050 00053 void equilaterali(PT & x, uint i) const; 00054 00057 void fermatpoint(PT & x) const; 00058 00060 void gergonnepoint(PT & x) const; 00061 00063 void incenter(PT & x) const; 00065 void incenteri(PT & x, uint i) const; 00066 00068 //template< typename U > 00069 void innercircle 00070 ( 00071 PD & radius, 00072 PT & center, 00073 PT & circlenormal 00074 ) const; 00075 00077 void midpoint(PT& x, uintc i) const; 00078 00082 void napoleanpoint(PT & x) const; 00083 00085 void normali(PT & x, uintc i) const; 00086 00090 void orthocenteri(PT & x, uintc i) const; 00092 void orthocenter(PT & x) const; 00093 00095 template< typename U > 00096 void normal(U & w) const 00097 { crossproduct::evalxyz(w, pi[1]-pi[0], pi[2]-pi[0]); } 00098 00100 template< typename U > 00101 void outercircle 00102 ( 00103 PD & radius, 00104 U & center, 00105 U & circlenormal 00106 ) const; 00107 00109 boolc valid() const; 00110 00111 00112 00113 }; 00114 00115 //template< typename PT, typename PD > 00116 //typedef void triangle3D<PT,PD>::pcenterfn(PT &) const; 00117 00118 00119 //--------------------------------------------------------- 00120 // Implementation 00121 00122 00123 template< typename PT, typename PD > 00124 template< typename U > 00125 void triangle3D<PT,PD>::outercircle 00126 ( 00127 PD & radius, 00128 U & center, 00129 U & circlenormal 00130 ) const 00131 { 00132 circumcenter(center); 00133 radius = (center-pi[0]).distance(); 00134 normal(circlenormal); 00135 } 00136 00137 template< typename PT, typename PD > 00138 void triangle3D<PT,PD>::normali(PT & x, uintc i) const 00139 { 00140 switch(i) 00141 { 00142 case 0: 00143 crossproduct::evalxyz(x, pi[2]-pi[1], pi[0]-pi[2]); break; 00144 00145 case 1: 00146 crossproduct::evalxyz(x, pi[0]-pi[2], pi[1]-pi[0]); break; 00147 00148 case 2: 00149 crossproduct::evalxyz(x, pi[1]-pi[0], pi[2]-pi[1] ); break; 00150 00151 default: 00152 assert(false); 00153 } 00154 } 00155 00156 template< typename PT, typename PD > 00157 void triangle3D<PT,PD>::orthocenteri(PT & x, uintc i) const 00158 { 00159 assert(i<3); 00160 00161 PT w0(pi[(i+1)%3]); 00162 PT w(pi[(i+2)%3]-w0); 00163 PT nml; 00164 normal(nml); 00165 //cout << SHOW(nml) << endl; 00166 PT m1; 00167 crossproduct::evalxyz(m1, w, nml); 00168 //cout << SHOW(m1) << endl; 00169 00170 PT t; 00171 asserteval(d2matsolve3D(t,m1,w*-1.0,w0-pi[i])); 00172 00173 x = pi[i] + m1*t.x; 00174 } 00175 00176 template< typename PT, typename PD > 00177 void triangle3D<PT,PD>::centroid(PT & x) const 00178 { 00179 x = pi[0]; 00180 x += pi[1]; 00181 x += pi[2]; 00182 x /= 3.0; 00183 } 00184 00185 template< typename PT, typename PD > 00186 void triangle3D<PT,PD>::circumcenter(PT & x) const 00187 { 00188 //x =(G*3.0-H)*0.5; 00189 centroid(x); 00190 x *= 3.0; 00191 PT H; 00192 orthocenter(H); 00193 x -= H; 00194 x *= 0.5; 00195 } 00196 00197 template< typename PT, typename PD > 00198 void triangle3D<PT,PD>::construct 00199 ( 00200 PT const & p0_, 00201 PT const & p1_, 00202 PT const & p2_ 00203 ) 00204 { 00205 pi[0] = p0_; 00206 pi[1] = p1_; 00207 pi[2] = p2_; 00208 00209 valid(); 00210 } 00211 00212 template< typename PT, typename PD > 00213 triangle3D<PT,PD>::triangle3D 00214 ( 00215 PT const & p0_, 00216 PT const & p1_, 00217 PT const & p2_ 00218 ) 00219 { 00220 construct(p0_,p1_,p2_); 00221 } 00222 00223 template< typename PT, typename PD > 00224 boolc triangle3D<PT,PD>::valid() const 00225 { 00226 return true; 00227 } 00228 00229 template< typename PT, typename PD > 00230 void triangle3D<PT,PD>::equilaterali(PT & x, uint i) const 00231 { 00232 PT g; 00233 PT n1; 00234 switch(i) 00235 { 00236 case 0: 00237 g = (pi[2]+pi[1])*0.5; 00238 n1=pi[2]-pi[1]; 00239 break; 00240 case 1: 00241 g = (pi[2]+pi[0])*0.5; 00242 n1=pi[0]-pi[2]; 00243 break; 00244 case 2: 00245 g = (pi[0]+pi[1])*0.5; 00246 n1=pi[1]-pi[0]; 00247 break; 00248 default: 00249 assert(false); 00250 } 00251 PT nml; 00252 normal(nml); 00253 PT n2; 00254 crossproduct::evalxyz(n2,n1,nml); 00255 assert(n2.distance()!=0); 00256 n2 /= n2.distance(); 00257 x = g+n2*sqrt(3.0)*0.5*n1.distance(); 00258 } 00259 00260 template< typename PT, typename PD > 00261 void triangle3D<PT,PD>::orthocenter(PT & x) const 00262 { 00263 PT t; 00264 PT p0w; 00265 orthocenteri(p0w,0); 00266 //cout << SHOW(p0w) << endl; 00267 PT p1w; 00268 orthocenteri(p1w,1); 00269 //cout << SHOW(p1w) << endl; 00270 00271 d2matsolve3D(t, p0w-pi[0], pi[1]-p1w, pi[1]-pi[0]); 00272 00273 x = pi[0] + (p0w-pi[0])*t.x; 00274 } 00275 00276 template< typename PT, typename PD > 00277 void triangle3D<PT,PD>::napoleanpoint(PT & x) const 00278 { 00279 PT e0; 00280 equilaterali(e0,0); 00281 PT e1; 00282 equilaterali(e1,1); 00283 00284 PD a(1.0); 00285 a /= PD(3.0); 00286 00287 PT c0(e0); 00288 c0 += pi[1]; 00289 c0 += pi[2]; 00290 c0 *= a; 00291 00292 PT c1(e1); 00293 c1 += pi[0]; 00294 c1 += pi[2]; 00295 c1 *= a; 00296 00297 PT t; 00298 d2matsolve3D(t, pi[1]-c1, c0-pi[0], c0-c1); 00299 00300 x = c1 + (pi[1]-c1)*t.x; 00301 } 00302 00303 template< typename PT, typename PD > 00304 void triangle3D<PT,PD>::fermatpoint(PT & x) const 00305 { 00306 PT c0; 00307 equilaterali(c0,0); 00308 PT c1; 00309 equilaterali(c1,1); 00310 00311 PT t; 00312 d2matsolve3D(t, pi[1]-c1, c0-pi[0], c0-c1); 00313 00314 x = c1 + (pi[1]-c1)*t.x; 00315 } 00316 00317 template< typename PT, typename PD > 00318 void triangle3D<PT,PD>::bisectangle(PT & x, uintc i) const 00319 { 00320 PT A,B; 00321 PT X; 00322 00323 switch(i) 00324 { 00325 case 0: 00326 A = pi[1]; 00327 B = pi[2]; 00328 X = pi[0]; 00329 break; 00330 00331 case 1: 00332 A = pi[0]; 00333 B = pi[2]; 00334 X = pi[1]; 00335 break; 00336 00337 case 2: 00338 A = pi[1]; 00339 B = pi[0]; 00340 X = pi[2]; 00341 break; 00342 00343 default: 00344 assert(false); 00345 } 00346 00347 PD a = (A-X).distance(); 00348 PD b = (B-X).distance(); 00349 00350 x = (A*b+B*a)/(a+b); 00351 } 00352 00353 template< typename PT, typename PD > 00354 void triangle3D<PT,PD>::midpoint(PT & x, uintc i) const 00355 { 00356 switch(i) 00357 { 00358 case 0: 00359 x=pi[1]; x += pi[2]; 00360 break; 00361 00362 case 1: 00363 x=pi[0]; x += pi[2]; 00364 break; 00365 00366 case 2: 00367 x=pi[1]; x += pi[0]; 00368 break; 00369 00370 default: 00371 assert(false); 00372 } 00373 00374 x *= 0.5; 00375 } 00376 00377 template< typename PT, typename PD > 00378 void triangle3D<PT,PD>::gergonnepoint(PT & x) const 00379 { 00380 PT c0; 00381 incenteri(c0,0); 00382 PT c1; 00383 incenteri(c1,1); 00384 00385 PT t; 00386 d2matsolve3D(t,pi[0]-c0,c1-pi[1],c1-c0); 00387 00388 x = c0 + (pi[0]-c0)*t.x; 00389 } 00390 00391 template< typename PT, typename PD > 00392 void triangle3D<PT,PD>::incenter(PT & x) const 00393 { 00394 PT b0; 00395 bisectangle(b0,0); 00396 PT b1; 00397 bisectangle(b1,1); 00398 00399 PT v; // The two variables. 00400 d2matsolve3D 00401 ( 00402 v, 00403 b0 - pi[0], pi[1] - b1, 00404 pi[1] - pi[0] 00405 ); 00406 00407 x = pi[0]+(b0-pi[0])*v.x; 00408 } 00409 00410 template< typename PT, typename PD > 00411 void triangle3D<PT,PD>::incenteri(PT & x, uintc i) const 00412 { 00413 PT q; 00414 incenter(q); 00415 00416 switch(i) 00417 { 00418 case 0: line<PT,PD>::nearestpointonline(x,q,pi[1],pi[2]-pi[1]); break; 00419 case 1: line<PT,PD>::nearestpointonline(x,q,pi[2],pi[0]-pi[2]); break; 00420 case 2: line<PT,PD>::nearestpointonline(x,q,pi[0],pi[1]-pi[0]); break; 00421 00422 default: assert(false); 00423 } 00424 } 00425 00426 template< typename PT, typename PD > 00427 void triangle3D<PT,PD>::innercircle 00428 ( 00429 PD & radius, 00430 PT & center, 00431 PT & circlenormal 00432 ) const 00433 { 00434 incenter(center); 00435 00436 PT w; 00437 line<PT,PD>::nearestpointonline(w,center,pi[0],pi[1]-pi[0]); 00438 //cout << SHOW(w) << endl; 00439 w -= center; 00440 00441 radius = w.distance(); 00442 00443 normal(circlenormal); 00444 /* 00445 cout << SHOW(pi[0]) << " "; 00446 cout << SHOW(pi[1]) << " "; 00447 cout << SHOW(pi[2]) << " "; 00448 cout << endl; 00449 cout << SHOW(radius) << endl; 00450 cout << SHOW(center) << endl; 00451 cout << SHOW(circlenormal) << endl; 00452 */ 00453 } 00454 00455 #endif 00456
1.5.8