Пример #1
0
void SPHSystem::sortParticles() {
    pgrid.reset();
    
    const int neighbors[][3] = {
        {-1, -1, -1}, {-1, 0, -1}, {-1, 1, -1},
        { 0, -1, -1}, { 0, 0, -1}, { 0, 1, -1},
        { 1, -1, -1}, { 1, 0, -1}, { 1, 1, -1},
        
        {-1, -1, 0}, {-1, 0, 0}, {-1, 1, 0},
        { 0, -1, 0}, { 0, 0, 0}, { 0, 1, 0},
        { 1, -1, 0}, { 1, 0, 0}, { 1, 1, 0},
        
        {-1, -1, 1}, {-1, 0, 1}, {-1, 1, 1},
        { 0, -1, 1}, { 0, 0, 1}, { 0, 1, 1},
        { 1, -1, 1}, { 1, 0, 1}, { 1, 1, 1},
    };
    
    
    for( int i=0;i<p.size();i++ ) {
        int gx = min(max((int)floor(p[i].x * pgrid.w), 0), pgrid.w-1);
        int gy = min(max((int)floor(p[i].y * pgrid.h), 0), pgrid.h-1);
        int gz = min(max((int)floor(p[i].z * pgrid.d), 0), pgrid.d-1);
        Grid::cell_t& cell = pgrid.getcell(gx, gy, gz);
        cell.push_back(i);
        cid[i] = iVec(gx, gy, gz);
        
        // determine relevant neighbors
        nid[i].clear();
        nid[i].reserve(27);
        
        for(int nidx=0;nidx<27;nidx++) {
            int nx = gx + neighbors[nidx][0];
            int ny = gy + neighbors[nidx][1];
            int nz = gz + neighbors[nidx][2];
            
            if( nx >= 0 && nx < pgrid.w
               && ny >= 0 && ny < pgrid.h
               && nz >= 0 && nz < pgrid.d ) {
                nid[i].push_back(nz * pgrid.w * pgrid.h + ny * pgrid.w + nx);
            }
        }
    }
}
Пример #2
0
// Illustrate the use of the fill and fill_n functions.
void fill_example ()
{
    std::cout << "Illustrate fill function\n";
    
    // Example 1, fill an array with initial values
    char buffer [100];
    char *bufferp = buffer;
    
    std::fill (bufferp, (bufferp + 100), '\0');
    std::fill_n (bufferp, 10, 'x');
    
    std::cout << buffer << '\n';
    
    // Example 2, use fill to initialize a std::list.
    std::list<std::string, std::allocator<std::string> > aList;
    
    std::fill_n (std::inserter (aList, aList.begin ()), 10, "empty");
    std::copy (aList.begin (), aList.end (),
               str_ostrm_iter (std::cout, " "));
    
    std::cout << '\n';
    
    // Example 3, use fill to overwrite values in a std::list.
    std::fill (aList.begin (), aList.end (), "full");
    std::copy (aList.begin (), aList.end (),
               str_ostrm_iter (std::cout, " "));
    
    std::cout << '\n';
    
    // Example 4, fill in a portion of a std::list.
    std::vector<int, std::allocator<int> > iVec (10);
    
    std::generate (iVec.begin (), iVec.end (), iotaGen (1));
    std::vector<int, std::allocator<int> >::iterator
        seven = std::find (iVec.begin (), iVec.end (), 7);
    std::fill (iVec.begin (), seven, 0);
    std::copy (iVec.begin (), iVec.end (), int_ostrm_iter (std::cout));
    
    std::cout << '\n';
}
Пример #3
0
// Illustrate the use of the generate and genrate_n functions.
void generate_example ()
{
    std::cout << "Illustrate generate algorithm\n";
    
    // Example 1, generate a std::list of label numbers.
    std::list<std::string, std::allocator<std::string> > labelList;
    
    std::generate_n (std::inserter (labelList, labelList.begin ()),
                     4, generateLabel);  
    std::copy (labelList.begin (), labelList.end (),
               str_ostrm_iter (std::cout, " "));
    
    std::cout << '\n';
    
    // Example 2, generate an arithmetic progression.
    std::vector<int, std::allocator<int> > iVec (10);
    
    std::generate (iVec.begin (), iVec.end (), iotaGen (2));
    std::generate_n (iVec.begin (), 5, iotaGen (7));
    std::copy (iVec.begin (), iVec.end (), int_ostrm_iter (std::cout, " "));
    
    std::cout << '\n';
}
Пример #4
0
  // Quantization takes place here!
  bool medianCut::performQuantization(const image& src,
                                      image& dest,
                                      channel8& mask,
                                      palette &thePalette) const {

    // parameters and const variables
    const parameters& param = getParameters();
    const int imageRows=src.rows();          // number of rows in src
    const int imageCols=src.columns();       // number of columns in src

    // resize destination containers
    dest.resize(imageRows,imageCols,rgbPixel(),false,false);
    mask.resize(imageRows,imageCols,ubyte(),false,false);

    // Variables
    int row,col;            // row, column counters
    int r,g,b;              // red,green,blue
    ivector iVec(3);        // int-vector

    std::list<boxInfo> theLeaves; // list of leaves (tree without root
                                  // and nodes)
    std::list<boxInfo>::iterator  splitPos;   // position to split
    std::list<boxInfo>::iterator  iter;       // iterator for theLeaves

    // create histogram with desired pre-quantization dimensions from src
    histogram theHist(3,param.preQuant);

    const float factor = param.preQuant/256.0f;

    for (row = 0 ; row < imageRows ; row++) {
      for (col = 0 ; col < imageCols ; col++) {

        r = static_cast<int>(src.at( row,col ).getRed()   * factor);
        g = static_cast<int>(src.at( row,col ).getGreen() * factor);
        b = static_cast<int>(src.at( row,col ).getBlue()  * factor);
        
        // insert point with quantized color
        dest.at(row,col).set((r*256+128)/param.preQuant,
                             (g*256+128)/param.preQuant,
                             (b*256+128)/param.preQuant,0); 

        iVec[0] = r;
        iVec[1] = g;
        iVec[2] = b;

        theHist.put(iVec);
      }
    }

    // initialization of first box of list (the whole histogram)
    boxInfo theBox(rgbPixel(0,0,0),
                   rgbPixel(param.preQuant-1,
                            param.preQuant-1,
                            param.preQuant-1));

    computeBoxInfo(theHist,theBox);

    // return, if desired number of colors smaller than colors in
    // pre-quantized image
    if (theBox.colors < param.numberOfColors) {

      thePalette.resize(theBox.colors,rgbPixel(),false,false);

      // prepare palette     
      int i = 0;
      for (r=0;r<param.preQuant;++r) {
        for (g=0;g<param.preQuant;++g) {
          for (b=0;b<param.preQuant;++b) {
            iVec[0] = r;
            iVec[1] = g;
            iVec[2] = b;
            if (theHist.at(iVec) > 0) {
              thePalette.at(i).set((r*256+128)/param.preQuant,
                                   (g*256+128)/param.preQuant,
                                   (b*256+128)/param.preQuant);
            }
          }
        }
      }

      // use the palette to generate the corresponding channel
      usePalette colorizer;
      colorizer.apply(dest,thePalette,mask);
      
      return true;
    }

    // Push first box into List
    theLeaves.push_back(theBox);

    // MAIN LOOP (do this until you have enough leaves (count), or no
    // splittable boxes (entries))
    int count, entries=1;  // auxiliary variables for the main loop
    for (count=1; (count<param.numberOfColors) && (entries!=0); count++) {

      // find box with largest number of entries from list
      entries = 0;
      for (iter = theLeaves.begin() ; iter != theLeaves.end() ; iter++) {
        if ( (*iter).colorFrequency > entries ) {
          // Avoid choosing single colors, i.e. unsplittable boxes
          if (  ((*iter).max.getRed()   > (*iter).min.getRed())   ||
                ((*iter).max.getGreen() > (*iter).min.getGreen()) ||
                ((*iter).max.getBlue()  > (*iter).min.getBlue()) ) {
            entries   = (*iter).colorFrequency;
            splitPos  = iter;
          }
        }
      }

      // A splittable box was found.
      // The iterator "splitPos" indicates its position in the List
      if (entries >0) {
        // Determine next axis to split (largest variance) and box dimensions
        int splitAxis;  // split axis indicator
        if ( ((*splitPos).var[0] >= (*splitPos).var[1]) &&
             ((*splitPos).var[0] >= (*splitPos).var[2]) ) {
          splitAxis = 0;  // red axis
        }
        else if ( (*splitPos).var[1] >= (*splitPos).var[2] ) {
          splitAxis = 1;  // green axis
        }
        else {
          splitAxis = 2;  // blue axis
        }

        int rMax  = ((*splitPos).max.getRed());
        int rMin  = ((*splitPos).min.getRed());
        int gMax  = ((*splitPos).max.getGreen());
        int gMin  = ((*splitPos).min.getGreen());
        int bMax  = ((*splitPos).max.getBlue());
        int bMin  = ((*splitPos).min.getBlue());

        // pass through box along the axis to split
        bool found;             // becomes true when split plane is found
        int nrOfCols=0;         // counter: number of colors of box
        int prevNrOfCols=0;     // forerunner of nrOfCols
        rgbPixel lower1;   // lower pixel from box 1
        rgbPixel upper1;   // upper pixel from box 1
        rgbPixel lower2;   // lower pixel from box 2
        rgbPixel upper2;   // upper pixel from box 2

        switch (splitAxis) {
          case 0: // red axis
            nrOfCols = 0;
            for (r = rMin , found = false ; (!found) && (r<=rMax) ; r++) {
              prevNrOfCols = nrOfCols;
              for (g = gMin ; g <= gMax ; g++) {
                for (b=bMin;b<=bMax;b++) {
                  iVec[0] = r;
                  iVec[1] = g;
                  iVec[2] = b;
                  if (theHist.at(iVec) > 0.0) {
                    nrOfCols += static_cast<long int>(theHist.at(iVec));
                  }
                }
              }
              if ( nrOfCols >= (*splitPos).colorFrequency/2 ) {
                found=true;
              }
            }
            if (fabs(prevNrOfCols -
                     static_cast<float>((*splitPos).colorFrequency)/2) <
                fabs(nrOfCols     -
                     static_cast<float>((*splitPos).colorFrequency)/2)) {
                r--;
                nrOfCols = prevNrOfCols;
            }
            // first box
            lower1.setRed(rMin);  lower1.setGreen(gMin);  lower1.setBlue(bMin);
            upper1.setRed(r-1);   upper1.setGreen(gMax);  upper1.setBlue(bMax);
            // second box
            lower2.setRed(r);     lower2.setGreen(gMin);  lower2.setBlue(bMin);
            upper2.setRed(rMax);  upper2.setGreen(gMax);  upper2.setBlue(bMax);
            break;

          case 1: // g axis
            nrOfCols = 0;
            for (g = gMin , found = false ; (!found) && (g<=gMax) ; g++) {
              prevNrOfCols = nrOfCols;
              for (r = rMin ; r <= rMax ; r++) {
                for (b = bMin ; b <= bMax ; b++) {
                  iVec[0] = r;
                  iVec[1] = g;
                  iVec[2] = b;
                  if (theHist.at(iVec) > 0.0) {
                    nrOfCols += static_cast<long int>(theHist.at(iVec));
                  }
                }
              }
              if ( nrOfCols >= (*splitPos).colorFrequency/2 ) {
                found=true;
              }
            }
            if (fabs(prevNrOfCols -
                     static_cast<float>((*splitPos).colorFrequency)/2) <
                fabs(nrOfCols     -
                     static_cast<float>((*splitPos).colorFrequency)/2)) {
                g--;
                nrOfCols = prevNrOfCols;
            }
            // first box
            lower1.setRed(rMin);  lower1.setGreen(gMin);  lower1.setBlue(bMin);
            upper1.setRed(rMax);  upper1.setGreen(g-1);   upper1.setBlue(bMax);
            // second box
            lower2.setRed(rMin);  lower2.setGreen(g);     lower2.setBlue(bMin);
            upper2.setRed(rMax);  upper2.setGreen(gMax);  upper2.setBlue(bMax);
            break;

          case 2: // b axis
            nrOfCols = 0;
            for (b = bMin , found = false ; (!found) && (b<=bMax) ; b++) {
              prevNrOfCols = nrOfCols;
              for (r = rMin ; r <= rMax ; r++) {
                for (g = gMin ; g <= gMax ; g++) {
                  iVec[0] = r;
                  iVec[1] = g;
                  iVec[2] = b;
                  if (theHist.at(iVec) > 0.0) {
                    nrOfCols += static_cast<long int>(theHist.at(iVec));
                  }
                }
              }
              if ( nrOfCols >= (*splitPos).colorFrequency/2 ) {
                found=true;
              }
            }
            if (fabs(prevNrOfCols -
                     static_cast<float>((*splitPos).colorFrequency)/2) <
                fabs(nrOfCols     -
                     static_cast<float>((*splitPos).colorFrequency)/2)) {
                b--;
                nrOfCols = prevNrOfCols;
            }
            // first box
            lower1.setRed(rMin); lower1.setGreen(gMin); lower1.setBlue(bMin);
            upper1.setRed(rMax); upper1.setGreen(gMax); upper1.setBlue(b-1);
            // second box
            lower2.setRed(rMin); lower2.setGreen(gMin); lower2.setBlue(b);
            upper2.setRed(rMax); upper2.setGreen(gMax); upper2.setBlue(bMax);
            break;
          default:
            break;
        } // end of switch

        // compute box info of new boxes and
        // append both at the end of list
        theBox.min = lower1;
        theBox.max = upper1;
        computeBoxInfo(theHist,theBox);
        theLeaves.push_back(theBox);

        theBox.min = lower2;
        theBox.max = upper2;
        computeBoxInfo(theHist,theBox);
        theLeaves.push_back(theBox);

        // delete splited box from list
        theLeaves.erase(splitPos);
      }

    } // end of for (MAIN LOOP)

    // compute block histogram and respective color palette
    thePalette.resize(theLeaves.size());
    int i;
    for (iter = theLeaves.begin() , i=0 ;
         iter != theLeaves.end() ;
         iter++ , i++) {
      // misuse histogram as a look-up-table
      for (r = (*iter).min.getRed(); r <= (*iter).max.getRed(); r++) {
        for (g = (*iter).min.getGreen(); g <= (*iter).max.getGreen(); g++) {
          for (b = (*iter).min.getBlue(); b <= (*iter).max.getBlue(); b++) {
            iVec[0] = r;
            iVec[1] = g;
            iVec[2] = b;
            theHist.at(iVec) = i; // insert palette-index (refers to
                                  // color in palette)
          }
        }
      }

      // create palette
      r = (static_cast<int>((*iter).mean[0]*factor)*256+128)/param.preQuant;
      g = (static_cast<int>((*iter).mean[1]*factor)*256+128)/param.preQuant;
      b = (static_cast<int>((*iter).mean[2]*factor)*256+128)/param.preQuant;
      thePalette[i].set(r,g,b,0);  // insert color
    }

    // create new image with palette and theHist
    dest.resize(imageRows,imageCols);
    mask.resize(imageRows,imageCols,0,false,true);

    // <= 256 colors? then also fill the mask
    if (thePalette.size() <= 256) {
      for (row = 0 ; row < imageRows ; row++) {
        for (col = 0 ; col < imageCols ; col++) {
          iVec[0] = static_cast<int>(src.at( row,col ).getRed()   * factor);
          iVec[1] = static_cast<int>(src.at( row,col ).getGreen() * factor);
          iVec[2] = static_cast<int>(src.at( row,col ).getBlue()  * factor);

          i = static_cast<int>(theHist.at( iVec ));

          dest.at(row,col) = thePalette[i];// insert point with quantized color
          mask.at(row,col) = i;     // insert palette index of quantized color
        }
      }
    }
    else {
      for (row = 0 ; row < imageRows ; row++) {
        for (col = 0 ; col < imageCols ; col++) {
          iVec[0] = static_cast<int>(src.at( row,col ).getRed()   * factor);
          iVec[1] = static_cast<int>(src.at( row,col ).getGreen() * factor);
          iVec[2] = static_cast<int>(src.at( row,col ).getBlue()  * factor);

          i = static_cast<int>(theHist.at( iVec ));

          r = thePalette[i].getRed();
          g = thePalette[i].getGreen();
          b = thePalette[i].getBlue();

          dest.at(row,col).set(r,g,b,0); // insert point with quantized color
        }
      }
    }

    return true;
  }
Пример #5
0
  // protected functions
  void medianCut::computeBoxInfo(const histogram& hist,
                                       boxInfo& theBox) const {

    // boxInfo.min and .max must be specified before entry and histogram
    // must be valid.  Missing information in boxInfo is computed (mean,
    // var, colorFrequency, colors) and box boundaries (min,max) are set
    // to the smallest size, that still encloses all entries in the
    // specified range of the histogram.

    int rLow=theBox.min.getRed();
    int gLow=theBox.min.getGreen();
    int bLow=theBox.min.getBlue();

    int rUp=theBox.max.getRed();
    int gUp=theBox.max.getGreen();
    int bUp=theBox.max.getBlue();

    int rMin=rUp,rMax=rLow,gMin=gUp,gMax=gLow,bMin=bUp,bMax=bLow;
    int i=rLow,j=gLow,k=bLow;
    int freq;
    ivector iVec(3);

    double meanR, meanG, meanB, meanSquareR, meanSquareG, meanSquareB;
    meanR = meanG = meanB = meanSquareR = meanSquareG = meanSquareB = 0;
    double accu = 0;

    theBox.colors = 0;
    for (i=rLow;i<=rUp;i++) {
      for (j=gLow;j<=gUp;j++) {
        for (k=bLow;k<=bUp;k++) {
          iVec[0]=i;
          iVec[1]=j;
          iVec[2]=k;
          if (hist.at(iVec)>0.0f) {
            if (k<bMin) {bMin=k;}
            if (k>bMax) {bMax=k;}
            if (j<gMin) {gMin=j;}
            if (j>gMax) {gMax=j;}
            if (i<rMin) {rMin=i;}
            if (i>rMax) {rMax=i;}

            freq = static_cast<const int>(hist.at(iVec));

            meanR += freq * i;
            meanG += freq * j;
            meanB += freq * k;

            meanSquareR += freq *i*i;
            meanSquareG += freq *j*j;
            meanSquareB += freq *k*k;

            accu  += freq;
            // Count number of distinct colors
            theBox.colors++;
          }
        }
      }
    }

    meanR /= accu;
    meanG /= accu;
    meanB /= accu;

    meanSquareR /= accu;
    meanSquareG /= accu;
    meanSquareB /= accu;

    // Set minimum and maximum enclosing bounds
    theBox.min.setRed(rMin);
    theBox.min.setGreen(gMin);
    theBox.min.setBlue(bMin);

    theBox.max.setRed(rMax);
    theBox.max.setGreen(gMax);
    theBox.max.setBlue(bMax);

    // Set number of entries inside box
    theBox.colorFrequency = static_cast<long int>(accu);

    // set mean and variance inside box
    theBox.mean[0] = meanR;
    theBox.mean[1] = meanG;
    theBox.mean[2] = meanB;

    theBox.var[0] = meanSquareR - meanR*meanR;
    theBox.var[1] = meanSquareG - meanG*meanG;
    theBox.var[2] = meanSquareB - meanB*meanB;
  }