示例#1
0
    void FunctionData<Degree, Real>::setDotTables(const int& flags)
    {
      clearDotTables (flags);
      int size;
      size = (res*res+res)>>1;
      if (flags & DOT_FLAG)
      {
        dotTable = new Real[size];
        memset(dotTable,0,sizeof(Real)*size);
      }
      if (flags & D_DOT_FLAG)
      {
        dDotTable = new Real[size];
        memset(dDotTable,0,sizeof(Real)*size);
      }
      if (flags & D2_DOT_FLAG)
      {
        d2DotTable = new Real[size];
        memset(d2DotTable,0,sizeof(Real)*size);
      }
      double t1,t2;
      t1 = baseFunction.polys[0].start;
      t2 = baseFunction.polys[baseFunction.polyCount-1].start;
      for(int i = 0; i < res; i++)
      {
        double c1, c2, w1, w2;
        BinaryNode<double>::CenterAndWidth (i, c1, w1);
        double start1 = t1*w1+c1;
        double end1 = t2*w1+c1;
        for(int j = 0; j <= i; j++)
        {
          BinaryNode<double>::CenterAndWidth (j, c2, w2);
          int idx = SymmetricIndex (i, j);

          double start = t1*w2+c2;
          double end = t2*w2+c2;

          if (start < start1)
            start = start1;
          if (end > end1)
            end = end1;
          if (start >= end)
            continue;

          BinaryNode<double>::CenterAndWidth (j, c2, w2);
          Real dot = dotProduct (c1, w1, c2, w2);
          if (fabs(dot) < 1e-15)
            continue;
          if (flags & DOT_FLAG)
            dotTable[idx] = dot;
          if (useDotRatios)
          {
            if (flags & D_DOT_FLAG)
              dDotTable [idx] = -dDotProduct(c1,w1,c2,w2)/dot;
            if (flags & D2_DOT_FLAG)
              d2DotTable[idx] = d2DotProduct(c1,w1,c2,w2)/dot;
          }
          else
          {
            if (flags & D_DOT_FLAG)
              dDotTable[idx] =  dDotProduct(c1,w1,c2,w2);
            if (flags & D2_DOT_FLAG)
              d2DotTable[idx] = d2DotProduct(c1,w1,c2,w2);
          }
        }
      }
    }
示例#2
0
文件: bspline_data.hpp 项目: 2php/pcl
    void BSplineData<Degree,Real>::setDotTables( int flags )
    {
      clearDotTables( flags );
      int size = ( functionCount*functionCount + functionCount )>>1;
      int fullSize = functionCount*functionCount;
      if( flags & VV_DOT_FLAG )
      {
        vvDotTable = new Real[size];
        memset( vvDotTable , 0 , sizeof(Real)*size );
      }
      if( flags & DV_DOT_FLAG )
      {
        dvDotTable = new Real[fullSize];
        memset( dvDotTable , 0 , sizeof(Real)*fullSize );
      }
      if( flags & DD_DOT_FLAG )
      {
        ddDotTable = new Real[size];
        memset( ddDotTable , 0 , sizeof(Real)*size );
      }
      double vvIntegrals[Degree+1][Degree+1];
      double vdIntegrals[Degree+1][Degree  ];
      double dvIntegrals[Degree  ][Degree+1];
      double ddIntegrals[Degree  ][Degree  ];
      int vvSums[Degree+1][Degree+1];
      int vdSums[Degree+1][Degree  ];
      int dvSums[Degree  ][Degree+1];
      int ddSums[Degree  ][Degree  ];
      SetBSplineElementIntegrals< Degree   , Degree   >( vvIntegrals );
      SetBSplineElementIntegrals< Degree   , Degree-1 >( vdIntegrals );
      SetBSplineElementIntegrals< Degree-1 , Degree   >( dvIntegrals );
      SetBSplineElementIntegrals< Degree-1 , Degree-1 >( ddIntegrals );

      for( int d1=0 ; d1<=depth ; d1++ )
        for( int off1=0 ; off1<(1<<d1) ; off1++ )
        {
          int ii = BinaryNode< Real >::CenterIndex( d1 , off1 );
          BSplineElements< Degree > b1( 1<<d1 , off1 , reflectBoundary ? BSplineElements<Degree>::NEUMANN   : BSplineElements< Degree>::NONE );
          BSplineElements< Degree-1 > db1;
          b1.differentiate( db1 );

          int start1 , end1;

          start1 = -1;
          for( int i=0 ; i<int(b1.size()) ; i++ ) for( int j=0 ; j<=Degree ; j++ )
          {
            if( b1[i][j] && start1==-1 ) start1 = i;
            if( b1[i][j] ) end1 = i+1;
          }
          for( int d2=d1 ; d2<=depth ; d2++ )
          {
            for( int off2=0 ; off2<(1<<d2) ; off2++ )
            {
              int start2 = off2-Degree;
              int end2   = off2+Degree+1;
              if( start2>=end1 || start1>=end2 ) continue;
              start2 = std::max< int >( start1 , start2 );
              end2   = std::min< int >(   end1 ,   end2 );
              if( d1==d2 && off2<off1 ) continue;
              int jj = BinaryNode< Real >::CenterIndex( d2 , off2 );
              BSplineElements< Degree > b2( 1<<d2 , off2 , reflectBoundary ? BSplineElements<Degree>::NEUMANN   : BSplineElements< Degree>::NONE );
              BSplineElements< Degree-1 > db2;
              b2.differentiate( db2 );

              int idx = SymmetricIndex( ii , jj );
              int idx1 = Index( ii , jj ) , idx2 = Index( jj , ii );

              memset( vvSums , 0 , sizeof( int ) * ( Degree+1 ) * ( Degree+1 ) );
              memset( vdSums , 0 , sizeof( int ) * ( Degree+1 ) * ( Degree   ) );
              memset( dvSums , 0 , sizeof( int ) * ( Degree   ) * ( Degree+1 ) );
              memset( ddSums , 0 , sizeof( int ) * ( Degree   ) * ( Degree   ) );
              for( int i=start2 ; i<end2 ; i++ )
              {
                for( int j=0 ; j<=Degree ; j++ ) for( int k=0 ; k<=Degree ; k++ ) vvSums[j][k] +=  b1[i][j] *  b2[i][k];
                for( int j=0 ; j<=Degree ; j++ ) for( int k=0 ; k< Degree ; k++ ) vdSums[j][k] +=  b1[i][j] * db2[i][k];
                for( int j=0 ; j< Degree ; j++ ) for( int k=0 ; k<=Degree ; k++ ) dvSums[j][k] += db1[i][j] *  b2[i][k];
                for( int j=0 ; j< Degree ; j++ ) for( int k=0 ; k< Degree ; k++ ) ddSums[j][k] += db1[i][j] * db2[i][k];
              }
              double vvDot = 0 , dvDot = 0 , vdDot = 0 , ddDot = 0;
              for( int j=0 ; j<=Degree ; j++ ) for( int k=0 ; k<=Degree ; k++ ) vvDot += vvIntegrals[j][k] * vvSums[j][k];
              for( int j=0 ; j<=Degree ; j++ ) for( int k=0 ; k< Degree ; k++ ) vdDot += vdIntegrals[j][k] * vdSums[j][k];
              for( int j=0 ; j< Degree ; j++ ) for( int k=0 ; k<=Degree ; k++ ) dvDot += dvIntegrals[j][k] * dvSums[j][k];
              for( int j=0 ; j< Degree ; j++ ) for( int k=0 ; k< Degree ; k++ ) ddDot += ddIntegrals[j][k] * ddSums[j][k];
              vvDot /= (1<<d2);
              ddDot *= (1<<d2);
              vvDot /= ( b1.denominator * b2.denominator );
              dvDot /= ( b1.denominator * b2.denominator );
              vdDot /= ( b1.denominator * b2.denominator );
              ddDot /= ( b1.denominator * b2.denominator );
              if( fabs(vvDot)<1e-15 ) continue;
              if( flags & VV_DOT_FLAG ) vvDotTable [idx] = Real( vvDot );
              if( useDotRatios )
              {
                if( flags & DV_DOT_FLAG ) dvDotTable[idx1] = Real( dvDot / vvDot );
                if( flags & DV_DOT_FLAG ) dvDotTable[idx2] = Real( vdDot / vvDot );
                if( flags & DD_DOT_FLAG ) ddDotTable[idx ] = Real( ddDot / vvDot );
              }
              else
              {
                if( flags & DV_DOT_FLAG ) dvDotTable[idx1] = Real( dvDot );
                if( flags & DV_DOT_FLAG ) dvDotTable[idx2] = Real( dvDot );
                if( flags & DD_DOT_FLAG ) ddDotTable[idx ] = Real( ddDot );
              }
            }
            BSplineElements< Degree > b;
            b = b1;
            b.upSample( b1 );
            b1.differentiate( db1 );
            start1 = -1;
            for( int i=0 ; i<int(b1.size()) ; i++ ) for( int j=0 ; j<=Degree ; j++ )
            {
              if( b1[i][j] && start1==-1 ) start1 = i;
              if( b1[i][j] ) end1 = i+1;
            }
          }
        }
    }