C++实现voronoi图
2016-03-25 14:59
1166 查看
本文用的VS2010
官网的程序是Voronoi_diagram 但是直接Copy过来会出错,需要改动,直接用下面程序就可以了
官网的程序是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) { 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 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; }
相关文章推荐
- 排序算法-插入排序
- 排序算法-交换排序
- 排序算法-冒泡排序
- C++ 内存
- .h,.m,.mm,.cpp等区别
- 【C++】析构函数的作用和用法
- C++ 枚举进程信息,并结束指定进程
- C++ 获取内存运行信息
- 機器學習基石 (Machine Learning Foundations) 作业1 Q18-20的C++实现(pocket)
- C++入门系列 拷贝构造函数 拷贝赋值函数
- C语言第八篇:点开课程链接出现"500 Internal Server Error“怎么办?
- C++ Primer in one article
- 機器學習基石 (Machine Learning Foundations) 作业1 Q15-17的C++实现
- C/C++---static函数,static成员函数,static变量,static成员变量 再来理一理
- C++枚举系统磁盘信息
- C++ dynamic_cast static_cast const_cast reinterpret_cast
- fibonacci 数列的快速幂求法
- c++ 虚函数表
- 设计模式---工厂方法C++实现
- C++实现查看当前应用程序名称,并结束指定应用程序