Polygon.cpp

Go to the documentation of this file.
00001 #include <Polygon.h>
00002 
00003 
00004 int Polygon::  no_vertices() {
00005   return p.size(); 
00006 }
00007 
00008 GiNaC::ex Polygon::vertex (int i) {
00009   return p[i];  
00010 }
00011 
00012 string Polygon:: str() {
00013   //FIXME could add all points here. 
00014   return "Polygon"; 
00015 }
00016 
00017 
00018 //---        Line ------------------------------------
00019 
00020 Line:: Line(GiNaC::ex x0, GiNaC::ex x1, string subscript_){ 
00021    subscript = subscript_; 
00022 
00023   /* Lines on the form 
00024    * x = x_0 + a_1 t
00025    * y = y_0 + a_2 t
00026    * z = z_0 + a_3 t
00027   */
00028 
00029 
00030 
00031 
00032   //FIXME does not need to be a list in 1D. 
00033   if ( true /* (is_a<lst>(x0) && is_a<lst>(x1)) && (x0.nops() == x1.nops())*/ ) { 
00034 
00035     GiNaC::lst aa; 
00036     GiNaC::lst bb; 
00037 
00038 
00039     // compute aa and bb 
00040     for (int i=0; i<= x0.nops()-1; i++) {
00041       bb.append(x0.op(i)); 
00042       aa.append(x1.op(i) - x0.op(i)); 
00043     }
00044 
00045 
00046     //update internal structure
00047     p.insert(p.end(), x0); ; 
00048     p.insert(p.end(), x1); ; 
00049     a_ = aa; 
00050     b_ = bb; 
00051 
00052   } else {
00053     // FIXME: not decided on proper error handling yet. 
00054     // Could build upon GiNaC
00055     cout <<"THIS SHOULD NOT HAPPEN "<<endl; 
00056   }
00057 }
00058 
00059 int Line:: no_vertices() { return 2;  }
00060 
00061 GiNaC::ex Line:: vertex(int i) {
00062   return p[i];  
00063 }
00064 
00065 
00066  
00067 GiNaC::ex Line:: repr(GiNaC::ex t, Repr_format format) {
00068   /* FIXME: use the same symbols in this 
00069    * description as in the actual symbols 
00070    * below and in the documentation. 
00071    *
00072    * Lines on the form 
00073    * x = x_0 + a_1 t,   
00074    * y = y_0 + a_2 t,
00075    * z = z_0 + a_3 t. 
00076    * for t in [0,1]
00077   */
00078 
00079   GiNaC::lst r; 
00080   // 2D
00081 
00082   if ( format == SUBS_PERFORMED ) { 
00083     if ( a_.nops() == 2) { 
00084       r = GiNaC::lst(  x == b_.op(0) +  a_.op(0)*t, 
00085                 y == b_.op(1) +  a_.op(1)*t);   
00086     // 3D
00087     } else if ( a_.nops() == 3) {
00088       r = GiNaC::lst(  x == b_.op(0) +  a_.op(0)*t, 
00089                 y == b_.op(1) +  a_.op(1)*t,   
00090                 z == b_.op(2) +  a_.op(2)*t);   
00091     }
00092     r.append(GiNaC::lst(t,0,1));
00093   }
00094   else if ( format == SUBS_NOT_PERFORMED ) { 
00095 
00096     // FIXME: decide how the constant should be !!
00097     GiNaC::symbol a1("A"+subscript); 
00098     GiNaC::symbol a2("C"+subscript); 
00099     GiNaC::symbol a3("E"+subscript); 
00100     GiNaC::symbol b1("B"+subscript); 
00101     GiNaC::symbol b2("D"+subscript); 
00102     GiNaC::symbol b3("F"+subscript); 
00103   
00104   
00105     // 3D
00106     if ( a_.nops() == 2) { 
00107       r = GiNaC::lst(  x == b1 +  a1*t, 
00108                 y == b2 +  a2*t);   
00109   
00110       r.append( a1 == a_.op(0));   
00111       r.append( b1 == b_.op(0));
00112       r.append( a2 == a_.op(1)); 
00113       r.append( b2 == b_.op(1)); 
00114     // 3D
00115     } else if ( a_.nops() == 3) {
00116       r = GiNaC::lst(  x == b1 +  a1*t, 
00117                 y == b2 +  a2*t,   
00118                 z == b3 +  a3*t);   
00119   
00120   
00121       r.append( a1 == a_.op(0));   
00122       r.append( b1 == b_.op(0));
00123       r.append( a2 == a_.op(1)); 
00124       r.append( b2 == b_.op(1)); 
00125       r.append( a3 == a_.op(2)); 
00126       r.append( b3 == b_.op(2)); 
00127   
00128   
00129     }
00130   
00131     r.append(GiNaC::lst(t,0,1));
00132   }
00133 
00134   return r; 
00135 }
00136 
00137 GiNaC::ex Line:: integrate(GiNaC::ex f, Repr_format format) {
00138   GiNaC::symbol t("t"); 
00139   GiNaC::ex t_repr = repr(t); 
00140   GiNaC::lst sub; 
00141   int counter; 
00142   // perform substitution 
00143   if ( p[0].nops() == 3) {
00144     sub = GiNaC::lst(t_repr.op(0), t_repr.op(1), t_repr.op(2));  
00145     counter = 3;  
00146   } else if ( p[0].nops() == 2) { 
00147     sub = GiNaC::lst(t_repr.op(0), t_repr.op(1));  
00148     counter = 2;  
00149   }
00150 
00151 
00152   // compute D
00153   GiNaC::ex D; 
00154   if ( p[0].nops() == 3) {
00155     D = pow(t_repr.op(0).rhs().coeff(t), 2) +  
00156         pow(t_repr.op(1).rhs().coeff(t), 2) +   
00157         pow(t_repr.op(2).rhs().coeff(t), 2);  
00158   } else if ( p[0].nops() == 2) { 
00159     D = pow(t_repr.op(0).rhs().coeff(t), 2) +  
00160         pow(t_repr.op(1).rhs().coeff(t), 2);  
00161   }
00162 
00163   D = sqrt(D); 
00164 
00165   GiNaC::ex intf = f.subs(sub)*D; 
00166 
00167   intf = GiNaC::integral(t_repr.op(counter).op(0), t_repr.op(counter).op(1), t_repr.op(counter).op(2), intf);  
00168   intf = eval_integ(intf); 
00169 
00170   return intf; 
00171 
00172 
00173 }
00174 
00175 string Line:: str(){
00176    std::ostringstream s; 
00177 //   s <<"Line("<<p[0]<<","<<p[1]<<")"; 
00178    s <<"Line";
00179    return s.str(); 
00180 }
00181 
00182 
00183 //---        ReferenceLine --------------------------------
00184 
00185 ReferenceLine:: ReferenceLine(string subscript_) {
00186   subscript = subscript_; 
00187   GiNaC::ex x0 = GiNaC::lst(0,0,0); 
00188   GiNaC::ex x1 = GiNaC::lst(1,0,0); 
00189   p.insert(p.end(),x0); 
00190   p.insert(p.end(),x1); 
00191 
00192 
00193 }
00194 
00195 int ReferenceLine:: no_vertices() { return 2; }
00196 
00197 GiNaC::ex ReferenceLine:: vertex(int i) {
00198   return p[i]; 
00199 }
00200 
00201 GiNaC::ex ReferenceLine:: a() {
00202   return GiNaC::lst(1,0,0);  
00203 }
00204 
00205 GiNaC::ex ReferenceLine:: b() {
00206   return GiNaC::lst(0,0,0); 
00207 }
00208 
00209 GiNaC::ex ReferenceLine:: repr(GiNaC::ex t, Repr_format format) {
00210   GiNaC::lst r; 
00211   r = GiNaC::lst( x == t, y == 0, z == 0, t, 0, 1);  
00212   return r; 
00213 }
00214 
00215 string ReferenceLine:: str() {
00216    std::ostringstream s; 
00217 //   s <<"ReferenceLine("<<p[0]<<","<<p[1]<<")"<<endl; 
00218    s <<"ReferenceLine"; // <<endl; 
00219    return s.str(); 
00220 }
00221 
00222 GiNaC::ex ReferenceLine:: integrate(GiNaC::ex f, Repr_format formt) {
00223   GiNaC::ex intf = GiNaC::integral(x,0,1,f);   
00224   intf =  eval_integ(intf); 
00225   return intf;  
00226 }
00227 
00228 
00229 //---        Triangle ------------------------------------
00230 
00231 Triangle:: Triangle(GiNaC::ex x0, GiNaC::ex x1, GiNaC::ex x2, string subscript_) { 
00232   subscript = subscript_; 
00233   p.insert(p.end(), x0); 
00234   p.insert(p.end(), x1); 
00235   p.insert(p.end(), x2); 
00236 
00237 }
00238 
00239 int Triangle:: no_vertices() { return 3; }
00240 
00241 GiNaC::ex Triangle:: vertex(int i) {
00242   return p[i]; 
00243 }
00244 
00245 /*
00246 GiNaC::ex Triangle:: plane() {
00247   GiNaC::lst ret; 
00248 
00249   if ( p[1].nops() == 3 ) {
00250    
00251     GiNaC::lst x1x0; // = GiNaC::ex_to<lst>(p[1] - p[0]); 
00252     GiNaC::lst x2x0; // = GiNaC::ex_to<lst>(p[2] - p[0]); 
00253     for (int i=0; i<= p[0].nops()-1; i++) {
00254       x1x0.append(p[1].op(i)-p[0].op(i));  
00255       x2x0.append(p[2].op(i)-p[0].op(i));  
00256     }
00257    
00258     GiNaC::lst normal = cross(x1x0, x2x0); 
00259    
00260     cout <<endl; 
00261   
00262     symbol A("A"); symbol B("B"); symbol C("C"); 
00263     ret.append(normal.op(0)*(x- p[0].op(0)));
00264     ret.append(normal.op(1)*(y- p[0].op(1)));
00265     ret.append(normal.op(2)*(z- p[0].op(2)));
00266   } else {
00267     ret.append(z == 0 ); 
00268   }
00269  return ret; 
00270 }
00271 */
00272 
00273 Line Triangle:: line(int i) {
00274 //  Line l = Line(p[(i-1)%3], p[i%3]); 
00275 //  return l; 
00276   if      ( i == 1) return Line(p[0],p[1], istr(subscript,i));  
00277   else if ( i == 2) return Line(p[0],p[2], istr(subscript,i));  
00278   else if ( i == 3) return Line(p[1],p[2], istr(subscript,i));  
00279 }
00280 
00281 GiNaC::ex Triangle:: repr(Repr_format format) {
00282    GiNaC::symbol r("r"), s("s"); 
00283    GiNaC::symbol G("G"), H("H"); 
00284    GiNaC::ex l1_repr = line(1).repr(r); 
00285    GiNaC::ex l2_repr = line(2).repr(s); 
00286    GiNaC::lst ret; 
00287    //2D 
00288    if ( p[0].nops() == 2) {
00289      ret = GiNaC::lst( x ==l1_repr.op(0).rhs().coeff(r,0) + l1_repr.op(0).rhs().coeff(r,1)*r +  l2_repr.op(0).rhs().coeff(s,1)*s,  
00290                 y ==l1_repr.op(1).rhs().coeff(r,0) + l1_repr.op(1).rhs().coeff(r,1)*r +  l2_repr.op(1).rhs().coeff(s,1)*s);   
00291 
00292 
00293    }
00294    else if ( p[0].nops() == 3) {
00295 
00296      ret = GiNaC::lst( x == l1_repr.op(0).rhs().coeff(r,0) + l1_repr.op(0).rhs().coeff(r,1)*r +  l2_repr.op(0).rhs().coeff(s,1)*s,  
00297                 y == l1_repr.op(1).rhs().coeff(r,0) + l1_repr.op(1).rhs().coeff(r,1)*r +  l2_repr.op(1).rhs().coeff(s,1)*s,   
00298                 z == l1_repr.op(2).rhs().coeff(r,0) + l1_repr.op(2).rhs().coeff(r,1)*r +  l2_repr.op(2).rhs().coeff(s,1)*s);   
00299 
00300    }
00301 
00302    ret.append(GiNaC::lst(r, 0, 1)); 
00303    ret.append(GiNaC::lst(s, 0, 1 - r)); 
00304 
00305    return ret; 
00306 
00307 }
00308 
00309 
00310 string Triangle:: str() {
00311    std::ostringstream s; 
00312 //   s <<"Triangle("<<p[0]<<","<<p[1]<<","<<p[2]<<")"<<endl; 
00313    s <<"Triangle"; 
00314    return s.str(); 
00315 }
00316 
00317 GiNaC::ex Triangle:: integrate(GiNaC::ex func, Repr_format format) {
00318 
00319   GiNaC::ex t_repr = repr(); 
00320   GiNaC::lst sub; 
00321   int counter; 
00322 
00323 
00324   // perform substitution
00325   if ( p[0].nops() == 3) {
00326     sub = GiNaC::lst(t_repr.op(0), t_repr.op(1), t_repr.op(2));  
00327     counter = 3;  
00328   } else if ( p[0].nops() == 2) { 
00329     sub = GiNaC::lst(t_repr.op(0), t_repr.op(1));  
00330     counter = 2;  
00331   }
00332   GiNaC::ex intf = func.subs(sub); 
00333 
00334   // compute D
00335   GiNaC::ex D; 
00336   if ( p[0].nops() == 3) {
00337     GiNaC::ex r = t_repr.op(3).op(0); 
00338     GiNaC::ex s = t_repr.op(4).op(0); 
00339     GiNaC::ex a = t_repr.op(0).rhs().coeff(r,1); 
00340     GiNaC::ex b = t_repr.op(0).rhs().coeff(s,1); 
00341     GiNaC::ex c = t_repr.op(1).rhs().coeff(r,1); 
00342     GiNaC::ex d = t_repr.op(1).rhs().coeff(s,1); 
00343     GiNaC::ex e = t_repr.op(2).rhs().coeff(r,1); 
00344     GiNaC::ex f = t_repr.op(2).rhs().coeff(s,1); 
00345     D = pow(c*f-d*e,2) + pow(a*f - b*e,2) + pow(a*d - b*c,2);   
00346     D = sqrt(D); 
00347   } else if ( p[0].nops() == 2) { 
00348     GiNaC::ex r = t_repr.op(2).op(0); 
00349     GiNaC::ex s = t_repr.op(3).op(0); 
00350     GiNaC::ex a = t_repr.op(0).rhs().coeff(r,1); 
00351     GiNaC::ex b = t_repr.op(0).rhs().coeff(s,1); 
00352     GiNaC::ex c = t_repr.op(1).rhs().coeff(r,1); 
00353     GiNaC::ex d = t_repr.op(1).rhs().coeff(s,1); 
00354     D = abs(a*d-b*c); 
00355   }
00356 
00357   intf = intf*D; 
00358 
00359 
00360   counter++; 
00361   intf = GiNaC::integral(t_repr.op(counter).op(0), t_repr.op(counter).op(1), t_repr.op(counter).op(2), intf);  
00362   intf = eval_integ(intf); 
00363 
00364   counter--; 
00365   intf = GiNaC::integral(t_repr.op(counter).op(0), t_repr.op(counter).op(1), t_repr.op(counter).op(2), intf);  
00366   intf = eval_integ(intf); 
00367   return intf; 
00368 
00369 }
00370 
00371 
00372 
00373 //---        ReferenceTriangle ----------------------------
00374 
00375 
00376 ReferenceTriangle:: ReferenceTriangle(string subscript_) { 
00377   subscript = subscript_; 
00378   GiNaC::ex x0 = GiNaC::lst(0,0,0); 
00379   GiNaC::ex x1 = GiNaC::lst(1,0,0); 
00380   GiNaC::ex x2 = GiNaC::lst(0,1,0); 
00381   p.insert(p.end(), x0); 
00382   p.insert(p.end(), x1); 
00383   p.insert(p.end(), x2); 
00384 }
00385 
00386 int ReferenceTriangle:: no_vertices() { return 3; }
00387 
00388 GiNaC::ex ReferenceTriangle:: vertex (int i) {
00389   return Triangle::vertex(i); 
00390 }
00391 
00392 //GiNaC::ex ReferenceTriangle:: plane() {
00393 //  return Triangle:: plane(); 
00394 //}
00395 
00396 Line ReferenceTriangle:: line(int i) {
00397   return Triangle:: line(i); 
00398 }
00399 
00400 GiNaC::ex ReferenceTriangle:: repr(Repr_format format) {
00401   return Triangle:: repr(); 
00402 }
00403   
00404 string ReferenceTriangle:: str() {
00405    std::ostringstream s; 
00406 //   s <<"ReferenceTriangle("<<p[0]<<","<<p[1]<<","<<p[2]<<")"; 
00407    s <<"ReferenceTriangle"; 
00408    return s.str(); 
00409 }
00410 
00411 GiNaC::ex ReferenceTriangle:: integrate(GiNaC::ex f) {
00412   //FIXME can not have two integrals and then two eval_integ ? 
00413   GiNaC::ex ret = GiNaC::eval_integ(
00414                   GiNaC::integral(y,0,1, 
00415                   GiNaC::eval_integ(
00416                   GiNaC::integral(x,0,1-y,f))));   
00417   return ret;  
00418 }
00419 
00420 
00421 
00422 
00423 //---        Tetrahedron ------------------------------------
00424 
00425 
00426 Tetrahedron:: Tetrahedron(GiNaC::ex x0, GiNaC::ex x1, GiNaC::ex x2, GiNaC::ex x3, string subscript_) { 
00427   subscript = subscript_; 
00428   p.insert(p.end(), x0); 
00429   p.insert(p.end(), x1); 
00430   p.insert(p.end(), x2); 
00431   p.insert(p.end(), x3); 
00432 
00433 }
00434 
00435 int Tetrahedron:: no_vertices() {return 4; }
00436 
00437 GiNaC::ex Tetrahedron:: vertex(int i) {
00438   return p[i]; 
00439 }
00440 
00441 Line Tetrahedron:: line(int i) {
00442   int i0, i1; 
00443   if ( i == 1 ) {
00444     i0 = 0; i1 = 1;  
00445   } else if ( i == 2 ) { 
00446     i0 = 0; i1 = 2;  
00447   } else if ( i == 3 )  { 
00448     i0 = 0; i1 = 3;  
00449   } else if ( i == 4 )  { 
00450     i0 = 1; i1 = 2;  
00451   } else if ( i == 5 )  { 
00452     i0 = 1; i1 = 3;  
00453   } else if ( i == 6 )  { 
00454     i0 = 2; i1 = 3;  
00455   }
00456   Line l = Line(p[i0], p[i1], istr(subscript,i)); 
00457   return l; 
00458 }
00459 
00460 Triangle Tetrahedron :: triangle(int i) {
00461   Triangle t = Triangle(p[i%4], p[(i+1)%4], p[(i+2)%4], istr(subscript,i)); 
00462   return t; 
00463 }
00464 
00465 string Tetrahedron:: str() {
00466    std::ostringstream s; 
00467 //   s <<"Tetrahedron("<<p[0]<<","<<p[1]<<","<<p[2]<<","<<p[3]<<")"; 
00468    s <<"Tetrahedron";
00469    return s.str(); 
00470 }
00471 
00472 
00473 GiNaC::ex Tetrahedron:: repr(Repr_format format) {
00474    GiNaC::symbol r("r"), s("s"), t("t"); 
00475    GiNaC::ex l1_repr = line(1).repr(r); 
00476    GiNaC::ex l2_repr = line(2).repr(s); 
00477    GiNaC::ex l3_repr = line(3).repr(t); 
00478    GiNaC::lst ret; 
00479 
00480 
00481    ret = GiNaC::lst( 
00482        x == l1_repr.op(0).rhs().coeff(r,0)   + l1_repr.op(0).rhs().coeff(r,1)*r 
00483          +  l2_repr.op(0).rhs().coeff(s,1)*s + l3_repr.op(0).rhs().coeff(t,1)*t,  
00484        y == l1_repr.op(1).rhs().coeff(r,0)   + l1_repr.op(1).rhs().coeff(r,1)*r 
00485          +  l2_repr.op(1).rhs().coeff(s,1)*s + l3_repr.op(1).rhs().coeff(t,1)*t,  
00486        z == l1_repr.op(2).rhs().coeff(r,0)   + l1_repr.op(1).rhs().coeff(r,1)*r  
00487          +  l2_repr.op(2).rhs().coeff(s,1)*s + l3_repr.op(2).rhs().coeff(t,1)*t);   
00488 
00489 
00490    ret.append(GiNaC::lst(r, 0, 1)); 
00491    ret.append(GiNaC::lst(s, 0, 1 - r)); 
00492    ret.append(GiNaC::lst(t, 0, 1 - r - s)); 
00493 
00494    return ret; 
00495 }
00496 
00497 GiNaC::ex Tetrahedron:: integrate(GiNaC::ex func, Repr_format format) {
00498   GiNaC::ex t_repr = repr(); 
00499 
00500   //perform substitution
00501   GiNaC::lst sub = GiNaC::lst(t_repr.op(0), t_repr.op(1), t_repr.op(2));  
00502   GiNaC::ex intf = func.subs(sub); 
00503 
00504   // compute D 
00505   GiNaC::ex D; 
00506   GiNaC::ex r = t_repr.op(3).op(0); 
00507   GiNaC::ex s = t_repr.op(4).op(0); 
00508   GiNaC::ex t = t_repr.op(5).op(0); 
00509   GiNaC::ex a = t_repr.op(0).rhs().coeff(r,1); 
00510   GiNaC::ex b = t_repr.op(0).rhs().coeff(s,1); 
00511   GiNaC::ex c = t_repr.op(0).rhs().coeff(t,1); 
00512   GiNaC::ex d = t_repr.op(1).rhs().coeff(r,1); 
00513   GiNaC::ex e = t_repr.op(1).rhs().coeff(s,1); 
00514   GiNaC::ex f = t_repr.op(1).rhs().coeff(t,1); 
00515   GiNaC::ex g = t_repr.op(2).rhs().coeff(r,1); 
00516   GiNaC::ex h = t_repr.op(2).rhs().coeff(s,1); 
00517   GiNaC::ex k = t_repr.op(2).rhs().coeff(t,1); 
00518 
00519   D = a*(e*k-f*h) - b*(d*k-f*g) + c*(d*h - g*e); 
00520 
00521   intf = intf*D; 
00522 
00523   intf = GiNaC::integral(t_repr.op(5).op(0), t_repr.op(5).op(1), t_repr.op(5).op(2), intf);  
00524   intf = GiNaC::eval_integ(intf); 
00525 
00526   intf = GiNaC::integral(t_repr.op(4).op(0), t_repr.op(4).op(1), t_repr.op(4).op(2), intf);  
00527   intf = GiNaC::eval_integ(intf); 
00528 
00529   intf = GiNaC::integral(t_repr.op(3).op(0), t_repr.op(3).op(1), t_repr.op(3).op(2), intf);  
00530   intf = GiNaC::eval_integ(intf); 
00531 
00532   return intf; 
00533 }
00534 
00535 //---        ReferenceTetrahedron ---------------------------
00536 
00537 ReferenceTetrahedron:: ReferenceTetrahedron(string subscript_) : Tetrahedron(subscript_) {
00538   subscript = subscript_;  
00539   GiNaC::ex x0 = GiNaC::lst(0, 0, 0); 
00540   GiNaC::ex x1 = GiNaC::lst(1, 0, 0); 
00541   GiNaC::ex x2 = GiNaC::lst(0, 1, 0); 
00542   GiNaC::ex x3 = GiNaC::lst(0, 0, 1); 
00543 
00544   p.insert(p.end(), x0); 
00545   p.insert(p.end(), x1); 
00546   p.insert(p.end(), x2); 
00547   p.insert(p.end(), x3); 
00548 }
00549 
00550 int ReferenceTetrahedron:: no_vertices () {
00551    return 4; 
00552 }
00553 
00554 GiNaC::ex ReferenceTetrahedron:: vertex(int i) {
00555    return Tetrahedron:: vertex(i); 
00556 }
00557 
00558 Line ReferenceTetrahedron:: line(int i) {
00559    return Tetrahedron:: line(i); 
00560 }
00561 
00562 Triangle ReferenceTetrahedron :: triangle(int i) {
00563    return Tetrahedron:: triangle(i); 
00564 }
00565 
00566 string ReferenceTetrahedron:: str() {
00567    std::ostringstream s; 
00568 //   s <<"ReferenceTetrahedron("<<p[0]<<","<<p[1]<<","<<p[2]<<","<<p[3]<<")"<<endl; 
00569    s <<"ReferenceTetrahedron"; 
00570    return s.str(); 
00571 }
00572 
00573 GiNaC::ex ReferenceTetrahedron:: integrate(GiNaC::ex f, Repr_format format) {
00574   // FIXME can not have two integrals and then two eval_integ ? 
00575   // Does not integrate over 3D. 
00576   
00577   GiNaC::ex intf = GiNaC::integral(x,0,1-y-z,f); 
00578   intf = GiNaC::eval_integ(intf); 
00579 
00580   intf = GiNaC::integral(y,0,1-z, intf); 
00581   intf = GiNaC::eval_integ(intf); 
00582 
00583   intf = GiNaC::integral(z,0,1, intf);  
00584   intf = GiNaC::eval_integ(intf); 
00585 
00586   return intf;  
00587 }
00588 
00589 
00590 //--  tools for Polygons ------------------------------------------------------ 
00591 
00592 GiNaC::lst bezier_ordinates(Tetrahedron& tetrahedra, int d) {
00593 
00594   //FIXME: ugly conversion to matrix 
00595 
00596   GiNaC::lst ret; 
00597   GiNaC::ex V1 = tetrahedra.vertex(0); 
00598   GiNaC::ex V2 = tetrahedra.vertex(1); 
00599   GiNaC::ex V3 = tetrahedra.vertex(2); 
00600   GiNaC::ex V4 = tetrahedra.vertex(3); 
00601 
00602   GiNaC::lst V1l = GiNaC::ex_to<GiNaC::lst>(V1); 
00603   GiNaC::lst V2l = GiNaC::ex_to<GiNaC::lst>(V2); 
00604   GiNaC::lst V3l = GiNaC::ex_to<GiNaC::lst>(V3); 
00605   GiNaC::lst V4l = GiNaC::ex_to<GiNaC::lst>(V4); 
00606 
00607 
00608   GiNaC::ex V1m  = lst_to_matrix2(V1l); 
00609   GiNaC::ex V2m  = lst_to_matrix2(V2l); 
00610   GiNaC::ex V3m  = lst_to_matrix2(V3l); 
00611   GiNaC::ex V4m  = lst_to_matrix2(V4l); 
00612 
00613   int l; 
00614   for (int i=0; i<= d; i++) {
00615     for (int j=0; j<= d; j++) {
00616       for (int k=0; k<= d; k++) {
00617         if ( d - i - j -k  >= 0 ) { 
00618           l= d - i - j -k; 
00619           GiNaC::ex sum = (i*V1m + j*V2m + k*V3m + l*V4m)/d;  
00620           ret.append(matrix_to_lst2(sum.evalm())); 
00621         }
00622       }
00623     }
00624   }
00625   // FIXME how should these be sorted ?????  
00626   // ret = ret.sort(); 
00627   return ret; 
00628 }
00629 
00630 
00631 
00632 GiNaC::lst bezier_ordinates(Triangle& triangle, int d) {
00633 
00634   //FIXME: ugly conversion to matrix 
00635 
00636   GiNaC::lst ret; 
00637   GiNaC::ex V1 = triangle.vertex(0); 
00638   GiNaC::ex V2 = triangle.vertex(1); 
00639   GiNaC::ex V3 = triangle.vertex(2); 
00640 
00641   GiNaC::lst V1l = GiNaC::ex_to<GiNaC::lst>(V1); 
00642   GiNaC::lst V2l = GiNaC::ex_to<GiNaC::lst>(V2); 
00643   GiNaC::lst V3l = GiNaC::ex_to<GiNaC::lst>(V3); 
00644 
00645   GiNaC::ex V1m  = lst_to_matrix2(V1l); 
00646   GiNaC::ex V2m  = lst_to_matrix2(V2l); 
00647   GiNaC::ex V3m  = lst_to_matrix2(V3l); 
00648 
00649   int k; 
00650   for (int i=0; i<= d; i++) {
00651     for (int j=0; j<= d-i; j++) {
00652       k= d - i - j; 
00653       GiNaC::ex sum = (i*V1m + j*V2m + k*V3m)/d;  
00654       ret.append(matrix_to_lst2(sum.evalm())); 
00655     }
00656   }
00657   // FIXME how should these be sorted ?????  
00658   // ret = ret.sort(); 
00659   return ret; 
00660 }
00661 
00662 // FIXME barycenter_line, barycenter_triangle, barycenter_tetrahedron
00663 // all needs to determine which equations to use in a proper way 
00664 
00665 GiNaC::ex barycenter_line(GiNaC::ex p0, GiNaC::ex p1) {
00666  GiNaC::ex sol = DUMMY;  
00667 
00668  // 1D
00669  if ( p0.nops() == 1 && p1.nops() == 1 ) {
00670    GiNaC::symbol b0("b0"), b1("b1");
00671    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0); 
00672    GiNaC::ex eq2 = 1 == b0 + b1; 
00673    sol = lsolve(GiNaC::lst(eq1, eq2), GiNaC::lst(b0, b1)); 
00674  }
00675  //2D 
00676  else if ( p0.nops() == 2 && p1.nops() == 2 ) {
00677    GiNaC::symbol b0("b0"), b1("b1");
00678    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0); 
00679    GiNaC::ex eq3 = 1 == b0 + b1; 
00680    sol = lsolve(GiNaC::lst(eq1, eq3), GiNaC::lst(b0, b1)); 
00681    if (sol.nops() == 0) {  
00682      GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1); 
00683      sol = lsolve(GiNaC::lst(eq2, eq3), GiNaC::lst(b0, b1)); 
00684    }
00685  }
00686  //3D 
00687  else if ( p0.nops() == 3 && p1.nops() == 3 ) {
00688    GiNaC::symbol b0("b0"), b1("b1");
00689    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0); 
00690    GiNaC::ex eq4 = 1 == b0 + b1; 
00691    sol = lsolve(GiNaC::lst(eq1, eq4), GiNaC::lst(b0, b1)); 
00692    if (sol.nops() == 0) {  
00693      GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1); 
00694      sol = lsolve(GiNaC::lst(eq2, eq4), GiNaC::lst(b0, b1)); 
00695    }
00696    if (sol.nops() == 0) {  
00697      GiNaC::ex eq3 = z == b0*p0.op(2) + b1*p1.op(2); 
00698      sol = lsolve(GiNaC::lst(eq3, eq4), GiNaC::lst(b0, b1)); 
00699    }
00700  } 
00701  else {
00702    cout <<"Could not compute the barycentric coordinates."<<endl; 
00703    cout <<"Check the coordinates."<<endl;
00704  }
00705  return sol; 
00706 }
00707 
00708 
00709 
00710 GiNaC::ex barycenter_triangle(GiNaC::ex p0, GiNaC::ex p1, GiNaC::ex p2) {
00711  GiNaC::ex sol; 
00712  sol = DUMMY; 
00713 
00714  // 2D 
00715  if ( p0.nops() == 2 && p1.nops() == 2 && p2.nops() == 2) {
00716    GiNaC::symbol b0("b0"), b1("b1"), b2("b2");
00717    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0) + b2*p2.op(0); 
00718    GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1) + b2*p2.op(1); 
00719    GiNaC::ex eq3 = 1 == b0 + b1 + b2; 
00720   
00721    sol = lsolve(GiNaC::lst(eq1, eq2, eq3), GiNaC::lst(b0, b1, b2)); 
00722  } 
00723  // 3D 
00724  else if ( p0.nops() == 3 && p1.nops() == 3 && p2.nops() == 3) {
00725    GiNaC::symbol b0("b0"), b1("b1"), b2("b2");
00726    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0) + b2*p2.op(0); 
00727    GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1) + b2*p2.op(1); 
00728    GiNaC::ex eq3 = z == b0*p0.op(2) + b1*p1.op(2) + b2*p2.op(2); 
00729    GiNaC::ex eq4 = 1 == b0 + b1 + b2; 
00730   
00731    sol = lsolve(GiNaC::lst(eq1, eq2, eq4), GiNaC::lst(b0, b1, b2)); 
00732    if ( sol.nops() == 0 ) {
00733      sol = lsolve(GiNaC::lst(eq1, eq3, eq4), GiNaC::lst(b0, b1, b2)); 
00734    }
00735    if ( sol.nops() == 0 ) {
00736      sol = lsolve(GiNaC::lst(eq2, eq3, eq4), GiNaC::lst(b0, b1, b2)); 
00737    }
00738  }
00739   
00740   
00741 
00742  return sol; 
00743 }
00744 
00745 GiNaC::ex barycenter_tetrahedron(GiNaC::ex p0, GiNaC::ex p1, GiNaC::ex p2, GiNaC::ex p3) {
00746  GiNaC::symbol b0("b0"), b1("b1"), b2("b2"), b3("b3");
00747 
00748  // 3D 
00749  GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0) + b2*p2.op(0) + b3*p3.op(0); 
00750  GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1) + b2*p2.op(1) + b3*p3.op(1); 
00751  GiNaC::ex eq3 = z == b0*p0.op(2) + b1*p1.op(2) + b2*p2.op(2) + b3*p3.op(2); 
00752  GiNaC::ex eq4 = 1 == b0 + b1 + b2 +b3; 
00753 
00754  GiNaC::ex sol = lsolve(GiNaC::lst(eq1, eq2, eq3, eq4), GiNaC::lst(b0, b1, b2, b3)); 
00755 
00756  return sol; 
00757 
00758 }
00759 
00760 GiNaC::ex bernstein(int order, Polygon& p, const string a) {
00761   GiNaC::ex ret; // GiNaC::ex to return   
00762   int dof;       // degrees of freedom  
00763   GiNaC::ex A;   // GiNaC::ex holding the coefficients a_0 .. a_dof  
00764   GiNaC::lst basis; 
00765 
00766   if ( p.str() == "Line" || p.str() == "ReferenceLine" ) {
00767     GiNaC::ex bary = barycenter_line(p.vertex(0), p.vertex(1)); 
00768     GiNaC::ex b0= bary.op(0).rhs(); 
00769     GiNaC::ex b1= bary.op(1).rhs(); 
00770     dof = order+1; 
00771     A = GiNaC::symbolic_matrix(1,dof, a); 
00772     int o=0; 
00773     for (GiNaC::const_iterator i = A.begin(); i != A.end(); ++i)  {  
00774       ret += (*i)*GiNaC::binomial(order,o)*pow(b0,o)*pow(b1,order-o);  
00775       basis.append(pow(b0,o)*pow(b1,order-o));  
00776       o++; 
00777     }
00778   }
00779   else if ( p.str() == "Triangle" || p.str() == "ReferenceTriangle" )  {
00780 
00781     dof = (order+1)*(order+2)/2; 
00782     A = GiNaC::symbolic_matrix(1, dof , a); 
00783 
00784     GiNaC::ex bary = barycenter_triangle(p.vertex(0), p.vertex(1), p.vertex(2)); 
00785     GiNaC::ex b0= bary.op(0).rhs(); 
00786     GiNaC::ex b1= bary.op(1).rhs(); 
00787     GiNaC::ex b2= bary.op(2).rhs(); 
00788 
00789     size_t i=0; 
00790     for (int o1 = 0; o1 <= order; o1++) {
00791       for (int o2 = 0; o2 <= order; o2++) {
00792         for (int o3 = 0; o3 <= order; o3++) {
00793           if ( o1 + o2 + o3 == order ) { 
00794             ret += A.op(i)*(GiNaC::factorial(order)/(GiNaC::factorial(o1)*GiNaC::factorial(o2)*GiNaC::factorial(o3)))
00795                    *pow(b0,o1)*pow(b1,o2)*pow(b2,o3);  
00796 
00797             basis.append(pow(b0,o1)*pow(b1,o2)*pow(b2,o3));  
00798             i++; 
00799           }
00800         }
00801       }
00802     }
00803   }
00804   else if (p.str() == "Tetrahedron" || p.str() == "ReferenceTetrahedron") {
00805 
00806 
00807     dof = 0; 
00808     for (int j=0; j<= order; j++) { 
00809       dof += (j+1)*(j+2)/2; 
00810     }
00811     A = GiNaC::symbolic_matrix(1, dof , a); 
00812 
00813 
00814     GiNaC::ex bary = barycenter_tetrahedron(p.vertex(0), p.vertex(1), p.vertex(2), p.vertex(3)); 
00815     GiNaC::ex b0= bary.op(0).rhs(); 
00816     GiNaC::ex b1= bary.op(1).rhs(); 
00817     GiNaC::ex b2= bary.op(2).rhs(); 
00818     GiNaC::ex b3= bary.op(3).rhs(); 
00819 
00820 
00821     size_t i=0; 
00822     for (int o1 = 0; o1 <= order; o1++) {
00823       for (int o2 = 0; o2 <= order; o2++) {
00824         for (int o3 = 0; o3 <= order; o3++) {
00825           for (int o4 = 0; o4 <= order; o4++) {
00826             if ( o1 + o2 + o3 + o4 == order ) { 
00827               ret += A.op(i)*(GiNaC::factorial(order)/(GiNaC::factorial(o1)*GiNaC::factorial(o2)*GiNaC::factorial(o3)*GiNaC::factorial(o4)))
00828                    *pow(b0,o1)*pow(b1,o2)*pow(b2,o3)*pow(b3,o4);  
00829               basis.append(pow(b0,o1)*pow(b1,o2)*pow(b2,o3)*pow(b3,o4));
00830               i++; 
00831             }
00832           }
00833         }
00834       }
00835     }
00836   }
00837   return GiNaC::lst(ret,matrix_to_lst2(A),basis); 
00838 }
00839 
00840 GiNaC::lst bernsteinv(int order, Polygon& p, const string a) {
00841   GiNaC::lst ret1;  // contains the polynom  
00842   GiNaC::lst ret2;  // contains the coefficients   
00843   GiNaC::lst ret3;  // constains the basis functions  
00844   GiNaC::lst basis_tmp; 
00845   for (int i=1; i<= nsd; i++) { 
00846     GiNaC::lst basis; 
00847     std::ostringstream s; 
00848     s <<a<<""<<i<<"_"; 
00849     GiNaC::ex pol = bernstein(order, p, s.str()); 
00850     ret1.append(pol.op(0)); 
00851     ret2.append(pol.op(1)); 
00852     basis_tmp = GiNaC::ex_to<GiNaC::lst>(pol.op(2)); 
00853     for (GiNaC::lst::const_iterator basis_iterator = basis_tmp.begin(); 
00854          basis_iterator != basis_tmp.end(); ++basis_iterator) {
00855       GiNaC::lst tmp_lst; 
00856       for (int d=1; d<=nsd; d++) tmp_lst.append(0);   
00857       tmp_lst.let_op(i-1) = (*basis_iterator);  
00858       ret3.append(tmp_lst); 
00859     }
00860   }
00861   return GiNaC::lst(ret1,ret2,ret3); 
00862 
00863 }
00864 
00865 GiNaC::lst normal(Tetrahedron& tetrahedron, int i){
00866   Triangle triangle = tetrahedron.triangle(i); 
00867 
00868   GiNaC::symbol t("t"); 
00869   GiNaC::ex line1_repr = triangle.line(1).repr(t); 
00870   GiNaC::ex n11 = line1_repr.op(0).rhs().coeff(t,1); 
00871   GiNaC::ex n12 = line1_repr.op(1).rhs().coeff(t,1); 
00872   GiNaC::ex n13 = line1_repr.op(2).rhs().coeff(t,1); 
00873 
00874   GiNaC::ex line2_repr = triangle.line(2).repr(t); 
00875   GiNaC::ex n21 = line2_repr.op(0).rhs().coeff(t,1); 
00876   GiNaC::ex n22 = line2_repr.op(1).rhs().coeff(t,1); 
00877   GiNaC::ex n23 = line2_repr.op(2).rhs().coeff(t,1); 
00878 
00879   GiNaC::lst n1 = GiNaC::lst(n11,n12,n13); 
00880   GiNaC::lst n2 = GiNaC::lst(n21,n22,n23); 
00881   GiNaC::lst n3 = cross(n1,n2);  
00882 
00883   return n3; 
00884 }
00885 
00886 
00887 GiNaC::lst normal(Triangle& triangle, int i){
00888   Line line = triangle.line(i); 
00889   //FIXME: 5 lines to compute the normal vector, these should
00890   // be put somewhere else.   
00891   GiNaC::symbol t("t"); 
00892   GiNaC::ex line_repr = line.repr(t); 
00893   GiNaC::ex n1 = line_repr.op(0).rhs().coeff(t,1); 
00894   GiNaC::ex n2 = line_repr.op(1).rhs().coeff(t,1); 
00895   GiNaC::lst normal = GiNaC::lst(n2,-n1);  
00896 return normal; 
00897 }
00898 
00899 
00900 
00901 

Generated on Mon Jan 9 18:08:08 2006 for SyFi by  doxygen 1.4.4