realroot_doc 0.1.1
/Users/mourrain/Devel/mmx/realroot/include/realroot/fatarcs.hpp
Go to the documentation of this file.
00001 #include <stack>
00002 #include <fstream>
00003 #include <string>
00004 #include <vector>
00005 
00006 #include <realroot/Interval.hpp>
00007 #include <realroot/polynomial_bernstein.hpp>
00008 #include <realroot/polynomial_tensor.hpp>
00009 #include <realroot/tensor_convert.hpp>
00010 
00011 #pragma once
00012 
00013 #define REP    poly.rep()
00014 #define SIZE   poly.size()
00015 #define TODOUBLE as<double>
00016 
00017 using namespace mmx;
00018 
00019 
00021 //BOX structure
00022 template<class C>
00023 struct domain
00024   { 
00025     typedef Interval<C>         int_t;
00026     typedef Seq< Interval<C> >  seqint_t;
00027     typedef std::vector<C>      vec_t;
00028 
00029 //CONSTRUCTORS
00030 
00031     seqint_t     I;
00032    
00033 
00034     domain( ){ }; 
00035     domain( int n ){ int_t unit( C(0),C(1) ); for(int i = 0; i < n; i++){I<<unit;}; }; 
00036     domain( int_t intxy ){ I<<intxy<<intxy; };
00037     domain( int_t intx , int_t inty ){ I<<intx<<inty; };
00038  
00039 //FCTS
00040     C dim(){
00041       int d=0; 
00042       for(unsigned i = 0; i < I.size(); i++){d++;}
00043       return(d);
00044     }
00045  
00046 
00047     C diam(){
00048       C d=C(0); 
00049       for(unsigned i = 0; i < I.size(); i++){
00050           d +=I[i].size()*I[i].size();}
00051       return(sqrt(d));
00052     }
00053  
00054   vec_t llc( )
00055     {vec_t v(I.size());
00056       for(unsigned i = 0; i < I.size(); i++){
00057           v[i]= I[i].m;};
00058       return v;
00059     };
00060 
00061   vec_t urc( )
00062     { vec_t v(I.size());
00063       for(unsigned i = 0; i < I.size(); i++){
00064           v[i]= I[i].M;};
00065       return v;
00066     };
00067 
00068   vec_t center( )
00069     { vec_t v(I.size());
00070       for(unsigned i = 0; i < I.size(); i++){
00071           v[i]= I[i].center();};
00072       return v;
00073     };
00074 
00075 
00076   Seq<C> delta( )
00077     {Seq<C> d; 
00078       for(unsigned i = 0; i < I.size(); i++){
00079           d<<I[i].size();}
00080       return(d);
00081     };
00082  
00083   void print(int digits)
00084     { std::cout.precision(digits);
00085       std::cout<<"["<< TODOUBLE(I[0].m)<<", "<< TODOUBLE(I[0].M)<<"]x["<< TODOUBLE(I[1].m)<<", "<< TODOUBLE(I[1].M)<<"],"<<std::endl;
00086       // std::cout << "box midpt: (" <<(llc()[0]+urc()[0])/C(2)<<","<<(llc()[1]+urc()[1])/C(2)<<")"<<std::endl;
00087       std::cout << "diam: " <<diam()<<std::endl;
00088     };
00089 
00090 
00091   void split(domain<C> * ch)
00092     { 
00093      
00094       C cx=I[0].center() ;
00095       C cy=I[1].center() ;
00096      
00097       Interval<C> Ixl(I[0].m , cx), Ixr(cx , I[0].M), Iyl(I[1].m , cy), Iyr(cy, I[1].M);
00098 
00099      
00100       ch[0]=domain(Ixl,Iyl);
00101       ch[1]=domain(Ixr,Iyl);
00102       ch[2]=domain(Ixl,Iyr);
00103       ch[3]=domain(Ixr,Iyr);
00104     };/*subdivison of a box*/
00105     /*
00106 Seq< vec_t > cornerpts( )
00107     { Seq< vec_t > cp;
00108       cp<<vec(I[0].m,I[1].m)<<vec(I[0].M,I[1].m)<<vec(I[0].m,I[1].M)<<vec(I[0].M,I[1].M);
00109      return cp;
00110      };*/
00111 
00112 };//end of boxes
00113 
00114 
00116 //arc_rep structure
00117 
00118 template<class C>
00119 struct arc_rep
00120 {
00121 
00122   typedef C                                              coeff_t;
00123   typedef std::vector<coeff_t>                           vec_t;
00124   typedef Seq<coeff_t>                                   seq_t;
00125   typedef domain<coeff_t>                                box_t;
00126   typedef polynomial<  coeff_t ,with<Bernstein>  >       bernstein_t;
00127   typedef polynomial<  coeff_t ,with<MonomialTensor> >   monom_t;
00128  
00129  
00130 
00131    vec_t pts[3];
00132     
00133   //CONSTRUCTORS
00134 
00135   arc_rep(){pts[0]=vec_t(); pts[1]=vec_t(); pts[2]=vec_t();};
00136 
00137   arc_rep( vec_t p0,  vec_t p1, vec_t p2){
00138     if(p0.size()!=0 && p1.size()!=0 &&  p2.size()!=0 )
00139       {if(matrat(v_minus(p1,p0),v_minus(p2,p0))[1]> coeff_t(0)){pts[0]=p2; pts[1]=p1; pts[2]=p0;}
00140         else{pts[0]=p0; pts[1]=p1; pts[2]=p2;}; }else{pts[0]=p0; pts[1]=p1; pts[2]=p2;}
00141   };
00142 
00143   arc_rep( vec_t p[3]){
00144     if(p[0].size()!=0 && p[1].size()!=0 &&  p[2].size()!=0 ){
00145       if(matrat( v_minus(p[1],p[0]),v_minus(p[2],p[0]) )[1]> coeff_t(0)){pts[0]=p[2]; pts[1]=p[1]; pts[2]=p[0];}
00146       else{pts[0]=p[0]; pts[1]=p[1]; pts[2]=p[2];}; }else{pts[0]=p[0]; pts[1]=p[1]; pts[2]=p[2];} 
00147   };
00148  
00149   //FCTS
00150 
00151  
00152   coeff_t weight()
00153   {return(dot(v_minus(pts[0],pts[1]),v_minus(pts[1],pts[2]))/
00154           (v_length(v_minus(pts[1],pts[2]))*v_length(v_minus(pts[1],pts[0]))));};
00155   
00156  
00157   vec_t midc(){   
00158     vec_t pp=v_minus(pts[0],pts[2]); pp=rotl(pp);
00159     vec_t m=v_mul(coeff_t( sign(dot(pp, v_minus(pts[1],pts[2]) ))),pp);
00160     coeff_t w=weight(); 
00161   
00162     vec_t d;
00163     if( (coeff_t(1)-w*w) > coeff_t(0) && w!=coeff_t(0) ){
00164       d=v_plus(v_div(v_plus(pts[0],pts[2]),coeff_t(2)),v_div(v_mul(coeff_t(sqrt( coeff_t(1)-w*w )),m),(coeff_t(2)*w))); }
00165     else {
00166       d=v_div(v_plus(pts[0],pts[2]),coeff_t(2)); };
00167     return(d);
00168 
00169   };/*middle control point in bb rep.*/
00170 
00171 
00172 
00173   seq_t arc_eq(){ 
00174 
00175   
00176     vec_t cvec=matrat(v_minus(pts[0],pts[1]),v_minus(pts[2],pts[1]));  
00177      
00178     coeff_t eh2=cvec[1];
00179     coeff_t ehx=dot(cvec, vec(pts[2][1]-pts[0][1],(coeff_t)(-1)*pts[0][0]-pts[2][0]));
00180     coeff_t ehy=dot(cvec, vec(pts[0][0]-pts[2][0],(coeff_t)(-1)*pts[0][1]-pts[2][1]));  
00181     coeff_t ehc=dot(cvec, vec(pts[0][1]*pts[2][0]-pts[0][0]*pts[2][1],
00182                                          pts[0][0]*pts[2][0]+pts[0][1]*pts[2][1])); 
00183 
00184     seq_t eh; eh<<eh2<<ehx<<ehy<<ehc;
00185      
00186   return(eh);
00187   }; /*coeff vector of monom rep: eh2*(x^2+y^2)+ehx*x+ehy*y+ehc=0*/
00188 
00189   
00190 
00191  vec_t critpt(int var){ 
00192 
00193   vec_t pt;
00194    Seq<coeff_t> coeffx,coeffy,wvec; 
00195    pt=vec(coeff_t(-1),coeff_t(-1));
00196    coeffx<<pts[0][0]<< midc()[0]*weight()<< pts[2][0];
00197    coeffy<<pts[0][1]<< midc()[1]*weight()<<pts[2][1]; 
00198    wvec<<coeff_t(1)<< weight()<<coeff_t(1);  
00199    coeff_t t, cx,cy,w;
00200 
00201    if (var==0 && (coeffx[2]-coeffx[0])!=0)
00202      {
00203        t=(coeffx[0]-coeffx[1])/(coeffx[2]-coeffx[0]);
00204      }
00205   else if (var==1 && (coeffy[2]-coeffy[0])!=0)
00206      {
00207        t=(coeffy[0]-coeffy[1])/(coeffy[2]-coeffy[0]);
00208      };
00209 
00210    if(is_unit1(t)){
00211    tensor::eval(cx,seq2b(coeffx).rep(),t);
00212    tensor::eval(cy,seq2b(coeffy).rep(),t);
00213    tensor::eval(w,seq2b(wvec).rep(),t);
00214    pt=vec( cx/w , cy/w );   
00215    }
00216    //  std::cout <<pt<<std::endl;
00217   return(pt);
00218   }; /*tang. pt in var*/
00219 
00220 
00221  arc_rep<coeff_t> offset(coeff_t r){
00222    vec_t newp[3];
00223    Seq<coeff_t> mo, ehrat;
00224    int i;unsigned j;
00225    vec_t pp=rotl(v_minus(pts[0],pts[2])); 
00226 
00227     coeff_t l=v_length(pp);
00228     coeff_t w=weight();
00229 
00230     for( i=0; i<3; i++){newp[i]=vec_t(); };
00231     arc_rep<coeff_t> ncirc(newp);
00232     if( l!=coeff_t(0) ){  
00233       if( w==coeff_t(1)){ for( i=0; i<3; i++){ newp[i]=v_plus(pts[i],v_mul(r/l,pp)); } }//case of a quarter of a circle
00234       else if (  
00235                //( coeff_t(1)-w*w )>coeff_t(0) && 
00236                ( r + l/(coeff_t(2)*sqrt( coeff_t(1)-w*w ) )) > coeff_t(0)  
00237             &&  v_length( v_minus(pts[1],v_plus(pts[0],pts[2])) )!=coeff_t(0) )
00238         { 
00239 
00240             newp[0]=v_plus(pts[0],v_mul(coeff_t(2)*r/l,
00241                                 rotl( v_minus(v_minus(v_mul((coeff_t(1)+w),pts[1]),v_mul((w+ coeff_t(0.5)),pts[0])),
00242                                                 v_div(pts[2],coeff_t(2))
00243                                                 )
00244                                       )
00245                                   )
00246                      );
00247 
00248             newp[1]=v_plus(pts[1],
00249                            v_mul(r/v_length(v_minus(pts[1],v_div(v_plus(pts[0],pts[2]),coeff_t(2)))),
00250                            v_minus(v_minus(pts[1],v_div(pts[0],coeff_t(2))),v_div(pts[2],coeff_t(2)))
00251                            )
00252                      );
00253 
00254             newp[2]=v_minus(pts[2],
00255                       v_mul(coeff_t(2)*r/l,
00256                             rotl(v_minus(v_minus(v_mul((coeff_t(1)+w),pts[1]),v_mul((w+(coeff_t)(0.5)),pts[2])),
00257                                          v_div(pts[0],coeff_t(2))
00258                                          )
00259                                  )
00260                             )
00261                       );
00262         };
00263    
00264       //std::cout <<"newp0: "<<newp[0]<<" "<<newp[1]<<" "<<newp[2]<<std::endl;
00265      ncirc=arc_rep<coeff_t>(newp);
00266      if(is_arc(ncirc)){
00267      Seq<vec_t> isp;
00268     ehrat=ncirc.arc_eq();  
00269     mo=solve2(ehrat[0],ehrat[2],ehrat[3]); 
00270     for( j=0; j<2; j++){if(is_unit1(mo[j])){isp<<vec(coeff_t(0),mo[j]);};};
00271     mo=solve2(ehrat[0],ehrat[2],ehrat[0]+ehrat[1]+ehrat[3]);
00272     for( j=0; j<2; j++){if(is_unit1(mo[j])){isp<<vec(coeff_t(1),mo[j]);};};
00273     mo=solve2(ehrat[0],ehrat[1],ehrat[3]);
00274     for( j=0; j<2; j++){if(is_unit1(mo[j])){isp<<vec(mo[j],coeff_t(0));};};
00275     mo=solve2(ehrat[0],ehrat[1],ehrat[0]+ehrat[2]+ehrat[3]);
00276     for( j=0; j<2; j++){if(is_unit1(mo[j])){isp<<vec(mo[j],coeff_t(1));};};
00277 
00278     if (isp.size()==0){newp[0]=vec_t(); }else{
00279     newp[0]=isp[0];
00280     for( j=1; j<isp.size(); j++)
00281       {if(v_length(v_minus(isp[j],pts[0]))<v_length(v_minus(newp[0],pts[0]))){newp[0]=isp[j];};};
00282     };
00283 
00284     if (isp.size()==0){newp[2]=vec_t(); }else{
00285     newp[2]=isp[0];
00286     for( j=1; j<isp.size(); j++)
00287       {if(v_length(v_minus(isp[j],pts[2]))<v_length(v_minus(newp[2],pts[2]))){newp[2]=isp[j];};};
00288     };
00289    ncirc=arc_rep<coeff_t>(newp);
00290    // std::cout <<"newp1: "<<newp[0]<<" "<<newp[1]<<" "<<newp[2]<<std::endl;
00291    /*if (is_arc(ncirc)){
00292       if( matrat(v_minus(newp[1],newp[0]),v_minus(newp[2],newp[0]))[1]>coeff_t(0) )
00293       { vec_t u=newp[0]; newp[0]=newp[2]; newp[2]=u;}};*/
00294      };
00295   };
00296  return( ncirc );
00297  } /*offset arc computation(with precise endpoints) - OR OUTSIDE!!!*/
00298 
00299 };//end of struct arc_rep
00300 
00301 
00303 //box_rep structure
00304 
00305 
00306 template<class C>
00307 struct box_rep
00308 {
00309 
00310   typedef C                                              coeff_t;
00311   typedef std::vector<coeff_t>                           vec_t;
00312   typedef domain<coeff_t>                                box_t;
00313   typedef polynomial< coeff_t ,with<Bernstein> >         bernstein_t; 
00314   typedef polynomial< coeff_t ,with<MonomialTensor> >    monom_t;  
00315   typedef arc_rep<coeff_t>               arc_rep_t;
00316  
00317   
00318   box_t       box;
00319   bernstein_t poly;
00320 
00321   //CONSTRUCTORS
00322 
00323   box_rep(bernstein_t  p){box_t bb; poly=p; box=bb; };
00324   box_rep(bernstein_t  p, box_t bb)
00325   {
00326     bernstein_t pa=p;
00327 
00328     tensor::restrict(pa.rep(), 0 , bb.I[0].m , bb.I[0].M );
00329     tensor::restrict(pa.rep(), 1 , bb.I[1].m , bb.I[1].M );
00330    
00331     poly=pa;
00332     box=bb;
00333   };
00334 
00335 
00336   //FCTS
00337 
00338 bool not_empty(){
00339 
00340   if( sign(min_coeff(poly))*sign(max_coeff(poly)) > 0 ){
00341     return false;
00342   }
00343   else{ 
00344     return true; 
00345   }
00346 }/*detect empty boxes*/
00347 
00348 
00349   bool edge_event(int var , int n){
00350 
00351   bernstein_t face_p;
00352   int event = 0;
00353 
00354   tensor::face(face_p, poly, var, n);
00355   
00356   int stc = 0;
00357  
00358   for(unsigned i = 0 ; i < face_p.size() ; i++){
00359     if( stc*sign(face_p.rep()[i]) == -1 ){
00360       stc = sign(face_p.rep()[i]); event++;
00361     }
00362     else if ( stc == 0 && sign(face_p.rep()[i])!=0 ){
00363       stc = sign(face_p.rep()[i]);
00364     };
00365   }
00366   if(event==1){return true;}else{return false;};
00367 }/*edge event along ONE edge*/
00368 
00369 
00370 int first_nonzero(bernstein_t list, int e){
00371 
00372   int elem =0;
00373   int n = list.size();
00374   int j;
00375 
00376   for(int i = 0; i < n ; i++){
00377     if( e==0 ){ j=i; }else{j=n-i-1;}
00378     if( coeff_t(0)!=(list[j]) ){
00379       elem=sign(list[j]);
00380       break;
00381     }
00382   } 
00383   return elem;
00384 
00385 }
00386 
00387 
00388   bool corner_event(int c1, int c2){
00389   vec_t evc=vec(coeff_t(c1),coeff_t(c2));
00390   coeff_t v;
00391   eval(v, poly.rep(), evc );
00392   bernstein_t face_p, face_q;
00393  
00394   if ( is_small(v) ){      
00395     tensor::face(face_p, poly, 0, c2);
00396     tensor::face(face_q, poly, 1, c1);
00397 
00398     if (first_nonzero(face_p, c1)*first_nonzero(face_q, c2) < 0){return true; }else{ return false; };
00399 
00400   }else{ return false;};
00401 }
00402 
00403 
00404   Seq<vec_t>event_list(){ 
00405     Seq<vec_t> elist;
00406     if(edge_event( 0, 0)){elist<<vec(coeff_t(0),coeff_t(0))<<vec(coeff_t(1),coeff_t(0));}
00407     if(edge_event( 0, 1)){elist<<vec(coeff_t(0),coeff_t(1))<<vec(coeff_t(1),coeff_t(1));}
00408     if(edge_event( 1, 0)){elist<<vec(coeff_t(0),coeff_t(0))<<vec(coeff_t(0),coeff_t(1));}
00409     if(edge_event( 1, 1)){elist<<vec(coeff_t(1),coeff_t(0))<<vec(coeff_t(1),coeff_t(1));}
00410 
00411     if(corner_event( 0, 0)){elist<<vec(coeff_t(0),coeff_t(0))<<vec_t();}
00412     if(corner_event( 0, 1)){elist<<vec(coeff_t(0),coeff_t(1))<<vec_t();}
00413     if(corner_event( 1, 0)){elist<<vec(coeff_t(1),coeff_t(0))<<vec_t();}
00414     if(corner_event( 1, 1)){elist<<vec(coeff_t(1),coeff_t(1))<<vec_t();}
00415     return elist;
00416 
00417 } //boxes with single implicitly defined curve segment*/
00418 
00419 
00420 coeff_t min_grad(){
00421 
00422   bernstein_t p0 = diff(poly,0);
00423   bernstein_t p1 = diff(poly,1);
00424   bernstein_t grad;
00425   bernstein_t gradx0 = p0; 
00426   bernstein_t gradx1 = p1;
00427 
00428  
00429   mul(gradx0.rep(),p0.rep());
00430   mul(gradx1.rep(),p1.rep()); 
00431   add(grad.rep(),gradx0.rep(),gradx1.rep());
00432 
00433   return(min_coeff(grad));
00434 }
00435 
00436 
00437 coeff_t max_eval(arc_rep_t circ){
00438   bernstein_t neww, bxt, byt, bwt, num, polyco;
00439   monom_t monomp, newnom, xt, yt, wt;    
00440   Seq<coeff_t> v;
00441 
00442   v<<coeff_t(1)<<circ.weight()<<coeff_t(1);
00443   neww=seq2b( v );
00444   v.clear();
00445  
00446     pow(neww,degree(poly,0)+degree(poly,1));
00447 
00448     v<<circ.pts[0][0]<<circ.midc()[0]*circ.weight()<<circ.pts[2][0];
00449     bxt=seq2b(v); v.clear(); 
00450     tensor::assign(xt.rep(),bxt.rep());
00451     v<<circ.pts[0][1]<<circ.midc()[1]*circ.weight()<<circ.pts[2][1];
00452     byt=seq2b(v); v.clear(); 
00453     tensor::assign(yt.rep(),byt.rep());
00454     v<<coeff_t(1)<<circ.weight()<<coeff_t(1);
00455     bwt=seq2b(v); v.clear(); 
00456     tensor::assign(wt.rep(),bwt.rep());
00457   
00458     Seq<monom_t> paramv; paramv<<wt<<xt<<yt;
00459  
00460     polyco=poly;
00461     tensor::assign(monomp.rep(),polyco.rep());
00462     tensor::heval(newnom, monomp.rep(), paramv ); 
00463   
00464     let::assign(num.rep(),newnom.rep());
00465       
00466    return(abs_max_coeff(num)/min_coeff(neww));
00467 
00468 };
00469 
00470 
00471 };//end of structure box_rep
00472 
00473 
00474 #include <realroot/fatarcs_fcts.hpp>
00475 
00476 
00477