Advertisement
nbonneel

Saving a set of convex cells (e.g., Voronoi diagram) in .png

May 25th, 2020
1,785
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.45 KB | None | 0 0
  1.     void save_frame(const std::vector<Facet> &cells, std::string filename, int frameid = 0) {
  2.         int W = 1000, H = 1000;
  3.         std::vector<unsigned char> image(W*H * 3, 255);
  4. #pragma omp parallel for schedule(dynamic)
  5.         for (int i = 0; i < cells.size(); i++) {
  6.  
  7.             double bminx = 1E9, bminy = 1E9, bmaxx = -1E9, bmaxy = -1E9;
  8.             for (int j = 0; j < cells[i].vertices.size(); j++) {
  9.                 bminx = std::min(bminx, cells[i].vertices[j][0]);
  10.                 bminy = std::min(bminy, cells[i].vertices[j][1]);
  11.                 bmaxx = std::max(bmaxx, cells[i].vertices[j][0]);
  12.                 bmaxy = std::max(bmaxy, cells[i].vertices[j][1]);
  13.             }
  14.             bminx = std::min(W-1., std::max(0., W * bminx));
  15.             bminy = std::min(H-1., std::max(0., H * bminy));
  16.             bmaxx = std::max(W-1., std::max(0., W * bmaxx));
  17.             bmaxy = std::max(H-1., std::max(0., H * bmaxy));
  18.  
  19.             for (int y = bminy; y < bmaxy; y++) {
  20.                 for (int x = bminx; x < bmaxx; x++) {
  21.                     int prevSign = 0;
  22.                     bool isInside = true;
  23.                     double mindistEdge = 1E9;
  24.                     for (int j = 0; j < cells[i].vertices.size(); j++) {
  25.                         double x0 = cells[i].vertices[j][0] * W;
  26.                         double y0 = cells[i].vertices[j][1] * H;
  27.                         double x1 = cells[i].vertices[(j + 1) % cells[i].vertices.size()][0] * W;
  28.                         double y1 = cells[i].vertices[(j + 1) % cells[i].vertices.size()][1] * H;
  29.                         double det = (x - x0)*(y1-y0) - (y - y0)*(x1-x0);
  30.                         int sign = sgn(det);
  31.                         if (prevSign == 0) prevSign = sign; else
  32.                             if (sign == 0) sign = prevSign; else
  33.                             if (sign != prevSign) {
  34.                                 isInside = false;
  35.                                 break;
  36.                             }
  37.                         prevSign = sign;
  38.                         double edgeLen = sqrt((x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0));
  39.                         double distEdge = std::abs(det)/ edgeLen;
  40.                         double dotp = (x - x0)*(x1 - x0) + (y - y0)*(y1 - y0);
  41.                         if (dotp<0 || dotp>edgeLen*edgeLen) distEdge = 1E9;
  42.                         mindistEdge = std::min(mindistEdge, distEdge);
  43.                     }
  44.                     if (isInside) {
  45.                         //if (i < N) {   // the N first particles may represent fluid, displayed in blue
  46.                         //  image[((H - y - 1)*W + x) * 3] = 0;
  47.                         //  image[((H - y - 1)*W + x) * 3 + 1] = 0;
  48.                         //  image[((H - y - 1)*W + x) * 3 + 2] = 255;
  49.                         //}
  50.                         if (mindistEdge <= 2) {
  51.                             image[((H - y - 1)*W + x) * 3] = 0;
  52.                             image[((H - y - 1)*W + x) * 3 + 1] = 0;
  53.                             image[((H - y - 1)*W + x) * 3 + 2] = 0;
  54.                         }
  55.  
  56.                     }
  57.                    
  58.                 }
  59.             }
  60.         }
  61.         std::ostringstream os;
  62.         os << filename << frameid << ".png";
  63.         stbi_write_png(os.str().c_str(), W, H, 3, &image[0], 0);
  64.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement