C++实现voronoi图

来源:互联网 发布:java命令行参数args 编辑:程序博客网 时间:2024/05/01 09:10

本文用的VS2010

官网的程序是Voronoi_diagram  但是直接Copy过来会出错,需要改动,直接用下面程序就可以了

#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) {BITMAPINFObi;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 TCHAR* 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 // should never happen!}}}void SetSitesPoints(){int i=0;for(auto point=points_.cbegin();point!=points_.cend();++point){int x=points_[i].x;int y=points_[i].y;i++;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++){ Point pointtest;pointtest.x=rand()%w+10;pointtest.y=rand()%h+10;points_.push_back(pointtest);}}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;}


1 0
原创粉丝点击