Beispiel #1
0
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++;
               }
          }
      }
}
Beispiel #2
0
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);

}
Beispiel #3
0
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);
}
Beispiel #4
0
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)
              )
         );
     }
	 }
}
Beispiel #5
0
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
         );
    }

}
Beispiel #6
0
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;
}
Beispiel #7
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()));
     }
      
}
Beispiel #8
0
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;
}
Beispiel #9
0
  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());
 }
Beispiel #10
0
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]);
     } 
}
Beispiel #11
0
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);
}
Beispiel #12
0
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;
}
Beispiel #13
0
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;
}
Beispiel #14
0
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";
}
Beispiel #15
0
static void random_polyl(ElFifo<Pt2dr> & f,INT nb)
{
     f.clear();
     for (INT k=0; k<nb ; k++)
         f.pushlast(random_pt());
}
Beispiel #16
0
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 ;
}
Beispiel #17
0
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;
}