Пример #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++;
               }
          }
      }
}
Пример #2
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;
}
Пример #3
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
         );
    }

}
Пример #4
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()));
     }
      
}
Пример #5
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 ;
}
Пример #6
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]);
     } 
}
Пример #7
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());
 }
Пример #8
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)
              )
         );
     }
	 }
}
Пример #9
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;
}
Пример #10
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;
}
Пример #11
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";
}