00001 #include <stack>
00002 #include <fstream>
00003 #include <string>
00004 #include <vector>
00005
00006 #include <realroot/Interval.hpp>
00007 #include <realroot/ring_bernstein_tensor.hpp>
00008 #include <realroot/ring_monomial_tensor.hpp>
00009 #include <realroot/tensor_convert.hpp>
00010 #include <realroot/fatarcs_fcts.hpp>
00011
00012 #pragma once
00013
00014 #define REP poly.rep()
00015 #define SIZE poly.size()
00016 #define TODOUBLE as<double>
00017
00018 using namespace mmx;
00019
00021
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
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
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
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 };
00105
00106
00107
00108
00109
00110
00111
00112 };
00113
00114
00116
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
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
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 };
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 };
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
00217 return(pt);
00218 };
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)); } }
00234 else if (
00235
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
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
00291
00292
00293
00294 };
00295 };
00296 return( ncirc );
00297 }
00298
00299 };
00300
00301
00303
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
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
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 }
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 }
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 }
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 };
00472
00473
00474
00475
00476