Files Classes Functions Hierarchy
00001 #ifndef TRIANGLE_H 00002 #define TRIANGLE_H 00003 00004 #include <cassert> 00005 using namespace std; 00006 00007 #include <line.h> 00008 #include <mathlib.h> 00009 #include <typedefs.h> 00010 00024 template< typename PT, typename PD > 00025 class triangle 00026 { 00027 public: 00028 00029 typedef PT PTtype; 00030 typedef PD PDtype; 00031 00033 PT pi[3]; 00034 00036 triangle() {} 00038 triangle 00039 ( 00040 PT const & p0, 00041 PT const & p1, 00042 PT const & p2 00043 ); 00045 void construct 00046 ( 00047 PT const & p0, 00048 PT const & p1, 00049 PT const & p2 00050 ); 00051 00053 void constructUnordered 00054 ( 00055 PT const & p0, 00056 PT const & p1, 00057 PT const & p2 00058 ); 00059 00062 void bisectangle(PT & x, uintc i) const; 00063 00065 void centroid(PT & x) const; 00066 00068 void circumcenter(PT & x) const; 00069 00071 //PT const gradline(uintc i) const; 00072 00074 //PT const normal(uint i) const; 00075 00078 void equilaterali(PT & x, uintc i) const; 00079 00082 void fermatpoint(PT & x) const; 00083 00085 void gergonnepoint(PT & x) const; 00086 00088 void incenter(PT & x) const; 00090 void incenteri(PT & x, uint i) const; 00091 00093 template< typename U > 00094 void innercircle 00095 ( 00096 PD & radius, 00097 U & center, 00098 U & circlenormal 00099 ) const; 00100 00102 void midpoint(PT& x, uintc i) const; 00103 00105 template< typename U > 00106 void normal(U & circlenormal) const; 00107 00111 void napoleanpoint(PT & x) const; 00112 00114 void orthocenter(PT & x) const; 00118 void orthocenteri(PT & x, uintc i) const; 00119 00121 template< typename U > 00122 void outercircle 00123 ( 00124 PD & radius, 00125 U & center, 00126 U & circlenormal 00127 ) const; 00128 00130 void outercircle 00131 ( 00132 PD & radius, 00133 PT & center 00134 ) const; 00135 00137 boolc valid() const; 00138 }; 00139 00140 00141 //--------------------------------------------------------- 00142 // Implementation 00143 00144 00145 00146 template< typename PT, typename PD > 00147 void triangle<PT,PD>::constructUnordered 00148 ( 00149 PT const & p0, 00150 PT const & p1, 00151 PT const & p2 00152 ) 00153 { 00154 pi[0] = p0; 00155 pi[1] = p1; 00156 pi[2] = p2; 00157 00158 if (valid()==false) 00159 { 00160 pi[1] = p2; 00161 pi[2] = p1; 00162 00163 assert(valid()); 00164 } 00165 } 00166 00167 template< typename PT, typename PD > 00168 void triangle<PT,PD>::gergonnepoint(PT & x) const 00169 { 00170 PT c0; 00171 incenteri(c0,0); 00172 PT c1; 00173 incenteri(c1,1); 00174 00175 PT t; 00176 d2matsolve(t,pi[0]-c0,c1-pi[1],c1-c0); 00177 00178 x = c0 + (pi[0]-c0)*t.x; 00179 } 00180 00181 template< typename PT, typename PD > 00182 void triangle<PT,PD>::napoleanpoint(PT & x) const 00183 { 00184 PT c0; 00185 equilaterali(c0,0); 00186 c0 += pi[1]; 00187 c0 += pi[2]; 00188 c0 /= 3.0; 00189 PT c1; 00190 equilaterali(c1,1); 00191 c1 += pi[0]; 00192 c1 += pi[2]; 00193 c1 /= 3.0; 00194 00195 PT t; 00196 d2matsolve(t,pi[0]-c0,c1-pi[1],c1-c0); 00197 00198 x = c0 + (pi[0]-c0)*t.x; 00199 } 00200 00201 template< typename PT, typename PD > 00202 void triangle<PT,PD>::fermatpoint(PT & x) const 00203 { 00204 PT e0; 00205 equilaterali(e0,0); 00206 PT e1; 00207 equilaterali(e1,1); 00208 00209 PT t; 00210 d2matsolve(t,pi[0]-e0,e1-pi[1],e1-e0); 00211 00212 x = e0 + (pi[0]-e0)*t.x; 00213 } 00214 00215 template< typename PT, typename PD > 00216 void triangle<PT,PD>::incenter(PT & x) const 00217 { 00218 PT b0; 00219 bisectangle(b0,0); 00220 PT b1; 00221 bisectangle(b1,1); 00222 00223 PT v; // The two variables. 00224 d2matsolve 00225 ( 00226 v, 00227 b0 - pi[0], pi[1] - b1, 00228 pi[1] - pi[0] 00229 ); 00230 00231 x = pi[0]+(b0-pi[0])*v.x; 00232 } 00233 template< typename PT, typename PD > 00234 template< typename U > 00235 void triangle<PT,PD>::normal(U & circlenormal) const 00236 { 00237 circlenormal.x = 0; 00238 circlenormal.y = 0; 00239 circlenormal.z = 1; 00240 } 00241 00242 00243 template< typename PT, typename PD > 00244 template< typename U > 00245 void triangle<PT,PD>::innercircle 00246 ( 00247 PD & radius, 00248 U & center, 00249 U & circlenormal 00250 ) const 00251 { 00252 PT c; 00253 incenter(c); 00254 center.x = c.x; 00255 center.y = c.y; 00256 00257 PT w; 00258 line<PT,PD>::nearestpointonline(w,c,pi[0],pi[1]-pi[0]); 00259 w -= c; 00260 00261 radius = w.distance(); 00262 normal(circlenormal); 00263 } 00264 00265 template< typename PT, typename PD > 00266 void triangle<PT,PD>::incenteri(PT & x, uintc i) const 00267 { 00268 PT q; 00269 incenter(q); 00270 00271 switch(i) 00272 { 00273 case 0: line<PT,PD>::nearestpointonline(x,q,pi[1],pi[2]-pi[1]); break; 00274 case 1: line<PT,PD>::nearestpointonline(x,q,pi[2],pi[0]-pi[2]); break; 00275 case 2: line<PT,PD>::nearestpointonline(x,q,pi[0],pi[1]-pi[0]); break; 00276 00277 default: assert(false); 00278 } 00279 } 00280 00281 template< typename PT, typename PD > 00282 template< typename U > 00283 void triangle<PT,PD>::outercircle 00284 ( 00285 PD & radius, 00286 U & center, 00287 U & circlenormal 00288 ) const 00289 { 00290 PT c; 00291 circumcenter(c); 00292 center.x = c.x; 00293 center.y = c.y; 00294 radius = (c-pi[0]).distance(); 00295 normal(circlenormal); 00296 } 00297 00298 template< typename PT, typename PD > 00299 void triangle<PT,PD>::outercircle 00300 ( 00301 PD & radius, 00302 PT & center 00303 ) const 00304 { 00305 PT c; 00306 circumcenter(c); 00307 center.x = c.x; 00308 center.y = c.y; 00309 radius = (c-pi[0]).distance(); 00310 } 00311 00312 00313 template< typename PT, typename PD > 00314 void triangle<PT,PD>::circumcenter(PT & x) const 00315 { 00316 //x =(G*3.0-H)*0.5; 00317 centroid(x); 00318 x *= 3.0; 00319 PT H; 00320 orthocenter(H); 00321 x -= H; 00322 x *= 0.5; 00323 } 00324 00325 template< typename PT, typename PD > 00326 void triangle<PT,PD>::orthocenter(PT & x) const 00327 { 00328 PT p0w; 00329 orthocenteri(p0w,0); 00330 PT p1w; 00331 orthocenteri(p1w,1); 00332 PT t; 00333 00334 d2matsolve(t,p0w-pi[0],pi[1]-p1w,pi[1]-pi[0]); 00335 00336 x = pi[0] + (p0w-pi[0])*t.x; 00337 } 00338 00339 template< typename PT, typename PD > 00340 void triangle<PT,PD>::centroid(PT & x) const 00341 { 00342 x = pi[0]; 00343 x += pi[1]; 00344 x += pi[2]; 00345 x /= 3.0; 00346 } 00347 00348 template< typename PT, typename PD > 00349 void triangle<PT,PD>::bisectangle(PT & x, uintc i) const 00350 { 00351 PT A,B; 00352 PT X; 00353 00354 switch(i) 00355 { 00356 case 0: 00357 A = pi[1]; 00358 B = pi[2]; 00359 X = pi[0]; 00360 break; 00361 00362 case 1: 00363 A = pi[0]; 00364 B = pi[2]; 00365 X = pi[1]; 00366 break; 00367 00368 case 2: 00369 A = pi[1]; 00370 B = pi[0]; 00371 X = pi[2]; 00372 break; 00373 00374 00375 default: 00376 assert(false); 00377 } 00378 00379 PD a = (A-X).distance(); 00380 PD b = (B-X).distance(); 00381 00382 x = (A*b+B*a)/(a+b); 00383 } 00384 00385 template< typename PT, typename PD > 00386 void triangle<PT,PD>::equilaterali(PT & x, uintc i) const 00387 { 00388 PT g; 00389 PT n1; 00390 switch(i) 00391 { 00392 case 0: 00393 g = (pi[2]+pi[1])*0.5; 00394 n1=pi[2]-pi[1]; 00395 break; 00396 case 1: 00397 g = (pi[2]+pi[0])*0.5; 00398 n1=pi[0]-pi[2]; 00399 break; 00400 case 2: 00401 g = (pi[0]+pi[1])*0.5; 00402 n1=pi[1]-pi[0]; 00403 break; 00404 default: 00405 assert(false); 00406 } 00407 00408 // Outwards normal. 00409 PT n2(n1.y,-n1.x); 00410 n2.normalize(); 00411 00412 x = g+n2*sqrt(3.0)*0.5*n1.distance(); 00413 } 00414 00415 //template< typename PT, typename PD > 00416 //PT const triangle<PT,PD>::normal(uintc i) const 00417 //{ 00418 // PT g(gradline(i)); 00419 // PT g2(-g.y,g.x); 00420 // return g2; 00421 //} 00422 00423 /* 00424 template< typename PT, typename PD > 00425 PT const triangle<PT,PD>::gradline(uintc i) const 00426 { 00427 PT g; 00428 00429 switch(i) 00430 { 00431 case 0: 00432 g = pi[2] - pi[1]; 00433 break; 00434 00435 case 1: 00436 g = pi[0] - pi[2]; 00437 break; 00438 00439 case 2: 00440 g = pi[1] - pi[0]; 00441 break; 00442 00443 default: 00444 assert(false); 00445 } 00446 00447 return g; 00448 } 00449 */ 00450 00451 template< typename PT, typename PD > 00452 void triangle<PT,PD>::orthocenteri(PT & x, uintc i) const 00453 { 00454 PT z; 00455 PT m0; 00456 PT w0; 00457 00458 switch(i) 00459 { 00460 case 0: 00461 w0 = pi[1]; 00462 m0 = pi[2] - pi[1]; 00463 00464 z = pi[0]; 00465 break; 00466 00467 case 1: 00468 w0 = pi[2]; 00469 m0 = pi[0] - pi[2]; 00470 00471 z = pi[1]; 00472 break; 00473 00474 case 2: 00475 w0 = pi[0]; 00476 m0 = pi[1] - pi[0]; 00477 00478 z = pi[2]; 00479 break; 00480 00481 default: 00482 assert(false); 00483 } 00484 00485 PT m1(-m0.y,m0.x); 00486 PT t; 00487 d2matsolve(t,m0,m1*-1.0,z-w0); 00488 00489 x = z + m1*t.y; 00490 } 00491 00492 template< typename PT, typename PD > 00493 void triangle<PT,PD>::midpoint(PT & x, uintc i) const 00494 { 00495 switch(i) 00496 { 00497 case 0: 00498 x=pi[1]; x += pi[2]; 00499 break; 00500 00501 case 1: 00502 x=pi[0]; x += pi[2]; 00503 break; 00504 00505 case 2: 00506 x=pi[1]; x += pi[0]; 00507 break; 00508 00509 default: 00510 assert(false); 00511 } 00512 00513 x *= 0.5; 00514 } 00515 00516 template< typename PT, typename PD > 00517 void triangle<PT,PD>::construct 00518 ( 00519 PT const & _p0, 00520 PT const & _p1, 00521 PT const & _p2 00522 ) 00523 { 00524 pi[0] = _p0; 00525 pi[1] = _p1; 00526 pi[2] = _p2; 00527 00528 assert(valid()); 00529 } 00530 00531 template< typename PT, typename PD > 00532 triangle<PT,PD>::triangle 00533 ( 00534 PT const & _p0, 00535 PT const & _p1, 00536 PT const & _p2 00537 ) 00538 { 00539 construct(_p0,_p1,_p2); 00540 } 00541 00542 template< typename PT, typename PD > 00543 boolc triangle<PT,PD>::valid() const 00544 { 00545 PT a0(pi[1]-pi[0]); 00546 PT a1; 00547 a1.x=-a0.y; 00548 a1.y=a0.x; 00549 PT q(pi[2]-pi[0]); 00550 bool res = (a1.x*q.x+a1.y*q.y>0); 00551 00552 return res; 00553 } 00554 00555 00556 00557 00558 00559 00560 00561 #endif 00562 00563 00564
1.5.8