Task: Voronoi diagram

C: #include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define N_SITES 150
double site[N_SITES][2];
unsigned char rgb[N_SITES][3];

int size_x = 640, size_y = 480;

inline double sq2(double x, double y)
{
	return x * x + y * y;
}

#define for_k for (k = 0; k < N_SITES; k++)
int nearest_site(double x, double y)
{
	int k, ret = 0;
	double d, dist = 0;
	for_k {
		d = sq2(x - site[k][0], y - site[k][1]);
		if (!k || d < dist) {
			dist = d, ret = k;
		}
	}
	return ret;
}


int at_edge(int *color, int y, int x)
{
	int i, j, c = color[y * size_x + x];
	for (i = y - 1; i <= y + 1; i++) {
		if (i < 0 || i >= size_y) continue;

		for (j = x - 1; j <= x + 1; j++) {
			if (j < 0 || j >= size_x) continue;
			if (color[i * size_x + j] != c) return 1;
		}
	}
	return 0;
}

#define AA_RES 4 
void aa_color(unsigned char *pix, int y, int x)
{
	int i, j, n;
	double r = 0, g = 0, b = 0, xx, yy;
	for (i = 0; i < AA_RES; i++) {
		yy = y + 1. / AA_RES * i + .5;
		for (j = 0; j < AA_RES; j++) {
			xx = x + 1. / AA_RES * j + .5;
			n = nearest_site(xx, yy);
			r += rgb[n][0];
			g += rgb[n][1];
			b += rgb[n][2];
		}
	}
	pix[0] = r / (AA_RES * AA_RES);
	pix[1] = g / (AA_RES * AA_RES);
	pix[2] = b / (AA_RES * AA_RES);
}

#define for_i for (i = 0; i < size_y; i++)
#define for_j for (j = 0; j < size_x; j++)
void gen_map()
{
	int i, j, k;
	int *nearest = malloc(sizeof(int) * size_y * size_x);
	unsigned char *ptr, *buf, color;

	ptr = buf = malloc(3 * size_x * size_y);
	for_i for_j nearest[i * size_x + j] = nearest_site(j, i);

	for_i for_j {
		if (!at_edge(nearest, i, j))
			memcpy(ptr, rgb[nearest[i * size_x + j]], 3);
		else	
			aa_color(ptr, i, j);
		ptr += 3;
	}

	
	for (k = 0; k < N_SITES; k++) {
		color = (rgb[k][0]*.25 + rgb[k][1]*.6 + rgb[k][2]*.15 > 80) ? 0 : 255;

		for (i = site[k][1] - 1; i <= site[k][1] + 1; i++) {
			if (i < 0 || i >= size_y) continue;

			for (j = site[k][0] - 1; j <= site[k][0] + 1; j++) {
				if (j < 0 || j >= size_x) continue;

				ptr = buf + 3 * (i * size_x + j);
				ptr[0] = ptr[1] = ptr[2] = color;
			}
		}
	}

	printf("P6\n%d %d\n255\n", size_x, size_y);
	fflush(stdout);
	fwrite(buf, size_y * size_x * 3, 1, stdout);
}

#define frand(x) (rand() / (1. + RAND_MAX) * x)
int main()
{
	int k;
	for_k {
		site[k][0] = frand(size_x);
		site[k][1] = frand(size_y);
		rgb [k][0] = frand(256);
		rgb [k][1] = frand(256);
		rgb [k][2] = frand(256);
	}

	gen_map();
	return 0;
}


C++: #include <windows.h>
#include <vector>
#include <string>

using namespace std;


struct Point {
  int x, y;
};


class MyBitmap {
 public:
  MyBitmap() : pen_(nullptr) {}
  ~MyBitmap() {
    DeleteObject(pen_);
    DeleteDC(hdc_);
    DeleteObject(bmp_);
  }

  bool Create(int w, int h) {
    BITMAPINFO	bi;
    ZeroMemory(&bi, sizeof(bi));

    bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
    bi.bmiHeader.biBitCount = sizeof(DWORD) * 8;
    bi.bmiHeader.biCompression = BI_RGB;
    bi.bmiHeader.biPlanes = 1;
    bi.bmiHeader.biWidth = w;
    bi.bmiHeader.biHeight = -h;

    void *bits_ptr = nullptr;
    HDC dc = GetDC(GetConsoleWindow());
    bmp_ = CreateDIBSection(dc, &bi, DIB_RGB_COLORS, &bits_ptr, nullptr, 0);
    if (!bmp_) return false;

    hdc_ = CreateCompatibleDC(dc);
    SelectObject(hdc_, bmp_);
    ReleaseDC(GetConsoleWindow(), dc);

    width_ = w;
    height_ = h;

    return true;
  }

  void SetPenColor(DWORD clr) {
    if (pen_) DeleteObject(pen_);
    pen_ = CreatePen(PS_SOLID, 1, clr);
    SelectObject(hdc_, pen_);
  }

  bool SaveBitmap(const char* path) {
    HANDLE file = CreateFile(path, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
    if (file == INVALID_HANDLE_VALUE) {
      return false;
    }

    BITMAPFILEHEADER fileheader;
    BITMAPINFO infoheader;
    BITMAP bitmap;    
    GetObject(bmp_, sizeof(bitmap), &bitmap);

    DWORD* dwp_bits = new DWORD[bitmap.bmWidth * bitmap.bmHeight];
    ZeroMemory(dwp_bits, bitmap.bmWidth * bitmap.bmHeight * sizeof(DWORD));
    ZeroMemory(&infoheader, sizeof(BITMAPINFO));
    ZeroMemory(&fileheader, sizeof(BITMAPFILEHEADER));

    infoheader.bmiHeader.biBitCount = sizeof(DWORD) * 8;
    infoheader.bmiHeader.biCompression = BI_RGB;
    infoheader.bmiHeader.biPlanes = 1;
    infoheader.bmiHeader.biSize = sizeof(infoheader.bmiHeader);
    infoheader.bmiHeader.biHeight = bitmap.bmHeight;
    infoheader.bmiHeader.biWidth = bitmap.bmWidth;
    infoheader.bmiHeader.biSizeImage = bitmap.bmWidth * bitmap.bmHeight * sizeof(DWORD);

    fileheader.bfType = 0x4D42;
    fileheader.bfOffBits = sizeof(infoheader.bmiHeader) + sizeof(BITMAPFILEHEADER);
    fileheader.bfSize = fileheader.bfOffBits + infoheader.bmiHeader.biSizeImage;

    GetDIBits(hdc_, bmp_, 0, height_, (LPVOID)dwp_bits, &infoheader, DIB_RGB_COLORS);

    DWORD wb;
    WriteFile(file, &fileheader, sizeof(BITMAPFILEHEADER), &wb, nullptr);
    WriteFile(file, &infoheader.bmiHeader, sizeof(infoheader.bmiHeader), &wb, nullptr);
    WriteFile(file, dwp_bits, bitmap.bmWidth * bitmap.bmHeight * 4, &wb, nullptr);
    CloseHandle(file);

    delete[] dwp_bits;
    return true;
  }

  HDC hdc() { return hdc_; }
  int width() { return width_; }
  int height() { return height_; }

 private:
  HBITMAP bmp_;
  HDC hdc_;
  HPEN pen_;
  int width_, height_;
};

static int DistanceSqrd(const Point& point, int x, int y) {
  int xd = x - point.x;
  int yd = y - point.y;
  return (xd * xd) + (yd * yd);
}


class Voronoi {
 public:
  void Make(MyBitmap* bmp, int count) {
    bmp_ = bmp;
    CreatePoints(count);
    CreateColors();
    CreateSites();
    SetSitesPoints();
  }

 private:
  void CreateSites() {
    int w = bmp_->width(), h = bmp_->height(), d;
    for (int hh = 0; hh < h; hh++) {
      for (int ww = 0; ww < w; ww++) {
        int ind = -1, dist = INT_MAX;
        for (size_t it = 0; it < points_.size(); it++) {
          const Point& p = points_[it];
          d = DistanceSqrd(p, ww, hh);
          if (d < dist) {
            dist = d;
            ind = it;
          }
        }

        if (ind > -1)
          SetPixel(bmp_->hdc(), ww, hh, colors_[ind]);
        else
          __asm nop 
        }
    }
  }

  void SetSitesPoints() {
    for (const auto& point : points_) {
      int x = point.x, y = point.y;
      for (int i = -1; i < 2; i++)
        for (int j = -1; j < 2; j++)
          SetPixel(bmp_->hdc(), x + i, y + j, 0);
    }
  }

  void CreatePoints(int count) {
    const int w = bmp_->width() - 20, h = bmp_->height() - 20;
    for (int i = 0; i < count; i++) {
      points_.push_back({ rand() % w + 10, rand() % h + 10 });
    }
  }

  void CreateColors() {
    for (size_t i = 0; i < points_.size(); i++) {
      DWORD c = RGB(rand() % 200 + 50, rand() % 200 + 55, rand() % 200 + 50);
      colors_.push_back(c);
    }
  }

  vector<Point> points_;
  vector<DWORD> colors_;
  MyBitmap* bmp_;
};


int main(int argc, char* argv[]) {
  ShowWindow(GetConsoleWindow(), SW_MAXIMIZE);
  srand(GetTickCount());

  MyBitmap bmp;
  bmp.Create(512, 512);
  bmp.SetPenColor(0);

  Voronoi v;
  v.Make(&bmp, 50);

  BitBlt(GetDC(GetConsoleWindow()), 20, 20, 512, 512, bmp.hdc(), 0, 0, SRCCOPY);
  bmp.SaveBitmap("v.bmp");

  system("pause");

  return 0;
}