您的位置:首页 > 编程语言 > C语言/C++

C++实现voronoi图

2016-03-25 14:59 1166 查看
本文用的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) {
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: