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   //NOTE 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   /* NOTE: 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     // NOTE: 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   if ( format == SUBS_PERFORMED) {  
00139     GiNaC::symbol t("t"); 
00140     GiNaC::ex t_repr = repr(t); 
00141     GiNaC::lst sub; 
00142     int counter; 
00143     // perform substitution 
00144     if ( p[0].nops() == 3) {
00145       sub = GiNaC::lst(t_repr.op(0), t_repr.op(1), t_repr.op(2));  
00146       counter = 3;  
00147     } else if ( p[0].nops() == 2) { 
00148       sub = GiNaC::lst(t_repr.op(0), t_repr.op(1));  
00149       counter = 2;  
00150     }
00151   
00152   
00153     // compute D
00154     GiNaC::ex D; 
00155     if ( p[0].nops() == 3) {
00156       D = pow(t_repr.op(0).rhs().coeff(t), 2) +  
00157           pow(t_repr.op(1).rhs().coeff(t), 2) +   
00158           pow(t_repr.op(2).rhs().coeff(t), 2);  
00159     } else if ( p[0].nops() == 2) { 
00160       D = pow(t_repr.op(0).rhs().coeff(t), 2) +  
00161           pow(t_repr.op(1).rhs().coeff(t), 2);  
00162     }
00163   
00164     D = sqrt(D); 
00165   
00166     GiNaC::ex intf = f.subs(sub)*D; 
00167   
00168     intf = GiNaC::integral(t_repr.op(counter).op(0), t_repr.op(counter).op(1), t_repr.op(counter).op(2), intf);  
00169     intf = eval_integ(intf); 
00170   
00171     return intf; 
00172   } else if ( format == SUBS_NOT_PERFORMED ) { 
00173     GiNaC::symbol t("t"); 
00174     GiNaC::ex t_repr = repr(t); 
00175     GiNaC::lst sub; 
00176     GiNaC::symbol a("a"), b("b"), c("c"), D("D"); 
00177     int counter; 
00178     // perform substitution 
00179     
00180     if ( p[0].nops() == 3) {x ==  p[0].op(0) + a*t, 
00181 //      sub = GiNaC::lst(t_repr.op(0), t_repr.op(1), t_repr.op(2));  
00182       sub = GiNaC::lst( x ==  p[0].op(0) + a*t, 
00183                         y ==  p[0].op(1) + b*t, 
00184                         z ==  p[0].op(2) + c*t); 
00185       counter = 3;  
00186     } else if ( p[0].nops() == 2) { 
00187 //      sub = GiNaC::lst(t_repr.op(0), t_repr.op(1));  
00188       sub = GiNaC::lst( x ==  p[0].op(0) + a*t, 
00189                         y ==  p[0].op(1) + b*t); 
00190       counter = 2;  
00191     }
00192   
00193   
00194     // compute D
00195     GiNaC::ex DD; 
00196     if ( p[0].nops() == 3) {
00197       DD = pow(t_repr.op(0).rhs().coeff(t), 2) +  
00198           pow(t_repr.op(1).rhs().coeff(t), 2) +   
00199           pow(t_repr.op(2).rhs().coeff(t), 2);  
00200     } else if ( p[0].nops() == 2) { 
00201       DD = pow(t_repr.op(0).rhs().coeff(t), 2) +  
00202           pow(t_repr.op(1).rhs().coeff(t), 2);  
00203     }
00204   
00205     DD = sqrt(DD); 
00206   
00207     GiNaC::ex intf = f.subs(sub); 
00208   
00209     intf = GiNaC::integral(t_repr.op(counter).op(0), t_repr.op(counter).op(1), t_repr.op(counter).op(2), intf);  
00210     intf = eval_integ(intf); 
00211 
00212 
00213     intf = intf*D; 
00214   
00215     return intf; 
00216   }
00217   return DUMMY; 
00218 }
00219 
00220 string Line:: str(){
00221    std::ostringstream s; 
00222 //   s <<"Line("<<p[0]<<","<<p[1]<<")"; 
00223    s <<"Line";
00224    return s.str(); 
00225 }
00226 
00227 
00228 //---        ReferenceLine --------------------------------
00229 
00230 ReferenceLine:: ReferenceLine(string subscript_) {
00231   subscript = subscript_; 
00232   GiNaC::ex x0 = GiNaC::lst(0,0,0); 
00233   GiNaC::ex x1 = GiNaC::lst(1,0,0); 
00234   p.insert(p.end(),x0); 
00235   p.insert(p.end(),x1); 
00236 
00237 
00238 }
00239 
00240 int ReferenceLine:: no_vertices() { return 2; }
00241 
00242 GiNaC::ex ReferenceLine:: vertex(int i) {
00243   return p[i]; 
00244 }
00245 
00246 GiNaC::ex ReferenceLine:: a() {
00247   return GiNaC::lst(1,0,0);  
00248 }
00249 
00250 GiNaC::ex ReferenceLine:: b() {
00251   return GiNaC::lst(0,0,0); 
00252 }
00253 
00254 GiNaC::ex ReferenceLine:: repr(GiNaC::ex t, Repr_format format) {
00255   GiNaC::lst r; 
00256   r = GiNaC::lst( x == t, y == 0, z == 0, t, 0, 1);  
00257   return r; 
00258 }
00259 
00260 string ReferenceLine:: str() {
00261    std::ostringstream s; 
00262 //   s <<"ReferenceLine("<<p[0]<<","<<p[1]<<")"<<endl; 
00263    s <<"ReferenceLine"; // <<endl; 
00264    return s.str(); 
00265 }
00266 
00267 GiNaC::ex ReferenceLine:: integrate(GiNaC::ex f, Repr_format formt) {
00268   GiNaC::ex intf = GiNaC::integral(x,0,1,f);   
00269   intf =  eval_integ(intf); 
00270   return intf;  
00271 }
00272 
00273 
00274 //---        Triangle ------------------------------------
00275 
00276 Triangle:: Triangle(GiNaC::ex x0, GiNaC::ex x1, GiNaC::ex x2, string subscript_) { 
00277   subscript = subscript_; 
00278   p.insert(p.end(), x0); 
00279   p.insert(p.end(), x1); 
00280   p.insert(p.end(), x2); 
00281 
00282 }
00283 
00284 int Triangle:: no_vertices() { return 3; }
00285 
00286 GiNaC::ex Triangle:: vertex(int i) {
00287   return p[i]; 
00288 }
00289 
00290 /*
00291 GiNaC::ex Triangle:: plane() {
00292   GiNaC::lst ret; 
00293 
00294   if ( p[1].nops() == 3 ) {
00295    
00296     GiNaC::lst x1x0; // = GiNaC::ex_to<lst>(p[1] - p[0]); 
00297     GiNaC::lst x2x0; // = GiNaC::ex_to<lst>(p[2] - p[0]); 
00298     for (int i=0; i<= p[0].nops()-1; i++) {
00299       x1x0.append(p[1].op(i)-p[0].op(i));  
00300       x2x0.append(p[2].op(i)-p[0].op(i));  
00301     }
00302    
00303     GiNaC::lst normal = cross(x1x0, x2x0); 
00304    
00305     cout <<endl; 
00306   
00307     symbol A("A"); symbol B("B"); symbol C("C"); 
00308     ret.append(normal.op(0)*(x- p[0].op(0)));
00309     ret.append(normal.op(1)*(y- p[0].op(1)));
00310     ret.append(normal.op(2)*(z- p[0].op(2)));
00311   } else {
00312     ret.append(z == 0 ); 
00313   }
00314  return ret; 
00315 }
00316 */
00317 
00318 Line Triangle:: line(int i) {
00319 //  Line l = Line(p[(i-1)%3], p[i%3]); 
00320 //  return l; 
00321   if      ( i == 1) return Line(p[0],p[1], istr(subscript,i));  
00322   else if ( i == 2) return Line(p[0],p[2], istr(subscript,i));  
00323   else if ( i == 3) return Line(p[1],p[2], istr(subscript,i));  
00324 }
00325 
00326 GiNaC::ex Triangle:: repr(Repr_format format) {
00327    GiNaC::symbol r("r"), s("s"); 
00328    GiNaC::symbol G("G"), H("H"); 
00329    GiNaC::ex l1_repr = line(1).repr(r); 
00330    GiNaC::ex l2_repr = line(2).repr(s); 
00331    GiNaC::lst ret; 
00332    //2D 
00333    if ( p[0].nops() == 2) {
00334      ret = GiNaC::lst( x == l1_repr.op(0).rhs().coeff(r,0) 
00335                          +  l1_repr.op(0).rhs().coeff(r,1)*r 
00336                          +  l2_repr.op(0).rhs().coeff(s,1)*s,  
00337                        y == l1_repr.op(1).rhs().coeff(r,0) 
00338                          +  l1_repr.op(1).rhs().coeff(r,1)*r 
00339                          +  l2_repr.op(1).rhs().coeff(s,1)*s);   
00340 
00341 
00342    }
00343    else if ( p[0].nops() == 3) {
00344 
00345      ret = GiNaC::lst( x == l1_repr.op(0).rhs().coeff(r,0) 
00346                           + l1_repr.op(0).rhs().coeff(r,1)*r 
00347                           + l2_repr.op(0).rhs().coeff(s,1)*s,  
00348                        y == l1_repr.op(1).rhs().coeff(r,0) 
00349                           + l1_repr.op(1).rhs().coeff(r,1)*r 
00350                           + l2_repr.op(1).rhs().coeff(s,1)*s,   
00351                        z == l1_repr.op(2).rhs().coeff(r,0) 
00352                           + l1_repr.op(2).rhs().coeff(r,1)*r 
00353                           + l2_repr.op(2).rhs().coeff(s,1)*s);   
00354 
00355    }
00356 
00357    ret.append(GiNaC::lst(r, 0, 1)); 
00358    ret.append(GiNaC::lst(s, 0, 1 - r)); 
00359 
00360    return ret; 
00361 
00362 }
00363 
00364 
00365 string Triangle:: str() {
00366    std::ostringstream s; 
00367 //   s <<"Triangle("<<p[0]<<","<<p[1]<<","<<p[2]<<")"<<endl; 
00368    s <<"Triangle"; 
00369    return s.str(); 
00370 }
00371 
00372 GiNaC::ex Triangle:: integrate(GiNaC::ex func, Repr_format format) {
00373 
00374   if ( format == SUBS_PERFORMED ) {
00375     GiNaC::ex t_repr = repr(); 
00376     GiNaC::lst sub; 
00377     int counter; 
00378   
00379   
00380     // perform substitution
00381     if ( p[0].nops() == 3) {
00382       sub = GiNaC::lst(t_repr.op(0), t_repr.op(1), t_repr.op(2));  
00383       counter = 3;  
00384     } else if ( p[0].nops() == 2) { 
00385       sub = GiNaC::lst(t_repr.op(0), t_repr.op(1));  
00386       counter = 2;  
00387     }
00388     GiNaC::ex intf = func.subs(sub); 
00389   
00390     // compute D
00391     GiNaC::ex D; 
00392     if ( p[0].nops() == 3) {
00393       GiNaC::ex r = t_repr.op(3).op(0); 
00394       GiNaC::ex s = t_repr.op(4).op(0); 
00395       GiNaC::ex a = t_repr.op(0).rhs().coeff(r,1); 
00396       GiNaC::ex b = t_repr.op(0).rhs().coeff(s,1); 
00397       GiNaC::ex c = t_repr.op(1).rhs().coeff(r,1); 
00398       GiNaC::ex d = t_repr.op(1).rhs().coeff(s,1); 
00399       GiNaC::ex e = t_repr.op(2).rhs().coeff(r,1); 
00400       GiNaC::ex f = t_repr.op(2).rhs().coeff(s,1); 
00401       D = pow(c*f-d*e,2) + pow(a*f - b*e,2) + pow(a*d - b*c,2);   
00402       D = sqrt(D); 
00403     } else if ( p[0].nops() == 2) { 
00404       GiNaC::ex r = t_repr.op(2).op(0); 
00405       GiNaC::ex s = t_repr.op(3).op(0); 
00406       GiNaC::ex a = t_repr.op(0).rhs().coeff(r,1); 
00407       GiNaC::ex b = t_repr.op(0).rhs().coeff(s,1); 
00408       GiNaC::ex c = t_repr.op(1).rhs().coeff(r,1); 
00409       GiNaC::ex d = t_repr.op(1).rhs().coeff(s,1); 
00410       D = abs(a*d-b*c); 
00411     }
00412   
00413     intf = intf*D; 
00414   
00415   
00416     counter++; 
00417     intf = GiNaC::integral(t_repr.op(counter).op(0), t_repr.op(counter).op(1), t_repr.op(counter).op(2), intf);  
00418     intf = eval_integ(intf); 
00419   
00420     counter--; 
00421     intf = GiNaC::integral(t_repr.op(counter).op(0), t_repr.op(counter).op(1), t_repr.op(counter).op(2), intf);  
00422     intf = eval_integ(intf); 
00423     return intf; 
00424   } else if ( format == SUBS_NOT_PERFORMED ) {
00425     GiNaC::ex t_repr = repr(); 
00426     GiNaC::lst sub; 
00427     int counter; 
00428   
00429     GiNaC::symbol a("a"), b("b"), c("c"), d("d"), e("e"), f("f"), r("r"), s("s"), D("D");
00430   
00431     // perform substitution
00432     if ( p[0].nops() == 3) {
00433       sub = GiNaC::lst(x == p[0].op(0) + a*r + b*s,   
00434                        y == p[0].op(1) + c*r + d*s, 
00435                        z == p[0].op(2) + e*r + f*s);  
00436       counter = 3;  
00437     } else if ( p[0].nops() == 2) { 
00438       sub = GiNaC::lst(t_repr.op(0), t_repr.op(1));  
00439       sub = GiNaC::lst(x == p[0].op(0) + a*r + b*s,   
00440                        y == p[0].op(1) + c*r + d*s); 
00441       counter = 2;  
00442     }
00443 
00444     GiNaC::ex intf = func.subs(sub); 
00445   
00446     counter++; 
00447     intf = GiNaC::integral(t_repr.op(counter).op(0), t_repr.op(counter).op(1), t_repr.op(counter).op(2), intf);  
00448     intf = eval_integ(intf); 
00449   
00450     counter--; 
00451     intf = GiNaC::integral(t_repr.op(counter).op(0), t_repr.op(counter).op(1), t_repr.op(counter).op(2), intf);  
00452     intf = eval_integ(intf); 
00453 
00454     intf = intf*D; 
00455     return intf; 
00456 
00457   }
00458   return DUMMY; 
00459   
00460 }
00461 
00462 
00463 
00464 //---        ReferenceTriangle ----------------------------
00465 
00466 
00467 ReferenceTriangle:: ReferenceTriangle(string subscript_) { 
00468   subscript = subscript_; 
00469   GiNaC::ex x0 = GiNaC::lst(0,0,0); 
00470   GiNaC::ex x1 = GiNaC::lst(1,0,0); 
00471   GiNaC::ex x2 = GiNaC::lst(0,1,0); 
00472   p.insert(p.end(), x0); 
00473   p.insert(p.end(), x1); 
00474   p.insert(p.end(), x2); 
00475 }
00476 
00477 int ReferenceTriangle:: no_vertices() { return 3; }
00478 
00479 GiNaC::ex ReferenceTriangle:: vertex (int i) {
00480   return Triangle::vertex(i); 
00481 }
00482 
00483 //GiNaC::ex ReferenceTriangle:: plane() {
00484 //  return Triangle:: plane(); 
00485 //}
00486 
00487 Line ReferenceTriangle:: line(int i) {
00488   return Triangle:: line(i); 
00489 }
00490 
00491 GiNaC::ex ReferenceTriangle:: repr(Repr_format format) {
00492   return Triangle:: repr(); 
00493 }
00494   
00495 string ReferenceTriangle:: str() {
00496    std::ostringstream s; 
00497 //   s <<"ReferenceTriangle("<<p[0]<<","<<p[1]<<","<<p[2]<<")"; 
00498    s <<"ReferenceTriangle"; 
00499    return s.str(); 
00500 }
00501 
00502 GiNaC::ex ReferenceTriangle:: integrate(GiNaC::ex f) {
00503   GiNaC::ex ret = GiNaC::eval_integ(
00504                   GiNaC::integral(y,0,1, 
00505                   GiNaC::eval_integ(
00506                   GiNaC::integral(x,0,1-y,f))));   
00507   return ret;  
00508 }
00509 
00510 // ---------- Rectangle -------------------------------------- 
00511 
00512 Rectangle:: Rectangle(GiNaC::ex p0, GiNaC::ex p1, string subscript_) { 
00513   subscript = subscript_; 
00514 
00515   GiNaC::ex x0; 
00516   GiNaC::ex x1; 
00517   GiNaC::ex x2; 
00518   GiNaC::ex x3; 
00519 
00520   if (p0.nops() == 2 && p1.nops() == 2) { 
00521 
00522     x0 = GiNaC::lst(p0.op(0), p0.op(1)); 
00523     x1 = GiNaC::lst(p1.op(0), p0.op(1)); 
00524     x2 = GiNaC::lst(p1.op(0), p1.op(1)); 
00525     x3 = GiNaC::lst(p0.op(0), p1.op(1)); 
00526   
00527   }
00528   else if (p0.nops() == 3 && p1.nops() == 3) { 
00529     if ( p0.op(0) == p1.op(0) ) { 
00530 
00531       x0 = GiNaC::lst(p0.op(0), p0.op(1), p0.op(2)); 
00532       x1 = GiNaC::lst(p0.op(0), p1.op(1), p0.op(2)); 
00533       x2 = GiNaC::lst(p0.op(0), p1.op(1), p1.op(2)); 
00534       x3 = GiNaC::lst(p0.op(0), p0.op(1), p1.op(2)); 
00535     
00536     } else if ( p0.op(1) == p1.op(1) ) { 
00537 
00538       x0 = GiNaC::lst(p0.op(0), p0.op(1), p0.op(2)); 
00539       x1 = GiNaC::lst(p1.op(0), p0.op(1), p0.op(2)); 
00540       x2 = GiNaC::lst(p1.op(0), p0.op(1), p1.op(2)); 
00541       x3 = GiNaC::lst(p0.op(0), p0.op(1), p1.op(2)); 
00542  
00543     } else if ( p0.op(2) == p1.op(2) ) {       
00544 
00545       x0 = GiNaC::lst(p0.op(0), p0.op(1), p0.op(2)); 
00546       x1 = GiNaC::lst(p1.op(0), p0.op(1), p0.op(2)); 
00547       x2 = GiNaC::lst(p1.op(0), p1.op(1), p0.op(2)); 
00548       x3 = GiNaC::lst(p0.op(0), p1.op(1), p0.op(2)); 
00549 
00550     }
00551   } else {
00552     throw(std::invalid_argument("The points p0 and p1 must be of dimention either 2 or 3."));
00553   }
00554 
00555   p.insert(p.end(), x0); 
00556   p.insert(p.end(), x1); 
00557   p.insert(p.end(), x2); 
00558   p.insert(p.end(), x3); 
00559 
00560 }
00561 
00562 int Rectangle:: no_vertices() { return 4; }
00563 
00564 GiNaC::ex Rectangle:: vertex (int i) {
00565   return p[i]; 
00566 }
00567 
00568 Line Rectangle:: line(int i) {
00569   if      ( i == 1) return Line(p[0],p[1], istr(subscript,i));  
00570   else if ( i == 2) return Line(p[1],p[2], istr(subscript,i));  
00571   else if ( i == 3) return Line(p[2],p[3], istr(subscript,i));  
00572   else if ( i == 4) return Line(p[3],p[0], istr(subscript,i));  
00573 }
00574 
00575 GiNaC::ex Rectangle:: repr(Repr_format format) {
00576    GiNaC::lst ret;   
00577    GiNaC::symbol r("r"), s("s"), t("t"); 
00578    if ( p[0].nops() == 2) {
00579      ret.append( x == p[0].op(0) + r*( p[2].op(0) - p[0].op(0))); 
00580      ret.append( y == p[0].op(1) + s*( p[2].op(1) - p[0].op(1))); 
00581      ret.append( GiNaC::lst(r,0,1)); 
00582      ret.append( GiNaC::lst(s,0,1)); 
00583    } else if ( p[0].nops() == 3) {
00584      ret.append( x == p[0].op(0) + r*( p[2].op(0) - p[0].op(0))); 
00585      ret.append( y == p[0].op(1) + s*( p[2].op(1) - p[0].op(1))); 
00586      ret.append( z == p[0].op(1) + t*( p[2].op(2) - p[0].op(2))); 
00587      ret.append( GiNaC::lst(r,0,1)); 
00588      ret.append( GiNaC::lst(s,0,1)); 
00589      ret.append( GiNaC::lst(t,0,1)); 
00590    }
00591    return ret; 
00592 }
00593 
00594 string Rectangle :: str() {
00595   return "Rectangle"; 
00596 }
00597  
00598 GiNaC::ex Rectangle:: integrate(GiNaC::ex func) {
00599 
00600     int counter; 
00601     GiNaC::ex s_repr = repr(); 
00602 
00603     GiNaC::lst sub; 
00604     // perform substitution
00605     if ( p[0].nops() == 3) {
00606       sub = GiNaC::lst(s_repr.op(0), s_repr.op(1), s_repr.op(2));  
00607       counter = 3;  
00608     } else if ( p[0].nops() == 2) { 
00609       sub = GiNaC::lst(s_repr.op(0), s_repr.op(1));  
00610       counter = 2;  
00611     }
00612 
00613     GiNaC::ex D; 
00614     if (p[0].nops() == 2) { 
00615       D =  ( p[2].op(0) - p[0].op(0)) 
00616           *( p[2].op(1) - p[0].op(1)); 
00617     } else if (p[0].nops() == 3) { 
00618 
00619       if ( p[2].op(0) == p[0].op(0) ) {   
00620         D =  ( p[2].op(1) - p[0].op(1)) 
00621             *( p[2].op(2) - p[0].op(2)); 
00622       } 
00623       else if ( p[2].op(1) == p[0].op(1) ) {   
00624         D =  ( p[2].op(0) - p[0].op(0)) 
00625             *( p[2].op(2) - p[0].op(2)); 
00626       }
00627       else if ( p[2].op(2) == p[0].op(2) ) {   
00628         D =  ( p[2].op(0) - p[0].op(0)) 
00629             *( p[2].op(1) - p[0].op(1)); 
00630       }
00631     }
00632 
00633     GiNaC::ex intf = func.subs(sub); 
00634      
00635     intf = intf*D; 
00636 
00637     intf = GiNaC::integral(s_repr.op(counter).op(0), s_repr.op(counter).op(1), s_repr.op(counter).op(2), intf);  
00638     intf = eval_integ(intf); 
00639   
00640     counter++; 
00641     intf = GiNaC::integral(s_repr.op(counter).op(0), s_repr.op(counter).op(1), s_repr.op(counter).op(2), intf);  
00642     intf = eval_integ(intf); 
00643 
00644     counter++; 
00645     if ( counter <  s_repr.nops() ) { 
00646       intf = GiNaC::integral(s_repr.op(counter).op(0), s_repr.op(counter).op(1), s_repr.op(counter).op(2), intf);  
00647       intf = eval_integ(intf); 
00648     }
00649    
00650     return intf; 
00651 
00652 
00653 }
00654 
00655 
00656 
00657 
00658 
00659 
00660 // ---------- ReferenceRectangle -------------------------------------- 
00661 
00662 ReferenceRectangle:: ReferenceRectangle(string subscript_) { 
00663   subscript = subscript_; 
00664   GiNaC::ex x0 = GiNaC::lst(0,0,0); 
00665   GiNaC::ex x1 = GiNaC::lst(1,0,0); 
00666   GiNaC::ex x2 = GiNaC::lst(1,1,0); 
00667   GiNaC::ex x3 = GiNaC::lst(0,1,0); 
00668   p.insert(p.end(), x0); 
00669   p.insert(p.end(), x1); 
00670   p.insert(p.end(), x2); 
00671   p.insert(p.end(), x3); 
00672 }
00673 
00674 int ReferenceRectangle:: no_vertices() { return 4; }
00675 
00676 GiNaC::ex ReferenceRectangle:: vertex (int i) {
00677   return p[i]; 
00678 }
00679 
00680 Line ReferenceRectangle:: line(int i) {
00681   return Rectangle::line(i); 
00682 }
00683 
00684 GiNaC::ex ReferenceRectangle:: repr(Repr_format format) {
00685   return Rectangle::repr(format); 
00686 }
00687 
00688 string ReferenceRectangle :: str() {
00689   return "ReferenceRectangle"; 
00690 }
00691  
00692 GiNaC::ex ReferenceRectangle:: integrate(GiNaC::ex func) {
00693   return Rectangle::integrate(func); 
00694 }
00695 
00696 
00697 
00698 
00699 
00700 //---        Tetrahedron ------------------------------------
00701 
00702 
00703 Tetrahedron:: Tetrahedron(GiNaC::ex x0, GiNaC::ex x1, GiNaC::ex x2, GiNaC::ex x3, string subscript_) { 
00704   subscript = subscript_; 
00705   p.insert(p.end(), x0); 
00706   p.insert(p.end(), x1); 
00707   p.insert(p.end(), x2); 
00708   p.insert(p.end(), x3); 
00709 
00710 }
00711 
00712 int Tetrahedron:: no_vertices() {return 4; }
00713 
00714 GiNaC::ex Tetrahedron:: vertex(int i) {
00715   return p[i]; 
00716 }
00717 
00718 Line Tetrahedron:: line(int i) {
00719   int i0, i1; 
00720   if ( i == 1 ) {
00721     i0 = 0; i1 = 1;  
00722   } else if ( i == 2 ) { 
00723     i0 = 0; i1 = 2;  
00724   } else if ( i == 3 )  { 
00725     i0 = 0; i1 = 3;  
00726   } else if ( i == 4 )  { 
00727     i0 = 1; i1 = 2;  
00728   } else if ( i == 5 )  { 
00729     i0 = 1; i1 = 3;  
00730   } else if ( i == 6 )  { 
00731     i0 = 2; i1 = 3;  
00732   }
00733   Line l = Line(p[i0], p[i1], istr(subscript,i)); 
00734   return l; 
00735 }
00736 
00737 Triangle Tetrahedron :: triangle(int i) {
00738   Triangle t = Triangle(p[i%4], p[(i+1)%4], p[(i+2)%4], istr(subscript,i)); 
00739   return t; 
00740 }
00741 
00742 string Tetrahedron:: str() {
00743    std::ostringstream s; 
00744 //   s <<"Tetrahedron("<<p[0]<<","<<p[1]<<","<<p[2]<<","<<p[3]<<")"; 
00745    s <<"Tetrahedron";
00746    return s.str(); 
00747 }
00748 
00749 
00750 GiNaC::ex Tetrahedron:: repr(Repr_format format) {
00751    GiNaC::symbol r("r"), s("s"), t("t"); 
00752    GiNaC::ex l1_repr = line(1).repr(r); 
00753    GiNaC::ex l2_repr = line(2).repr(s); 
00754    GiNaC::ex l3_repr = line(3).repr(t); 
00755    GiNaC::lst ret; 
00756 
00757 
00758    ret = GiNaC::lst( 
00759        x == l1_repr.op(0).rhs().coeff(r,0)   + l1_repr.op(0).rhs().coeff(r,1)*r 
00760          +  l2_repr.op(0).rhs().coeff(s,1)*s + l3_repr.op(0).rhs().coeff(t,1)*t,  
00761        y == l1_repr.op(1).rhs().coeff(r,0)   + l1_repr.op(1).rhs().coeff(r,1)*r 
00762          +  l2_repr.op(1).rhs().coeff(s,1)*s + l3_repr.op(1).rhs().coeff(t,1)*t,  
00763        z == l1_repr.op(2).rhs().coeff(r,0)   + l1_repr.op(1).rhs().coeff(r,1)*r  
00764          +  l2_repr.op(2).rhs().coeff(s,1)*s + l3_repr.op(2).rhs().coeff(t,1)*t);   
00765 
00766 
00767    ret.append(GiNaC::lst(r, 0, 1)); 
00768    ret.append(GiNaC::lst(s, 0, 1 - r)); 
00769    ret.append(GiNaC::lst(t, 0, 1 - r - s)); 
00770 
00771    return ret; 
00772 }
00773 
00774 GiNaC::ex Tetrahedron:: integrate(GiNaC::ex func, Repr_format format) {
00775   if ( format == SUBS_PERFORMED ) {
00776     GiNaC::ex t_repr = repr(); 
00777   
00778     //perform substitution
00779     GiNaC::lst sub = GiNaC::lst(t_repr.op(0), t_repr.op(1), t_repr.op(2));  
00780     GiNaC::ex intf = func.subs(sub); 
00781   
00782     // compute D 
00783     GiNaC::ex D; 
00784     GiNaC::ex r = t_repr.op(3).op(0); 
00785     GiNaC::ex s = t_repr.op(4).op(0); 
00786     GiNaC::ex t = t_repr.op(5).op(0); 
00787     GiNaC::ex a = t_repr.op(0).rhs().coeff(r,1); 
00788     GiNaC::ex b = t_repr.op(0).rhs().coeff(s,1); 
00789     GiNaC::ex c = t_repr.op(0).rhs().coeff(t,1); 
00790     GiNaC::ex d = t_repr.op(1).rhs().coeff(r,1); 
00791     GiNaC::ex e = t_repr.op(1).rhs().coeff(s,1); 
00792     GiNaC::ex f = t_repr.op(1).rhs().coeff(t,1); 
00793     GiNaC::ex g = t_repr.op(2).rhs().coeff(r,1); 
00794     GiNaC::ex h = t_repr.op(2).rhs().coeff(s,1); 
00795     GiNaC::ex k = t_repr.op(2).rhs().coeff(t,1); 
00796   
00797     D = a*(e*k-f*h) - b*(d*k-f*g) + c*(d*h - g*e); 
00798   
00799     intf = intf*D; 
00800   
00801     intf = GiNaC::integral(t_repr.op(5).op(0), t_repr.op(5).op(1), t_repr.op(5).op(2), intf);  
00802     intf = GiNaC::eval_integ(intf); 
00803   
00804     intf = GiNaC::integral(t_repr.op(4).op(0), t_repr.op(4).op(1), t_repr.op(4).op(2), intf);  
00805     intf = GiNaC::eval_integ(intf); 
00806   
00807     intf = GiNaC::integral(t_repr.op(3).op(0), t_repr.op(3).op(1), t_repr.op(3).op(2), intf);  
00808     intf = GiNaC::eval_integ(intf); 
00809   
00810     return intf; 
00811   } else if ( format == SUBS_NOT_PERFORMED ) {
00812     GiNaC::ex t_repr = repr(); 
00813   
00814     GiNaC::symbol a("a"), b("b"), c("c"), d("d"), e("e"), f("f"), g("g"), h("h"), k("k"), D("D");
00815     GiNaC::ex r = t_repr.op(3).op(0); 
00816     GiNaC::ex s = t_repr.op(4).op(0); 
00817     GiNaC::ex t = t_repr.op(5).op(0); 
00818 
00819     //perform substitution
00820 //    GiNaC::lst sub = GiNaC::lst(t_repr.op(0), t_repr.op(1), t_repr.op(2));  
00821     GiNaC::ex sub = GiNaC::lst(x == p[0].op(0) + a*r + b*s + c*t,   
00822                      y == p[0].op(1) + d*r + e*s + f*t, 
00823                      z == p[0].op(2) + g*r + h*s + k*t);  
00824 
00825     GiNaC::ex intf = func.subs(sub); 
00826 
00827     intf = GiNaC::integral(t_repr.op(5).op(0), t_repr.op(5).op(1), t_repr.op(5).op(2), intf);  
00828     intf = GiNaC::eval_integ(intf); 
00829   
00830     intf = GiNaC::integral(t_repr.op(4).op(0), t_repr.op(4).op(1), t_repr.op(4).op(2), intf);  
00831     intf = GiNaC::eval_integ(intf); 
00832   
00833     intf = GiNaC::integral(t_repr.op(3).op(0), t_repr.op(3).op(1), t_repr.op(3).op(2), intf);  
00834     intf = GiNaC::eval_integ(intf); 
00835   
00836     intf = intf*D; 
00837 
00838     return intf; 
00839 
00840   }
00841   return DUMMY; 
00842 }
00843 
00844 //---        ReferenceTetrahedron ---------------------------
00845 
00846 ReferenceTetrahedron:: ReferenceTetrahedron(string subscript_) : Tetrahedron(subscript_) {
00847   subscript = subscript_;  
00848   GiNaC::ex x0 = GiNaC::lst(0, 0, 0); 
00849   GiNaC::ex x1 = GiNaC::lst(1, 0, 0); 
00850   GiNaC::ex x2 = GiNaC::lst(0, 1, 0); 
00851   GiNaC::ex x3 = GiNaC::lst(0, 0, 1); 
00852 
00853   p.insert(p.end(), x0); 
00854   p.insert(p.end(), x1); 
00855   p.insert(p.end(), x2); 
00856   p.insert(p.end(), x3); 
00857 }
00858 
00859 int ReferenceTetrahedron:: no_vertices () {
00860    return 4; 
00861 }
00862 
00863 GiNaC::ex ReferenceTetrahedron:: vertex(int i) {
00864    return Tetrahedron:: vertex(i); 
00865 }
00866 
00867 Line ReferenceTetrahedron:: line(int i) {
00868    return Tetrahedron:: line(i); 
00869 }
00870 
00871 Triangle ReferenceTetrahedron :: triangle(int i) {
00872    return Tetrahedron:: triangle(i); 
00873 }
00874 
00875 string ReferenceTetrahedron:: str() {
00876    std::ostringstream s; 
00877 //   s <<"ReferenceTetrahedron("<<p[0]<<","<<p[1]<<","<<p[2]<<","<<p[3]<<")"<<endl; 
00878    s <<"ReferenceTetrahedron"; 
00879    return s.str(); 
00880 }
00881 
00882 GiNaC::ex ReferenceTetrahedron:: integrate(GiNaC::ex f, Repr_format format) {
00883   
00884   GiNaC::ex intf = GiNaC::integral(x,0,1-y-z,f); 
00885   intf = GiNaC::eval_integ(intf); 
00886 
00887   intf = GiNaC::integral(y,0,1-z, intf); 
00888   intf = GiNaC::eval_integ(intf); 
00889 
00890   intf = GiNaC::integral(z,0,1, intf);  
00891   intf = GiNaC::eval_integ(intf); 
00892 
00893   return intf;  
00894 }
00895 
00896 
00897 //--  tools for Polygons ------------------------------------------------------ 
00898 
00899 GiNaC::lst bezier_ordinates(Tetrahedron& tetrahedra, int d) {
00900 
00901   //FIXME: ugly conversion to matrix 
00902 
00903   GiNaC::lst ret; 
00904   GiNaC::ex V1 = tetrahedra.vertex(0); 
00905   GiNaC::ex V2 = tetrahedra.vertex(1); 
00906   GiNaC::ex V3 = tetrahedra.vertex(2); 
00907   GiNaC::ex V4 = tetrahedra.vertex(3); 
00908 
00909   GiNaC::lst V1l = GiNaC::ex_to<GiNaC::lst>(V1); 
00910   GiNaC::lst V2l = GiNaC::ex_to<GiNaC::lst>(V2); 
00911   GiNaC::lst V3l = GiNaC::ex_to<GiNaC::lst>(V3); 
00912   GiNaC::lst V4l = GiNaC::ex_to<GiNaC::lst>(V4); 
00913 
00914 
00915   GiNaC::ex V1m  = lst_to_matrix2(V1l); 
00916   GiNaC::ex V2m  = lst_to_matrix2(V2l); 
00917   GiNaC::ex V3m  = lst_to_matrix2(V3l); 
00918   GiNaC::ex V4m  = lst_to_matrix2(V4l); 
00919 
00920   int l; 
00921   for (int i=0; i<= d; i++) {
00922     for (int j=0; j<= d; j++) {
00923       for (int k=0; k<= d; k++) {
00924         if ( d - i - j -k  >= 0 ) { 
00925           l= d - i - j -k; 
00926           GiNaC::ex sum = (l*V1m + k*V2m + j*V3m + i*V4m)/d;  
00927           ret.append(matrix_to_lst2(sum.evalm())); 
00928         }
00929       }
00930     }
00931   }
00932   // FIXME how should these be sorted ?????  
00933 //  ret = ret.sort(); 
00934   return ret; 
00935 }
00936 
00937 
00938 
00939 GiNaC::lst bezier_ordinates(Triangle& triangle, int d) {
00940 
00941   //FIXME: ugly conversion to matrix 
00942 
00943   GiNaC::lst ret; 
00944   GiNaC::ex V1 = triangle.vertex(0); 
00945   GiNaC::ex V2 = triangle.vertex(1); 
00946   GiNaC::ex V3 = triangle.vertex(2); 
00947 
00948   GiNaC::lst V1l = GiNaC::ex_to<GiNaC::lst>(V1); 
00949   GiNaC::lst V2l = GiNaC::ex_to<GiNaC::lst>(V2); 
00950   GiNaC::lst V3l = GiNaC::ex_to<GiNaC::lst>(V3); 
00951 
00952   GiNaC::ex V1m  = lst_to_matrix2(V1l); 
00953   GiNaC::ex V2m  = lst_to_matrix2(V2l); 
00954   GiNaC::ex V3m  = lst_to_matrix2(V3l); 
00955 
00956 
00957   int k; 
00958   for (int i=0; i <= d; i++) {
00959     for (int j=0; j <= d; j++) {
00960       if ( d - i - j >= 0  ) { 
00961         k = d - i - j; 
00962         GiNaC::ex sum = (k*V1m + j*V2m + i*V3m)/d;  
00963         ret.append(matrix_to_lst2(sum.evalm())); 
00964       }
00965     }
00966   }
00967   // FIXME how should these be sorted ?????  
00968   // ret = ret.sort(); 
00969   return ret; 
00970 }
00971 
00972 // FIXME barycenter_line, barycenter_triangle, barycenter_tetrahedron
00973 // all needs to determine which equations to use in a proper way 
00974 
00975 GiNaC::ex barycenter_line(GiNaC::ex p0, GiNaC::ex p1) {
00976  GiNaC::ex sol = DUMMY;  
00977 
00978  // 1D
00979  if ( p0.nops() == 1 && p1.nops() == 1 ) {
00980    GiNaC::symbol b0("b0"), b1("b1");
00981    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0); 
00982    GiNaC::ex eq2 = 1 == b0 + b1; 
00983    sol = lsolve(GiNaC::lst(eq1, eq2), GiNaC::lst(b0, b1)); 
00984    if ( sol == 0 ) {
00985      GiNaC::ex eq1 = y == b0*p0.op(1) + b1*p1.op(1); 
00986      sol = lsolve(GiNaC::lst(eq1, eq2), GiNaC::lst(b0, b1)); 
00987    }
00988    if ( sol == 0 ) {
00989      GiNaC::ex eq1 = z == b0*p0.op(2) + b1*p1.op(2); 
00990      sol = lsolve(GiNaC::lst(eq1, eq2), GiNaC::lst(b0, b1)); 
00991    }
00992  }
00993  //2D 
00994  else if ( p0.nops() == 2 && p1.nops() == 2 ) {
00995    GiNaC::symbol b0("b0"), b1("b1");
00996    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0); 
00997    GiNaC::ex eq3 = 1 == b0 + b1; 
00998    sol = lsolve(GiNaC::lst(eq1, eq3), GiNaC::lst(b0, b1)); 
00999    if (sol.nops() == 0) {  
01000      GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1); 
01001      sol = lsolve(GiNaC::lst(eq2, eq3), GiNaC::lst(b0, b1)); 
01002    }
01003  }
01004  //3D 
01005  else if ( p0.nops() == 3 && p1.nops() == 3 ) {
01006    GiNaC::symbol b0("b0"), b1("b1");
01007    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0); 
01008    GiNaC::ex eq4 = 1 == b0 + b1; 
01009    sol = lsolve(GiNaC::lst(eq1, eq4), GiNaC::lst(b0, b1)); 
01010    if (sol.nops() == 0) {  
01011      GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1); 
01012      sol = lsolve(GiNaC::lst(eq2, eq4), GiNaC::lst(b0, b1)); 
01013    }
01014    if (sol.nops() == 0) {  
01015      GiNaC::ex eq3 = z == b0*p0.op(2) + b1*p1.op(2); 
01016      sol = lsolve(GiNaC::lst(eq3, eq4), GiNaC::lst(b0, b1)); 
01017    }
01018  } 
01019  else {
01020    cout <<"Could not compute the barycentric coordinates."<<endl; 
01021    cout <<"Check the coordinates."<<endl;
01022  }
01023  return sol; 
01024 }
01025 
01026 
01027 
01028 GiNaC::ex barycenter_triangle(GiNaC::ex p0, GiNaC::ex p1, GiNaC::ex p2) {
01029  GiNaC::ex sol; 
01030  sol = DUMMY; 
01031 
01032  // 2D 
01033  if ( p0.nops() == 2 && p1.nops() == 2 && p2.nops() == 2) {
01034    GiNaC::symbol b0("b0"), b1("b1"), b2("b2");
01035    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0) + b2*p2.op(0); 
01036    GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1) + b2*p2.op(1); 
01037    GiNaC::ex eq3 = 1 == b0 + b1 + b2; 
01038   
01039    sol = lsolve(GiNaC::lst(eq1, eq2, eq3), GiNaC::lst(b0, b1, b2)); 
01040  } 
01041  // 3D 
01042  else if ( p0.nops() == 3 && p1.nops() == 3 && p2.nops() == 3) {
01043    GiNaC::symbol b0("b0"), b1("b1"), b2("b2");
01044    GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0) + b2*p2.op(0); 
01045    GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1) + b2*p2.op(1); 
01046    GiNaC::ex eq3 = z == b0*p0.op(2) + b1*p1.op(2) + b2*p2.op(2); 
01047    GiNaC::ex eq4 = 1 == b0 + b1 + b2; 
01048   
01049    sol = lsolve(GiNaC::lst(eq1, eq2, eq4), GiNaC::lst(b0, b1, b2)); 
01050    if ( sol.nops() == 0 ) {
01051      sol = lsolve(GiNaC::lst(eq1, eq3, eq4), GiNaC::lst(b0, b1, b2)); 
01052    }
01053    if ( sol.nops() == 0 ) {
01054      sol = lsolve(GiNaC::lst(eq2, eq3, eq4), GiNaC::lst(b0, b1, b2)); 
01055    }
01056  }
01057   
01058   
01059 
01060  return sol; 
01061 }
01062 
01063 GiNaC::ex barycenter_tetrahedron(GiNaC::ex p0, GiNaC::ex p1, GiNaC::ex p2, GiNaC::ex p3) {
01064  GiNaC::symbol b0("b0"), b1("b1"), b2("b2"), b3("b3");
01065 
01066  // 3D 
01067  GiNaC::ex eq1 = x == b0*p0.op(0) + b1*p1.op(0) + b2*p2.op(0) + b3*p3.op(0); 
01068  GiNaC::ex eq2 = y == b0*p0.op(1) + b1*p1.op(1) + b2*p2.op(1) + b3*p3.op(1); 
01069  GiNaC::ex eq3 = z == b0*p0.op(2) + b1*p1.op(2) + b2*p2.op(2) + b3*p3.op(2); 
01070  GiNaC::ex eq4 = 1 == b0 + b1 + b2 +b3; 
01071 
01072  GiNaC::ex sol = lsolve(GiNaC::lst(eq1, eq2, eq3, eq4), GiNaC::lst(b0, b1, b2, b3)); 
01073 
01074  return sol; 
01075 
01076 }
01077 
01078 GiNaC::ex bernstein(int order, Polygon& p, const string a) {
01079 
01080   if ( order < 0 ) {
01081     cout <<"Can not create polynomials of order less than 0!"<<endl; 
01082     return DUMMY; 
01083   }
01084 
01085   GiNaC::ex ret; // GiNaC::ex to return   
01086   int dof;       // degrees of freedom  
01087   GiNaC::ex A;   // GiNaC::ex holding the coefficients a_0 .. a_dof  
01088   GiNaC::lst basis; 
01089 
01090   if ( p.str() == "Line" || p.str() == "ReferenceLine" ) {
01091     GiNaC::ex bary = barycenter_line(p.vertex(0), p.vertex(1)); 
01092     GiNaC::ex b0= bary.op(0).rhs(); 
01093     GiNaC::ex b1= bary.op(1).rhs(); 
01094     dof = order+1; 
01095     A = GiNaC::symbolic_matrix(1,dof, a); 
01096     int o=0; 
01097     for (GiNaC::const_iterator i = A.begin(); i != A.end(); ++i)  {  
01098       ret += (*i)*GiNaC::binomial(order,o)*pow(b0,o)*pow(b1,order-o);  
01099       basis.append(pow(b0,o)*pow(b1,order-o));  
01100       o++; 
01101     }
01102   }
01103   else if ( p.str() == "Triangle" || p.str() == "ReferenceTriangle" )  {
01104 
01105     dof = (order+1)*(order+2)/2; 
01106     A = GiNaC::symbolic_matrix(1, dof , a); 
01107 
01108     GiNaC::ex bary = barycenter_triangle(p.vertex(0), p.vertex(1), p.vertex(2)); 
01109     GiNaC::ex b0= bary.op(0).rhs(); 
01110     GiNaC::ex b1= bary.op(1).rhs(); 
01111     GiNaC::ex b2= bary.op(2).rhs(); 
01112 
01113     size_t i=0; 
01114     for (int o1 = 0; o1 <= order; o1++) {
01115       for (int o2 = 0; o2 <= order; o2++) {
01116         for (int o3 = 0; o3 <= order; o3++) {
01117           if ( o1 + o2 + o3 == order ) { 
01118             ret += A.op(i)*(GiNaC::factorial(order)/(GiNaC::factorial(o1)*GiNaC::factorial(o2)*GiNaC::factorial(o3)))
01119                    *pow(b0,o1)*pow(b1,o2)*pow(b2,o3);  
01120 
01121             basis.append(pow(b0,o1)*pow(b1,o2)*pow(b2,o3));  
01122             i++; 
01123           }
01124         }
01125       }
01126     }
01127   }
01128   else if (p.str() == "Tetrahedron" || p.str() == "ReferenceTetrahedron") {
01129 
01130 
01131     dof = 0; 
01132     for (int j=0; j<= order; j++) { 
01133       dof += (j+1)*(j+2)/2; 
01134     }
01135     A = GiNaC::symbolic_matrix(1, dof , a); 
01136 
01137 
01138     GiNaC::ex bary = barycenter_tetrahedron(p.vertex(0), p.vertex(1), p.vertex(2), p.vertex(3)); 
01139     GiNaC::ex b0= bary.op(0).rhs(); 
01140     GiNaC::ex b1= bary.op(1).rhs(); 
01141     GiNaC::ex b2= bary.op(2).rhs(); 
01142     GiNaC::ex b3= bary.op(3).rhs(); 
01143 
01144 
01145     size_t i=0; 
01146     for (int o1 = 0; o1 <= order; o1++) {
01147       for (int o2 = 0; o2 <= order; o2++) {
01148         for (int o3 = 0; o3 <= order; o3++) {
01149           for (int o4 = 0; o4 <= order; o4++) {
01150             if ( o1 + o2 + o3 + o4 == order ) { 
01151               ret += A.op(i)*(GiNaC::factorial(order)/(GiNaC::factorial(o1)*GiNaC::factorial(o2)*GiNaC::factorial(o3)*GiNaC::factorial(o4)))
01152                    *pow(b0,o1)*pow(b1,o2)*pow(b2,o3)*pow(b3,o4);  
01153               basis.append(pow(b0,o1)*pow(b1,o2)*pow(b2,o3)*pow(b3,o4));
01154               i++; 
01155             }
01156           }
01157         }
01158       }
01159     }
01160   }
01161   return GiNaC::lst(ret,matrix_to_lst2(A),basis); 
01162 }
01163 
01164 GiNaC::lst bernsteinv(int no_fields, int order, Polygon& p, const string a) {
01165 
01166   if ( order < 0 ) {
01167     cout <<"Can not create polynomials of order less than 0!"<<endl; 
01168     return GiNaC::lst(DUMMY); 
01169   }
01170 
01171   GiNaC::lst ret1;  // contains the polynom  
01172   GiNaC::lst ret2;  // contains the coefficients   
01173   GiNaC::lst ret3;  // constains the basis functions  
01174   GiNaC::lst basis_tmp; 
01175   for (int i=1; i<= no_fields; i++) { 
01176     GiNaC::lst basis; 
01177     std::ostringstream s; 
01178     s <<a<<""<<i<<"_"; 
01179     GiNaC::ex pol = bernstein(order, p, s.str()); 
01180     ret1.append(pol.op(0)); 
01181     ret2.append(pol.op(1)); 
01182     basis_tmp = GiNaC::ex_to<GiNaC::lst>(pol.op(2)); 
01183     for (GiNaC::lst::const_iterator basis_iterator = basis_tmp.begin(); 
01184          basis_iterator != basis_tmp.end(); ++basis_iterator) {
01185       GiNaC::lst tmp_lst; 
01186       for (int d=1; d<=no_fields; d++) tmp_lst.append(0);   
01187       tmp_lst.let_op(i-1) = (*basis_iterator);  
01188       ret3.append(tmp_lst); 
01189     }
01190   }
01191   return GiNaC::lst(ret1,ret2,ret3); 
01192 
01193 }
01194 
01195 GiNaC::lst normal(Tetrahedron& tetrahedron, int i){
01196   Triangle triangle = tetrahedron.triangle(i); 
01197 
01198   GiNaC::symbol t("t"); 
01199   GiNaC::ex line1_repr = triangle.line(1).repr(t); 
01200   GiNaC::ex n11 = line1_repr.op(0).rhs().coeff(t,1); 
01201   GiNaC::ex n12 = line1_repr.op(1).rhs().coeff(t,1); 
01202   GiNaC::ex n13 = line1_repr.op(2).rhs().coeff(t,1); 
01203 
01204   GiNaC::ex line2_repr = triangle.line(2).repr(t); 
01205   GiNaC::ex n21 = line2_repr.op(0).rhs().coeff(t,1); 
01206   GiNaC::ex n22 = line2_repr.op(1).rhs().coeff(t,1); 
01207   GiNaC::ex n23 = line2_repr.op(2).rhs().coeff(t,1); 
01208 
01209   GiNaC::lst n1 = GiNaC::lst(n11,n12,n13); 
01210   GiNaC::lst n2 = GiNaC::lst(n21,n22,n23); 
01211   GiNaC::lst n3 = cross(n1,n2);  
01212 
01213   GiNaC::ex norm = sqrt(pow(n3.op(0),2) 
01214                       + pow(n3.op(1),2) 
01215                       + pow(n3.op(2),2));
01216 
01217   n3.let_op(0) = n3.op(0)/norm;
01218   n3.let_op(1) = n3.op(1)/norm;
01219   n3.let_op(2) = n3.op(2)/norm;
01220 
01221   return n3; 
01222 }
01223 
01224 
01225 GiNaC::lst normal(Triangle& triangle, int i){
01226   Line line = triangle.line(i); 
01227   //FIXME: 5 lines to compute the normal vector, these should
01228   // be put somewhere else.   
01229   GiNaC::symbol t("t"); 
01230   GiNaC::ex line_repr = line.repr(t); 
01231   GiNaC::ex n1 = line_repr.op(0).rhs().coeff(t,1); 
01232   GiNaC::ex n2 = line_repr.op(1).rhs().coeff(t,1); 
01233   GiNaC::ex norm = sqrt(pow(n1,2) + pow(n2,2));
01234   GiNaC::lst normal = GiNaC::lst(n2/norm,-n1/norm);  
01235 return normal; 
01236 }
01237 
01238 GiNaC::lst tangent(Triangle& triangle, int i){
01239   Line line = triangle.line(i); 
01240   //FIXME: 5 lines to compute the tangent vector, these should
01241   // be put somewhere else.   
01242   GiNaC::symbol t("t"); 
01243   GiNaC::ex line_repr = line.repr(t); 
01244   GiNaC::ex t1 = line_repr.op(0).rhs().coeff(t,1); 
01245   GiNaC::ex t2 = line_repr.op(1).rhs().coeff(t,1); 
01246   GiNaC::ex norm = sqrt(pow(t1,2) + pow(t2,2));
01247   GiNaC::lst tangent = GiNaC::lst(t1/norm,t2/norm);  
01248 return tangent; 
01249 }
01250 
01251 
01252 // ---------- Box -------------------------------------- 
01253 
01254 Box:: Box(GiNaC::ex p0, GiNaC::ex p1, string subscript_) { 
01255   subscript = subscript_; 
01256   GiNaC::ex x0 = GiNaC::lst(p0.op(0),p0.op(1),p0.op(2)); 
01257   GiNaC::ex x1 = GiNaC::lst(p1.op(0),p0.op(1),p0.op(2)); 
01258   GiNaC::ex x2 = GiNaC::lst(p1.op(0),p1.op(1),p0.op(2)); 
01259   GiNaC::ex x3 = GiNaC::lst(p0.op(0),p1.op(1),p0.op(2)); 
01260 
01261   GiNaC::ex x4 = GiNaC::lst(p0.op(0),p0.op(1),p1.op(2)); 
01262   GiNaC::ex x5 = GiNaC::lst(p1.op(0),p0.op(1),p1.op(2)); 
01263   GiNaC::ex x6 = GiNaC::lst(p1.op(0),p1.op(1),p1.op(2)); 
01264   GiNaC::ex x7 = GiNaC::lst(p0.op(0),p1.op(1),p1.op(2)); 
01265 
01266   p.insert(p.end(), x0); 
01267   p.insert(p.end(), x1); 
01268   p.insert(p.end(), x2); 
01269   p.insert(p.end(), x3); 
01270 
01271   p.insert(p.end(), x4); 
01272   p.insert(p.end(), x5); 
01273   p.insert(p.end(), x6); 
01274   p.insert(p.end(), x7); 
01275 
01276 }
01277 
01278 int Box:: no_vertices() { return 8; }
01279 
01280 GiNaC::ex Box:: vertex (int i) {
01281   return p[i]; 
01282 }
01283 
01284 Line Box:: line(int i) {
01285   if      ( i == 1) return Line(p[0],p[1], istr(subscript,i));  
01286   else if ( i == 2) return Line(p[1],p[2], istr(subscript,i));  
01287   else if ( i == 3) return Line(p[2],p[3], istr(subscript,i));  
01288   else if ( i == 4) return Line(p[3],p[0], istr(subscript,i));  
01289 
01290   else if ( i == 5) return Line(p[4],p[5], istr(subscript,i));  
01291   else if ( i == 6) return Line(p[5],p[6], istr(subscript,i));  
01292   else if ( i == 7) return Line(p[6],p[7], istr(subscript,i));  
01293   else if ( i == 8) return Line(p[7],p[4], istr(subscript,i));  
01294 
01295   else if ( i == 9)  return Line(p[0],p[4], istr(subscript,i));  
01296   else if ( i == 10) return Line(p[1],p[5], istr(subscript,i));  
01297   else if ( i == 11) return Line(p[2],p[6], istr(subscript,i));  
01298   else if ( i == 12) return Line(p[3],p[7], istr(subscript,i));  
01299 }
01300 
01301 GiNaC::ex Box:: repr(Repr_format format) {
01302    GiNaC::lst ret;   
01303    GiNaC::symbol r("r"), s("s"), t("t"); 
01304    ret.append( x == p[0].op(0) + r*( p[6].op(0) - p[0].op(0))); 
01305    ret.append( y == p[0].op(1) + s*( p[6].op(1) - p[0].op(1))); 
01306    ret.append( z == p[0].op(1) + t*( p[6].op(2) - p[0].op(2))); 
01307    ret.append( GiNaC::lst(r,0,1)); 
01308    ret.append( GiNaC::lst(s,0,1)); 
01309    ret.append( GiNaC::lst(t,0,1)); 
01310    return ret; 
01311 }
01312 
01313 string Box :: str() {
01314   return "Box"; 
01315 }
01316  
01317 GiNaC::ex Box:: integrate(GiNaC::ex func) {
01318 
01319     GiNaC::ex b_repr = repr(); 
01320 
01321     GiNaC::lst sub; 
01322     sub = GiNaC::lst(b_repr.op(0), b_repr.op(1), b_repr.op(2));  
01323     GiNaC::ex intf = func.subs(sub); 
01324 
01325     GiNaC::ex D =  ( p[6].op(0) - p[0].op(0))
01326                   *( p[6].op(1) - p[0].op(1)) 
01327                   *( p[6].op(2) - p[0].op(2)); 
01328      
01329 
01330     
01331 
01332     
01333     intf = intf*D; 
01334 
01335     intf = GiNaC::integral(b_repr.op(3).op(0), b_repr.op(3).op(1), b_repr.op(3).op(2), intf);  
01336     intf = eval_integ(intf); 
01337   
01338     intf = GiNaC::integral(b_repr.op(4).op(0), b_repr.op(4).op(1), b_repr.op(4).op(2), intf);  
01339     intf = eval_integ(intf); 
01340 
01341     intf = GiNaC::integral(b_repr.op(5).op(0), b_repr.op(5).op(1), b_repr.op(5).op(2), intf);  
01342     intf = eval_integ(intf); 
01343    
01344     return intf; 
01345 
01346 
01347 }
01348 
01349 // ---------- ReferenceBox -------------------------------------- 
01350 
01351 ReferenceBox:: ReferenceBox(string subscript_) { 
01352   subscript = subscript_; 
01353   GiNaC::ex x0 = GiNaC::lst(0,0,0); 
01354   GiNaC::ex x1 = GiNaC::lst(1,0,0); 
01355   GiNaC::ex x2 = GiNaC::lst(1,1,0); 
01356   GiNaC::ex x3 = GiNaC::lst(0,1,0); 
01357 
01358   GiNaC::ex x4 = GiNaC::lst(0,0,1); 
01359   GiNaC::ex x5 = GiNaC::lst(1,0,1); 
01360   GiNaC::ex x6 = GiNaC::lst(1,1,1); 
01361   GiNaC::ex x7 = GiNaC::lst(0,1,1); 
01362 
01363   p.insert(p.end(), x0); 
01364   p.insert(p.end(), x1); 
01365   p.insert(p.end(), x2); 
01366   p.insert(p.end(), x3); 
01367 
01368   p.insert(p.end(), x4); 
01369   p.insert(p.end(), x5); 
01370   p.insert(p.end(), x6); 
01371   p.insert(p.end(), x7); 
01372 
01373 }
01374 
01375 int ReferenceBox:: no_vertices() { return 8; }
01376 
01377 GiNaC::ex ReferenceBox:: vertex (int i) {
01378   return Box::vertex(i); 
01379 }
01380 
01381 Line ReferenceBox:: line(int i) {
01382   return Box::line(i); 
01383 }
01384 
01385 GiNaC::ex ReferenceBox:: repr(Repr_format format) {
01386   return Box::repr(format); 
01387 }
01388 
01389 string ReferenceBox :: str() {
01390   return "ReferenceBox"; 
01391 }
01392  
01393 GiNaC::ex ReferenceBox:: integrate(GiNaC::ex func) {
01394   return Box::integrate(func); 
01395 }
01396 
01397 
01398 
01399 

Generated on Wed Apr 19 12:38:14 2006 for SyFi by  doxygen 1.4.4