Approx_poly::Approx_poly ( const ElFifo<Pt2dr> & fp, ArgAPP arg ) : _arg (arg) { _ind0 = get_best_intexe(fp,arg.InitWithEnvConv()); _circ = fp.circ(); init(fp.nb()+_circ,arg); for (int i = 0; i<_nb; i++) _s[i].set_pt(fp[i+_ind0]); if (arg._freem_sup) { INT nb_sup = 0; for ( INT k0 = _nb-1; k0>=2; k0-- ) { INT k1 = k0-1; while (freem_supprimable(k1)) { k1--; _s[k0]._pred = _s+k1; _s[k1]._next = _s+k0; nb_sup++; } } } }
void PtsOfSquare(ElFifo<Pt2dr> & pts,Pt2dr p0,Pt2dr p1) { pts.set_circ(true); pts.clear(); Pt2dr H = p1 -p0; Pt2dr V = H * Pt2dr(0,1); pts.pushlast(p0); pts.pushlast(p1); pts.pushlast(p1+V); pts.pushlast(p1+V-H); }
void approx_poly ( ElFifo<INT> & res, const ElFifo<Pt2di> & fpi, ArgAPP arg ) { ElFifo<Pt2dr> fpr(fpi.size(),fpi.circ());; for (INT aK=0 ; aK<INT(fpi.size()) ; aK++) fpr.push_back(Pt2dr(fpi[aK])); approx_poly(res,fpr,arg); }
void ClipSeg ( ActionSeg & Act, ElFifo<Pt2dr> & f, SegComp seg ) { f.set_circ(true); Act._events.clear(); bool OrTrig = (surf_or_poly(f) >= 0); for (INT k=0; k<f.nb() ; k++) { Pt2dr p0 = seg.to_rep_loc(f[k]); Pt2dr p1 = seg.to_rep_loc(f[k+1]); if ((p0.y>0) != (p1.y>0)) { bool entr = (p0.y>0); if (!OrTrig) entr = ! entr; REAL absc = p0.x-p0.y*((p1.x-p0.x)/(p1.y-p0.y)) ; Act._events.add_ev(EventInterv(absc,entr)); } } Act._intervs.init(Act._events); const ElFilo<Interval> & intervs = Act._intervs.intervs(); { for (INT k=0 ; k<intervs.nb() ; k++) { Pt2dr p0 (intervs[k]._v0,0.0); Pt2dr p1 (intervs[k]._v1,0.0); Act.action_seg ( Seg2d ( seg.from_rep_loc(p0), seg.from_rep_loc(p1) ) ); } } }
void EL_API_MAKE_VECTO::action // => Br_Vect_Action ( const ElFifo<Pt2di> & pts, const ElFifo<INT> * args, INT ) { const ElFifo<INT> & dist = args[0]; approx_poly(_approx,pts,_arg_app); for (INT kAp=1 ; kAp< _approx.nb() ; kAp++) { INT k1 = _approx[kAp-1]; INT k2 = _approx[kAp]; _pts_interm.clear(); _d_interm.clear(); for (INT k=k1 ; k<= k2 ; k++) { _pts_interm.push_back(Pt2d2complex(pts[k]+_dec)); _d_interm.push_back(dist[k]); } _call_back.ElVectoAction ( Pt2d2complex(pts[k1]+_dec), Pt2d2complex(pts[k2]+_dec), _pts_interm, _d_interm ); } }
REAL surf_or_poly(const ElFifo<Pt2dr> & f) { REAL res = 0.0; for (INT k=0; k<f.nb(); k++) res += f[k]^f[k+1]; return res /2.0; }
void HPoly ( ActionSeg & Act, ElFifo<Pt2dr> & f, Pt2dr dir, REAL esp ) { REAL omax = -1e50; REAL omin = 1e50; SegComp s0 (Pt2dr(0,0),dir); for (INT k=0; k<f.nb() ; k++) { REAL ord = s0.ordonnee(f[k]); ElSetMax(omax,ord); ElSetMin(omin,ord); } for (REAL ord = round_up(omin/esp) *esp; ord<omax; ord += esp) { Pt2dr p0 = s0.from_rep_loc(Pt2dr(0.0,ord)); ClipSeg(Act,f,Seg2d(p0,p0+s0.tangente())); } }
std::vector<int> approx_poly ( const std::vector<Pt2dr> & fp, bool Circ, ArgAPP arg ) { ElFifo<INT> res; ElFifo<Pt2dr> aFP(fp,Circ); Approx_poly app(aFP,arg); app.pcc_until_stab(res); std::vector<int> aRV; for (INT aK=0 ; aK< (INT(res.size())-Circ) ; aK++) aRV.push_back(res[aK]%INT(fp.size())); return aRV; }
void action(const ElFifo<Pt2di> & pts,bool ext) { if (ext) _nb_ext ++; else _nb_int ++; ElList<Pt2di> l; for (INT k=0; k<pts.nb(); k++) l = l + pts[k]; ELISE_COPY ( polygone(l,ext), (_check.in()+1) % 2, _check.out()); }
void BoxPts(ElFifo<Pt2dr> & pts,Pt2dr & p0,Pt2dr & p1) { p0 = pts[0]; p1 = pts[0]; for (INT k=0 ; k<pts.nb() ; k++) { p0.SetInf(pts[k]); p1.SetSup(pts[k]); } }
void Approx_poly::pcc_until_stab(ElFifo<INT> & res) { INT nb = one_pass_pcc(); for ( INT nb_last = nb+1, step = 1 ; (nb_last != nb) && (step < _arg._nb_step) ; step++ ) { nb_last = nb; nb = one_pass_pcc(); } res.clear(); for ( SomApproxPoly * sommet = last_som() ; (sommet != 0) ; sommet = sommet->_best_anc ) res.pushfirst(index_som(sommet)+_ind0); }
REAL SquareDistPointPoly(const ElFifo<Pt2dr> & f,Pt2dr pt) { if ( PointInPoly(f,pt)) return 0; REAL d2 = 1e40; for (INT k=0; k<f.nb() ; k++) ElSetMin ( d2, SegComp(f[k],f[k+1]).square_dist_seg(pt) ); return d2; }
bool PointInterieurPoly(const ElFifo<Pt2dr> & f,Pt2dr pt,REAL d) { if (! PointInPoly(f,pt)) return false; REAL d2 = ElSquare(d); for (INT k=0; k<f.nb() ; k++) { Pt2dr q0 = f[k]; Pt2dr q1 = f[k+1]; if ((q0!=q1) && (SegComp(q0,q1).square_dist_seg(pt) < d2)) return false; } return true; }
void bench_dist_point_seg_droite() /* On tire un segment vertical V et un point p, le calcul de d0 = D2(V,p) est trivial ; On tire une rotation affine r, soit d1 la distance r(V), r(p), elle doit etre invariante par rotation. Ce processus donne des pointe te sgement quelconuq on verifie d1=d0 */ { INT f; for (f =0; f< 1000; f++) { ElFifo<Pt2dr> poly; poly.set_circ(NRrandom3() > 0.5); random_polyl(poly,(INT)(2+20*NRrandom3())); SegComp s = random_seg(true); SegComp::ModePrim mode = ran_prim_seg(); ElFifo<Pt2dr> inters; ElFifo<INT > index; s.inter_polyline(mode,poly,index,inters); for (INT k=0; k<index.nb(); k++) { INT ind = index[k]; Pt2dr inter = inters[k]; Pt2dr p0 = poly[ind]; Pt2dr p1 = poly[ind+1]; BENCH_ASSERT ( (s.square_dist(mode,inter)<epsilon) && (SegComp(p0,p1).square_dist_seg(inter) < epsilon) ); } if ((mode==SegComp::droite) && poly.circ()) BENCH_ASSERT((inters.nb()%2)==0); } for ( f = 0; f<10000 ; f++) { bool ok; SegComp::ModePrim m0 = ran_prim_seg(); SegComp::ModePrim m1 = ran_prim_seg(); SegComp s0 = random_seg(true); SegComp s1 = SegNotPar(s0); Pt2dr i = s0.inter(m0,s1,m1,ok); BENCH_ASSERT ( (s0.square_dist_droite(i) < BIG_epsilon) && (s1.square_dist_droite(i) < BIG_epsilon) ); if ( pt_loin_from_bande(s0,i) && pt_loin_from_bande(s1,i) ) { BENCH_ASSERT ( ok == ( seg_prim_inside(s0,i,m0) && seg_prim_inside(s1,i,m1) ) ); } } for ( f = 0; f<10000 ; f++) { Pt2dr p1 = Pt2dr(0,NRrandom3()*1e3); Pt2dr p2 = Pt2dr(0,p1.y +10+1e3*NRrandom3()); Pt2dr q = Pt2dr((NRrandom3()-0.5)*1e4,(NRrandom3()-0.5)*1e4); SegComp::ModePrim mode = ran_prim_seg(); Pt2dr proj_q = Pt2dr(0,q.y); Pt2dr projP_q = proj_q; double d0 = ElSquare(q.x); double dp0 = d0; if (proj_q.y>p2.y) { if (mode == SegComp::seg) { dp0 += ElSquare(proj_q.y-p2.y); projP_q.y = p2.y; } } else if (proj_q.y<p1.y) { if (mode != SegComp::droite) { dp0 += ElSquare(proj_q.y-p1.y); projP_q.y = p1.y; } } Pt2dr tr = Pt2dr((NRrandom3()-0.5)*1e5,(NRrandom3()-0.5)*1e5); REAL teta = NRrandom3() *100; Pt2dr rot(cos(teta),sin(teta)); p1 = tr + p1 * rot; p2 = tr + p2 * rot; q = tr + q * rot; proj_q = tr + proj_q * rot; projP_q = tr + projP_q * rot; SegComp s(p1,p2); REAL d1 = s.square_dist_droite(q); REAL dp1 = s.square_dist(mode,q); BENCH_ASSERT(std::abs(d0 -d1) < BIG_epsilon); BENCH_ASSERT(std::abs(dp0 -dp1) < BIG_epsilon); Pt2dr proj_q_2 = s.proj_ortho_droite(q); BENCH_ASSERT( euclid(proj_q-proj_q_2) < BIG_epsilon); BENCH_ASSERT(euclid(projP_q,s.proj_ortho(mode,q))<BIG_epsilon); } for ( f = 0; f<10000 ; f++) { REAL rho = 1+NRrandom3()*1e3; REAL teta = (NRrandom3()-0.5)*1.9999*PI; Pt2dr p1 = Pt2dr::FromPolar(rho,teta); REAL teta2 = angle(p1); Pt2dr p2 = Pt2dr::FromPolar(1+NRrandom3()*1e3,NRrandom3()*1e3); REAL teta3 = angle(p2,p1*p2); BENCH_ASSERT(std::abs(teta2-teta)<epsilon); BENCH_ASSERT(std::abs(teta3-teta)<epsilon); } for ( f =0; f< 2000; f++) { SegComp::ModePrim m0 = ran_prim_seg(); SegComp::ModePrim m1 = ran_prim_seg(); SegComp s0 = random_seg(true); SegComp s1 = SegNotPar(s0); Seg2d proj = s0.proj_ortho(m0,s1,m1); BENCH_ASSERT ( std::abs ( square_euclid(proj.p0()-proj.p1()) -s0.square_dist(m0,s1,m1) ) < epsilon ); BENCH_ASSERT ( (s0.square_dist(m0,proj.p0())<epsilon) && (s1.square_dist(m1,proj.p1())<epsilon) ); for (INT k=0; k< 8*(2+(INT)m0)*(2+(INT)m1) ; k++) { Pt2dr q0 = proj.p0() + s0.tangente()*((NRrandom3()-0.5) * (1<<(k%10))) ; Pt2dr q1 = proj.p1() + s1.tangente()*((NRrandom3()-0.5) * (1<<(k%10))) ; q0 = s0.proj_ortho(m0,q0); q1 = s1.proj_ortho(m1,q1); BENCH_ASSERT ( euclid(proj.p0(),proj.p1()) < (euclid(q0,q1)+epsilon) ); } } cout << "OK OK OK DIIIIIIST \n"; }
static void random_polyl(ElFifo<Pt2dr> & f,INT nb) { f.clear(); for (INT k=0; k<nb ; k++) f.pushlast(random_pt()); }
template <class T> INT get_best_intexe(const ElFifo<T> & fp,bool EnvConv) { if (! fp.circ()) return 0; if (fp.nb() < 4) return 0; INT delta = EnvConv ? 1 : std::min(5,(fp.nb()-2)/2); REAL min_cos = 10.0; INT best_index = 0; std::vector<INT> aVOk; std::vector<INT> aVPrec; std::vector<INT> aVSucc; for(INT aK=0 ; aK<INT(fp.size()) ; aK++) { aVOk.push_back(EnvConv ? 0 : 1); aVPrec.push_back(aK-delta); aVSucc.push_back(aK+delta); } if (EnvConv) { ElFilo<Pt2dr> aFLP; for(INT aK=0 ; aK<INT(fp.size()) ; aK++) aFLP.pushlast(fp[aK]); ElFifo<INT> Ind; env_conv(Ind,aFLP,true); for (INT aK=0 ; aK<Ind.nb() ; aK++) { aVOk[Ind[aK]] = 1; aVPrec[Ind[aK]] = Ind[(aK-1+Ind.nb())%Ind.nb()]; aVSucc[Ind[aK]] = Ind[(aK+1)%Ind.nb()]; } } for (INT k =0 ; k<fp.nb() ; k++) { if (aVOk[k]) { T u1 = fp[k]-fp[aVPrec[k]]; T u2 = fp[aVSucc[k]]-fp[k]; double d1 = euclid(u1); double d2 = euclid(u2); if (d1 && d2) { double cosin = scal(u1,u2) / (d1*d2); if (cosin < min_cos) { min_cos = cosin; best_index = k; } } } } return best_index ; }
template <class TypeIm,class TypeBase> Im2D_Bits<1> CreateGr(tGRGraf & mGr,Im2D<TypeIm,TypeBase> anIm,int aLabelOut,const cParamGrReg & aPGR) { bool V8=true; //int aNbV = V8 ? 8 : 4; //Pt2di * TabV = V8 ? TAB_8_NEIGH : TAB_4_NEIGH; TIm2D<TypeIm,TypeBase> aTIm(anIm); Pt2di aSz = anIm.sz(); Im2D_INT4 aImLabel(aSz.x,aSz.y,-1); TIm2D<INT4,INT4> aTL(aImLabel); ELISE_COPY(aImLabel.border(1),-2,aImLabel.out()); Pt2di aP0; int aCpt=0; ElGrowingSetInd aSV(1000); std::vector<tGRSom *> aVSom; for (aP0.y=0 ; aP0.y<aSz.y ; aP0.y++) { for (aP0.x=0 ; aP0.x<aSz.x ; aP0.x++) { int aLabel = aTIm.get(aP0); if ((aTL.get(aP0)==-1) && (aLabel != aLabelOut)) { std::vector<Pt2di> aVPts; CompCnx(aVPts,V8,aP0,anIm,aImLabel,INT4(aCpt),&aSV); int aNbPts = aVPts.size(); if (aNbPts >= aPGR.mSzMinInit) { cGR_AttrSom anAttr(aP0,aLabel,aCpt,aNbPts); tGRSom & aSom = mGr.new_som(anAttr); aVSom.push_back(&aSom); for (ElGrowingSetInd::const_iterator itV=aSV.begin(); itV!=aSV.end() ; itV++) { tGRSom * aS2 = aVSom[*itV]; if (aS2) { cGR_AttrArc anAA; mGr.add_arc(aSom,*aS2,anAA); } } } else { aVSom.push_back(0); } aCpt++; } } } //std::cout << "BGIN FLAG MONT-DESC\n"; getchar(); // Calcul des flag montant et descandant int aFlagArcMont = mGr.alloc_flag_arc(); int aFlagArcDesc = mGr.alloc_flag_arc(); ElSubGraphe<cGR_AttrSom,cGR_AttrArc> aSubAll; for (int aKS=0 ; aKS<int(aVSom.size()) ; aKS++) { tGRSom * aSom = aVSom[aKS]; if (aSom) { tGRSom * aSMax = aSom; tGRSom * aSMin = aSom; for (tGRSom::TArcIter itA=aSom->begin(aSubAll); itA.go_on(); itA++) { tGRSom * aS2 = &(itA->s2()); if ( (aS2->attr().ValR() > aSMax->attr().ValR()) || ((aS2->attr().ValR()==aSMax->attr().ValR()) && (aS2->attr().Sz() > aSMax->attr().Sz())) ) { aSMax = aS2; } if ( (aS2->attr().ValR() < aSMin->attr().ValR()) || ((aS2->attr().ValR()==aSMin->attr().ValR()) && (aS2->attr().Sz() > aSMin->attr().Sz())) ) { aSMin = aS2; } } if (aSMax != aSom) mGr.arc_s1s2(*aSom,*aSMax)->sym_flag_set_kth_true(aFlagArcMont); if (aSMin != aSom) mGr.arc_s1s2(*aSom,*aSMin)->sym_flag_set_kth_true(aFlagArcDesc); } } // std::cout << "EeenDD FLAG MONT-DESC\n"; // Analyse zone water shade for (int aKMD=0 ; aKMD<2 ; aKMD++) { bool isMont = (aKMD==0); int aFlagArc = (isMont) ? aFlagArcMont : aFlagArcDesc; ElPartition<tGRSom * > aPart; ElSubGraphe<cGR_AttrSom,cGR_AttrArc> aSubAll; cSubGrFlagArc< ElSubGraphe<cGR_AttrSom,cGR_AttrArc> > aSub(aSubAll,aFlagArc); PartitionCC(aPart,mGr,aSub); std::vector<tGRSom *> aVBarbs; cSubGrSzSup aGrCons(aPGR.mSzBarb); Ebarbule(mGr,aSub,aGrCons,aVBarbs); std::set<tGRSom *> aSetB(aVBarbs.begin(),aVBarbs.end()); for (int aKC=0 ; aKC< aPart.nb() ; aKC++) { ElSubFilo<tGRSom *> aCC = aPart[aKC]; int aSzTot = SomSz(aCC); bool Ok = aSzTot >= aPGR.mSeuilZonWS ; if (Ok) { for (int aKS=0 ; aKS<aCC.size() ; aKS++) { if (aSetB.find(aCC[aKS])==aSetB.end()) { aCC[aKS]->attr().Valid() = true; } else { } } } } } // std::cout << "EeenDD PARTITION\n"; getchar(); double aSomT=0; double aMaxT=0; int aDelta = 1; // 1 for (int aKS=0 ; aKS<int(aVSom.size()) ; aKS++) { tGRSom * aSom = aVSom[aKS]; if (aSom && (! aSom->attr().DoneValR())) { ElTimer aChrono; cSubGrInterv aSG(aSom->attr().ValR()-aDelta,aSom->attr().ValR()+aDelta); ElFifo<tGRSom *> aCC; comp_connexe_som(aCC,aSom,aSG); int aSzCC = SomSz(aCC); bool Ok = aSzCC >= aPGR.mSeuilValRDelta; for (int aKC=0 ; aKC<int(aCC.size()) ; aKC++) { tGRSom * aSom2 = aCC[aKC]; if (aSom2->attr().ValR() == aSom->attr().ValR()) aSom2->attr().DoneValR() = true; if (Ok) aSom2->attr().Valid() = true; } // ShowComp(aCC,V8,(Ok?255:0), anIm,aImLabel); double aT = aChrono.uval(); aSomT += aT; if (aT > aMaxT) { aMaxT = aT; } } } /* */ // EXPORT DES RESULTATS FINALS Im2D_Bits<1> aImRes(aSz.x,aSz.y,0); TIm2DBits<1> aTImRes(aImRes); for (int aKS=0 ; aKS<int(aVSom.size()) ; aKS++) { tGRSom * aSom = aVSom[aKS]; if (aSom && aSom->attr().Valid()) { std::vector<Pt2di> aVPts; CompCnxCste(aVPts,V8,aSom->attr().P0(),anIm,aImLabel); for (int aKP=0 ; aKP<int(aVPts.size()) ; aKP++) { aTImRes.oset(aVPts[aKP],1); } } } return aImRes; }