Interactive Voronoi polygons?
I am trying to create a Voronoi Diagram which looks like the following(this is also my output at the moment):

and my question was how can I make this interactive.
And with that I mean I want to be able to set black dots and then it should adjust to the map and create a Voronoi polygon.
The code structure of my project contains 2 header classes one is where the Voronoi is calculated, the second is the bitmap and as for last the one main.cpp.
the classes look like the following:
voronoi.h
#pragma once
#include "stdafx.h"
#include "MyBitmap.h"
#include <windows.h>
#include <vector>
#include <string>
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();
}
void CreateSites() { //voronoi triangulation mathematics
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); //lines between points
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() {
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 }); //where the black points are placed.
}
}
void CreateColors() {
for (size_t i = 0; i < points_.size(); i++) {
DWORD c = RGB(255, 0,0); //red
DWORD d = RGB(0, 0, 255); //blue
colors_.push_back(c);
colors_.push_back(d);
}
}
vector<Point> points_;
vector<DWORD> colors_;
MyBitmap* bmp_;
};
this is responsible for the voronoi algorithms.
next up the MyBitmap.h:
#pragma once
#include "stdafx.h"
#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 = CreateFileA(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_;
};
and as last but not least main.cpp:
// Voronoi Diagram Game.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <SDL_image.h>
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <SDL.h>
#include "MyBitmap.h"
#include "Voronoi.h"
//Screen dimension constants
const int SCREEN_WIDTH = 740;
const int SCREEN_HEIGHT = 550;
bool init();
//Loads media
bool loadMedia();
//Frees media and shuts down SDL
void close();
//Loads individual image
SDL_Surface* loadSurface(std::string path);
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//Current displayed PNG image
SDL_Surface* gImageSurface = NULL;
SDL_Rect sourceRect;
SDL_Rect destRect;
//InputHandler * handler = new InputHandler();
int m_count = 0;
bool init()
{
//Initialization flag
bool success = true;
//where on the screen it is shown
sourceRect.x = 20;
sourceRect.y = -10;
sourceRect.w = 10;
sourceRect.y = 10;
//how big the window is that the sprite is shown in
destRect.x = 0;
destRect.y = 0;
destRect.w = 740;
destRect.h = 550;
//Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL Error: %sn", SDL_GetError());
success = false;
}
else
{
//Create window
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (gWindow == NULL)
{
printf("Window could not be created! SDL Error: %sn", SDL_GetError());
success = false;
}
else
{
//Initialize PNG loading
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
printf("SDL_image could not initialize! SDL_image Error: %sn", IMG_GetError());
success = false;
}
else
{
//Get window surface
gScreenSurface = SDL_GetWindowSurface(gWindow);
}
}
}
return success;
}
bool loadMedia()
{
//Loading success flag
bool success = true;
//Load PNG surface
gImageSurface = SDL_LoadBMP("v.bmp");
if (gImageSurface == NULL)
{
printf("Failed to load PNG image!n");
success = false;
}
return success;
}
void close()
{
//Free loaded image
SDL_FreeSurface(gImageSurface);
gImageSurface = NULL;
//Destroy window
SDL_DestroyWindow(gWindow);
gWindow = NULL;
//Quit SDL subsystems
IMG_Quit();
SDL_Quit();
}
SDL_Surface* loadSurface(std::string path)
{
//The final optimized image
SDL_Surface* optimizedSurface = NULL;
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
if (loadedSurface == NULL)
{
printf("Unable to load image %s! SDL_image Error: %sn", path.c_str(), IMG_GetError());
}
else
{
//Convert surface to screen format
optimizedSurface = SDL_ConvertSurface(loadedSurface, gScreenSurface->format, NULL);
if (optimizedSurface == NULL)
{
printf("Unable to optimize image %s! SDL Error: %sn", path.c_str(), SDL_GetError());
}
//Get rid of old loaded surface
SDL_FreeSurface(loadedSurface);
}
return optimizedSurface;
}
int main(int argc, char* args)
{
MyBitmap bmp;
Voronoi v;
srand(GetTickCount());
int clickCount = 0;
bmp.Create(512, 512); //how big the bitmap is
bmp.SetPenColor(0);
v.Make(&bmp, 50);
//Start up SDL and create window
if (!init())
{
printf("Failed to initialize!n");
}
else
{
// create the newbmp
bmp.SaveBitmap("v.bmp");
//Load media
if (!loadMedia())
{
printf("Failed to load media!n");
}
else
{
//Main loop flag
bool quit = false;
SDL_Event e;
while (!quit)
{
//Handle events on queue
while (SDL_PollEvent(&e) != 0)
{
if (e.type == SDL_QUIT)
{
quit = true;
}
else if (e.type == SDL_MOUSEBUTTONDOWN) {
if (e.button.button == SDL_BUTTON_LEFT) {
//TO DO: create a black dot
//TO DO: add voronoi polygon according to the others
cout << "left button pressed" << endl;
clickCount++;
}
}
}
//BitBlt(GetDC(GetConsoleWindow()), 20, 20, 512, 512, bmp.hdc(), 0, 0, SRCCOPY); //shows it in the cmd
//Apply the image
SDL_BlitSurface(gImageSurface, &destRect, gScreenSurface, &sourceRect);
//Update the surface
SDL_UpdateWindowSurface(gWindow);
}
}
}
//Free resources and close SDL
close();
return 0;
}
So to summarize I want to be able to place black dots/Voronoi polygons which adjust to the other Voronoi polygons and I haven't found a way yet to do this.
It has to be done by mouse click and on mouse position which I am working on right now.
It is also alright if it starts Blanco without any Voronoi polygons.
I got a good example for this from here.
I have a rough knowledge of what it does (except for the MyBitmap.h) but I got the source code from here.
c++ sdl-2 voronoi
add a comment |
I am trying to create a Voronoi Diagram which looks like the following(this is also my output at the moment):

and my question was how can I make this interactive.
And with that I mean I want to be able to set black dots and then it should adjust to the map and create a Voronoi polygon.
The code structure of my project contains 2 header classes one is where the Voronoi is calculated, the second is the bitmap and as for last the one main.cpp.
the classes look like the following:
voronoi.h
#pragma once
#include "stdafx.h"
#include "MyBitmap.h"
#include <windows.h>
#include <vector>
#include <string>
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();
}
void CreateSites() { //voronoi triangulation mathematics
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); //lines between points
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() {
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 }); //where the black points are placed.
}
}
void CreateColors() {
for (size_t i = 0; i < points_.size(); i++) {
DWORD c = RGB(255, 0,0); //red
DWORD d = RGB(0, 0, 255); //blue
colors_.push_back(c);
colors_.push_back(d);
}
}
vector<Point> points_;
vector<DWORD> colors_;
MyBitmap* bmp_;
};
this is responsible for the voronoi algorithms.
next up the MyBitmap.h:
#pragma once
#include "stdafx.h"
#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 = CreateFileA(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_;
};
and as last but not least main.cpp:
// Voronoi Diagram Game.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <SDL_image.h>
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <SDL.h>
#include "MyBitmap.h"
#include "Voronoi.h"
//Screen dimension constants
const int SCREEN_WIDTH = 740;
const int SCREEN_HEIGHT = 550;
bool init();
//Loads media
bool loadMedia();
//Frees media and shuts down SDL
void close();
//Loads individual image
SDL_Surface* loadSurface(std::string path);
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//Current displayed PNG image
SDL_Surface* gImageSurface = NULL;
SDL_Rect sourceRect;
SDL_Rect destRect;
//InputHandler * handler = new InputHandler();
int m_count = 0;
bool init()
{
//Initialization flag
bool success = true;
//where on the screen it is shown
sourceRect.x = 20;
sourceRect.y = -10;
sourceRect.w = 10;
sourceRect.y = 10;
//how big the window is that the sprite is shown in
destRect.x = 0;
destRect.y = 0;
destRect.w = 740;
destRect.h = 550;
//Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL Error: %sn", SDL_GetError());
success = false;
}
else
{
//Create window
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (gWindow == NULL)
{
printf("Window could not be created! SDL Error: %sn", SDL_GetError());
success = false;
}
else
{
//Initialize PNG loading
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
printf("SDL_image could not initialize! SDL_image Error: %sn", IMG_GetError());
success = false;
}
else
{
//Get window surface
gScreenSurface = SDL_GetWindowSurface(gWindow);
}
}
}
return success;
}
bool loadMedia()
{
//Loading success flag
bool success = true;
//Load PNG surface
gImageSurface = SDL_LoadBMP("v.bmp");
if (gImageSurface == NULL)
{
printf("Failed to load PNG image!n");
success = false;
}
return success;
}
void close()
{
//Free loaded image
SDL_FreeSurface(gImageSurface);
gImageSurface = NULL;
//Destroy window
SDL_DestroyWindow(gWindow);
gWindow = NULL;
//Quit SDL subsystems
IMG_Quit();
SDL_Quit();
}
SDL_Surface* loadSurface(std::string path)
{
//The final optimized image
SDL_Surface* optimizedSurface = NULL;
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
if (loadedSurface == NULL)
{
printf("Unable to load image %s! SDL_image Error: %sn", path.c_str(), IMG_GetError());
}
else
{
//Convert surface to screen format
optimizedSurface = SDL_ConvertSurface(loadedSurface, gScreenSurface->format, NULL);
if (optimizedSurface == NULL)
{
printf("Unable to optimize image %s! SDL Error: %sn", path.c_str(), SDL_GetError());
}
//Get rid of old loaded surface
SDL_FreeSurface(loadedSurface);
}
return optimizedSurface;
}
int main(int argc, char* args)
{
MyBitmap bmp;
Voronoi v;
srand(GetTickCount());
int clickCount = 0;
bmp.Create(512, 512); //how big the bitmap is
bmp.SetPenColor(0);
v.Make(&bmp, 50);
//Start up SDL and create window
if (!init())
{
printf("Failed to initialize!n");
}
else
{
// create the newbmp
bmp.SaveBitmap("v.bmp");
//Load media
if (!loadMedia())
{
printf("Failed to load media!n");
}
else
{
//Main loop flag
bool quit = false;
SDL_Event e;
while (!quit)
{
//Handle events on queue
while (SDL_PollEvent(&e) != 0)
{
if (e.type == SDL_QUIT)
{
quit = true;
}
else if (e.type == SDL_MOUSEBUTTONDOWN) {
if (e.button.button == SDL_BUTTON_LEFT) {
//TO DO: create a black dot
//TO DO: add voronoi polygon according to the others
cout << "left button pressed" << endl;
clickCount++;
}
}
}
//BitBlt(GetDC(GetConsoleWindow()), 20, 20, 512, 512, bmp.hdc(), 0, 0, SRCCOPY); //shows it in the cmd
//Apply the image
SDL_BlitSurface(gImageSurface, &destRect, gScreenSurface, &sourceRect);
//Update the surface
SDL_UpdateWindowSurface(gWindow);
}
}
}
//Free resources and close SDL
close();
return 0;
}
So to summarize I want to be able to place black dots/Voronoi polygons which adjust to the other Voronoi polygons and I haven't found a way yet to do this.
It has to be done by mouse click and on mouse position which I am working on right now.
It is also alright if it starts Blanco without any Voronoi polygons.
I got a good example for this from here.
I have a rough knowledge of what it does (except for the MyBitmap.h) but I got the source code from here.
c++ sdl-2 voronoi
2
If your count of dots is small enough, just re-calculate the whole thing. If not, you can use the special property of a Delaunay triangulation, which can be re-triangulated locally. The Voronoi cells are just like the bounding contour of the triangulation if you will.
– Thomas Lang
Nov 28 '18 at 22:03
add a comment |
I am trying to create a Voronoi Diagram which looks like the following(this is also my output at the moment):

and my question was how can I make this interactive.
And with that I mean I want to be able to set black dots and then it should adjust to the map and create a Voronoi polygon.
The code structure of my project contains 2 header classes one is where the Voronoi is calculated, the second is the bitmap and as for last the one main.cpp.
the classes look like the following:
voronoi.h
#pragma once
#include "stdafx.h"
#include "MyBitmap.h"
#include <windows.h>
#include <vector>
#include <string>
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();
}
void CreateSites() { //voronoi triangulation mathematics
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); //lines between points
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() {
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 }); //where the black points are placed.
}
}
void CreateColors() {
for (size_t i = 0; i < points_.size(); i++) {
DWORD c = RGB(255, 0,0); //red
DWORD d = RGB(0, 0, 255); //blue
colors_.push_back(c);
colors_.push_back(d);
}
}
vector<Point> points_;
vector<DWORD> colors_;
MyBitmap* bmp_;
};
this is responsible for the voronoi algorithms.
next up the MyBitmap.h:
#pragma once
#include "stdafx.h"
#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 = CreateFileA(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_;
};
and as last but not least main.cpp:
// Voronoi Diagram Game.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <SDL_image.h>
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <SDL.h>
#include "MyBitmap.h"
#include "Voronoi.h"
//Screen dimension constants
const int SCREEN_WIDTH = 740;
const int SCREEN_HEIGHT = 550;
bool init();
//Loads media
bool loadMedia();
//Frees media and shuts down SDL
void close();
//Loads individual image
SDL_Surface* loadSurface(std::string path);
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//Current displayed PNG image
SDL_Surface* gImageSurface = NULL;
SDL_Rect sourceRect;
SDL_Rect destRect;
//InputHandler * handler = new InputHandler();
int m_count = 0;
bool init()
{
//Initialization flag
bool success = true;
//where on the screen it is shown
sourceRect.x = 20;
sourceRect.y = -10;
sourceRect.w = 10;
sourceRect.y = 10;
//how big the window is that the sprite is shown in
destRect.x = 0;
destRect.y = 0;
destRect.w = 740;
destRect.h = 550;
//Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL Error: %sn", SDL_GetError());
success = false;
}
else
{
//Create window
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (gWindow == NULL)
{
printf("Window could not be created! SDL Error: %sn", SDL_GetError());
success = false;
}
else
{
//Initialize PNG loading
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
printf("SDL_image could not initialize! SDL_image Error: %sn", IMG_GetError());
success = false;
}
else
{
//Get window surface
gScreenSurface = SDL_GetWindowSurface(gWindow);
}
}
}
return success;
}
bool loadMedia()
{
//Loading success flag
bool success = true;
//Load PNG surface
gImageSurface = SDL_LoadBMP("v.bmp");
if (gImageSurface == NULL)
{
printf("Failed to load PNG image!n");
success = false;
}
return success;
}
void close()
{
//Free loaded image
SDL_FreeSurface(gImageSurface);
gImageSurface = NULL;
//Destroy window
SDL_DestroyWindow(gWindow);
gWindow = NULL;
//Quit SDL subsystems
IMG_Quit();
SDL_Quit();
}
SDL_Surface* loadSurface(std::string path)
{
//The final optimized image
SDL_Surface* optimizedSurface = NULL;
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
if (loadedSurface == NULL)
{
printf("Unable to load image %s! SDL_image Error: %sn", path.c_str(), IMG_GetError());
}
else
{
//Convert surface to screen format
optimizedSurface = SDL_ConvertSurface(loadedSurface, gScreenSurface->format, NULL);
if (optimizedSurface == NULL)
{
printf("Unable to optimize image %s! SDL Error: %sn", path.c_str(), SDL_GetError());
}
//Get rid of old loaded surface
SDL_FreeSurface(loadedSurface);
}
return optimizedSurface;
}
int main(int argc, char* args)
{
MyBitmap bmp;
Voronoi v;
srand(GetTickCount());
int clickCount = 0;
bmp.Create(512, 512); //how big the bitmap is
bmp.SetPenColor(0);
v.Make(&bmp, 50);
//Start up SDL and create window
if (!init())
{
printf("Failed to initialize!n");
}
else
{
// create the newbmp
bmp.SaveBitmap("v.bmp");
//Load media
if (!loadMedia())
{
printf("Failed to load media!n");
}
else
{
//Main loop flag
bool quit = false;
SDL_Event e;
while (!quit)
{
//Handle events on queue
while (SDL_PollEvent(&e) != 0)
{
if (e.type == SDL_QUIT)
{
quit = true;
}
else if (e.type == SDL_MOUSEBUTTONDOWN) {
if (e.button.button == SDL_BUTTON_LEFT) {
//TO DO: create a black dot
//TO DO: add voronoi polygon according to the others
cout << "left button pressed" << endl;
clickCount++;
}
}
}
//BitBlt(GetDC(GetConsoleWindow()), 20, 20, 512, 512, bmp.hdc(), 0, 0, SRCCOPY); //shows it in the cmd
//Apply the image
SDL_BlitSurface(gImageSurface, &destRect, gScreenSurface, &sourceRect);
//Update the surface
SDL_UpdateWindowSurface(gWindow);
}
}
}
//Free resources and close SDL
close();
return 0;
}
So to summarize I want to be able to place black dots/Voronoi polygons which adjust to the other Voronoi polygons and I haven't found a way yet to do this.
It has to be done by mouse click and on mouse position which I am working on right now.
It is also alright if it starts Blanco without any Voronoi polygons.
I got a good example for this from here.
I have a rough knowledge of what it does (except for the MyBitmap.h) but I got the source code from here.
c++ sdl-2 voronoi
I am trying to create a Voronoi Diagram which looks like the following(this is also my output at the moment):

and my question was how can I make this interactive.
And with that I mean I want to be able to set black dots and then it should adjust to the map and create a Voronoi polygon.
The code structure of my project contains 2 header classes one is where the Voronoi is calculated, the second is the bitmap and as for last the one main.cpp.
the classes look like the following:
voronoi.h
#pragma once
#include "stdafx.h"
#include "MyBitmap.h"
#include <windows.h>
#include <vector>
#include <string>
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();
}
void CreateSites() { //voronoi triangulation mathematics
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); //lines between points
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() {
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 }); //where the black points are placed.
}
}
void CreateColors() {
for (size_t i = 0; i < points_.size(); i++) {
DWORD c = RGB(255, 0,0); //red
DWORD d = RGB(0, 0, 255); //blue
colors_.push_back(c);
colors_.push_back(d);
}
}
vector<Point> points_;
vector<DWORD> colors_;
MyBitmap* bmp_;
};
this is responsible for the voronoi algorithms.
next up the MyBitmap.h:
#pragma once
#include "stdafx.h"
#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 = CreateFileA(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_;
};
and as last but not least main.cpp:
// Voronoi Diagram Game.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <windows.h>
#include <SDL_image.h>
#include <iostream>
#include <stdio.h>
#include <vector>
#include <string>
#include <SDL.h>
#include "MyBitmap.h"
#include "Voronoi.h"
//Screen dimension constants
const int SCREEN_WIDTH = 740;
const int SCREEN_HEIGHT = 550;
bool init();
//Loads media
bool loadMedia();
//Frees media and shuts down SDL
void close();
//Loads individual image
SDL_Surface* loadSurface(std::string path);
//The window we'll be rendering to
SDL_Window* gWindow = NULL;
//The surface contained by the window
SDL_Surface* gScreenSurface = NULL;
//Current displayed PNG image
SDL_Surface* gImageSurface = NULL;
SDL_Rect sourceRect;
SDL_Rect destRect;
//InputHandler * handler = new InputHandler();
int m_count = 0;
bool init()
{
//Initialization flag
bool success = true;
//where on the screen it is shown
sourceRect.x = 20;
sourceRect.y = -10;
sourceRect.w = 10;
sourceRect.y = 10;
//how big the window is that the sprite is shown in
destRect.x = 0;
destRect.y = 0;
destRect.w = 740;
destRect.h = 550;
//Initialize SDL
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL Error: %sn", SDL_GetError());
success = false;
}
else
{
//Create window
gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (gWindow == NULL)
{
printf("Window could not be created! SDL Error: %sn", SDL_GetError());
success = false;
}
else
{
//Initialize PNG loading
int imgFlags = IMG_INIT_PNG;
if (!(IMG_Init(imgFlags) & imgFlags))
{
printf("SDL_image could not initialize! SDL_image Error: %sn", IMG_GetError());
success = false;
}
else
{
//Get window surface
gScreenSurface = SDL_GetWindowSurface(gWindow);
}
}
}
return success;
}
bool loadMedia()
{
//Loading success flag
bool success = true;
//Load PNG surface
gImageSurface = SDL_LoadBMP("v.bmp");
if (gImageSurface == NULL)
{
printf("Failed to load PNG image!n");
success = false;
}
return success;
}
void close()
{
//Free loaded image
SDL_FreeSurface(gImageSurface);
gImageSurface = NULL;
//Destroy window
SDL_DestroyWindow(gWindow);
gWindow = NULL;
//Quit SDL subsystems
IMG_Quit();
SDL_Quit();
}
SDL_Surface* loadSurface(std::string path)
{
//The final optimized image
SDL_Surface* optimizedSurface = NULL;
//Load image at specified path
SDL_Surface* loadedSurface = IMG_Load(path.c_str());
if (loadedSurface == NULL)
{
printf("Unable to load image %s! SDL_image Error: %sn", path.c_str(), IMG_GetError());
}
else
{
//Convert surface to screen format
optimizedSurface = SDL_ConvertSurface(loadedSurface, gScreenSurface->format, NULL);
if (optimizedSurface == NULL)
{
printf("Unable to optimize image %s! SDL Error: %sn", path.c_str(), SDL_GetError());
}
//Get rid of old loaded surface
SDL_FreeSurface(loadedSurface);
}
return optimizedSurface;
}
int main(int argc, char* args)
{
MyBitmap bmp;
Voronoi v;
srand(GetTickCount());
int clickCount = 0;
bmp.Create(512, 512); //how big the bitmap is
bmp.SetPenColor(0);
v.Make(&bmp, 50);
//Start up SDL and create window
if (!init())
{
printf("Failed to initialize!n");
}
else
{
// create the newbmp
bmp.SaveBitmap("v.bmp");
//Load media
if (!loadMedia())
{
printf("Failed to load media!n");
}
else
{
//Main loop flag
bool quit = false;
SDL_Event e;
while (!quit)
{
//Handle events on queue
while (SDL_PollEvent(&e) != 0)
{
if (e.type == SDL_QUIT)
{
quit = true;
}
else if (e.type == SDL_MOUSEBUTTONDOWN) {
if (e.button.button == SDL_BUTTON_LEFT) {
//TO DO: create a black dot
//TO DO: add voronoi polygon according to the others
cout << "left button pressed" << endl;
clickCount++;
}
}
}
//BitBlt(GetDC(GetConsoleWindow()), 20, 20, 512, 512, bmp.hdc(), 0, 0, SRCCOPY); //shows it in the cmd
//Apply the image
SDL_BlitSurface(gImageSurface, &destRect, gScreenSurface, &sourceRect);
//Update the surface
SDL_UpdateWindowSurface(gWindow);
}
}
}
//Free resources and close SDL
close();
return 0;
}
So to summarize I want to be able to place black dots/Voronoi polygons which adjust to the other Voronoi polygons and I haven't found a way yet to do this.
It has to be done by mouse click and on mouse position which I am working on right now.
It is also alright if it starts Blanco without any Voronoi polygons.
I got a good example for this from here.
I have a rough knowledge of what it does (except for the MyBitmap.h) but I got the source code from here.
c++ sdl-2 voronoi
c++ sdl-2 voronoi
edited Nov 28 '18 at 22:40
genpfault
42.6k954100
42.6k954100
asked Nov 28 '18 at 21:56
Onur BalliOnur Balli
317
317
2
If your count of dots is small enough, just re-calculate the whole thing. If not, you can use the special property of a Delaunay triangulation, which can be re-triangulated locally. The Voronoi cells are just like the bounding contour of the triangulation if you will.
– Thomas Lang
Nov 28 '18 at 22:03
add a comment |
2
If your count of dots is small enough, just re-calculate the whole thing. If not, you can use the special property of a Delaunay triangulation, which can be re-triangulated locally. The Voronoi cells are just like the bounding contour of the triangulation if you will.
– Thomas Lang
Nov 28 '18 at 22:03
2
2
If your count of dots is small enough, just re-calculate the whole thing. If not, you can use the special property of a Delaunay triangulation, which can be re-triangulated locally. The Voronoi cells are just like the bounding contour of the triangulation if you will.
– Thomas Lang
Nov 28 '18 at 22:03
If your count of dots is small enough, just re-calculate the whole thing. If not, you can use the special property of a Delaunay triangulation, which can be re-triangulated locally. The Voronoi cells are just like the bounding contour of the triangulation if you will.
– Thomas Lang
Nov 28 '18 at 22:03
add a comment |
1 Answer
1
active
oldest
votes
I finally got the answer.
I made a method in voronoi which gets the points on mouse position which looks like the following:
void GetPointsOnMousePosition() {
int x, y;
SDL_GetMouseState(&x, &y);
int d;
isClicked = true;
cout << x << " and " << y << endl;
points_.push_back({ x, y }); //where the black points are placed.
CreateColors();
CreateSites();
SetSitesPoints();
}
this gets the mouse position and sets it on the x and y and pushes it into the array of points.
and in the main.cpp i asked for the pointsOnMousePosition method reloaded the bmp and saved it as following:
if (e.button.button == SDL_BUTTON_LEFT) {
//bmp.~MyBitmap();
cout << "left button pressed" << endl;
v.GetPointsOnMousePosition();
//adjusts the voronoi map
bmp.SaveBitmap("v.bmp");
gImageSurface = SDL_LoadBMP("v.bmp");
cout << "points added!" << endl;
isClicked = false;
}
Hopefully this helps someone in the future.
add a comment |
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53528722%2finteractive-voronoi-polygons%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
I finally got the answer.
I made a method in voronoi which gets the points on mouse position which looks like the following:
void GetPointsOnMousePosition() {
int x, y;
SDL_GetMouseState(&x, &y);
int d;
isClicked = true;
cout << x << " and " << y << endl;
points_.push_back({ x, y }); //where the black points are placed.
CreateColors();
CreateSites();
SetSitesPoints();
}
this gets the mouse position and sets it on the x and y and pushes it into the array of points.
and in the main.cpp i asked for the pointsOnMousePosition method reloaded the bmp and saved it as following:
if (e.button.button == SDL_BUTTON_LEFT) {
//bmp.~MyBitmap();
cout << "left button pressed" << endl;
v.GetPointsOnMousePosition();
//adjusts the voronoi map
bmp.SaveBitmap("v.bmp");
gImageSurface = SDL_LoadBMP("v.bmp");
cout << "points added!" << endl;
isClicked = false;
}
Hopefully this helps someone in the future.
add a comment |
I finally got the answer.
I made a method in voronoi which gets the points on mouse position which looks like the following:
void GetPointsOnMousePosition() {
int x, y;
SDL_GetMouseState(&x, &y);
int d;
isClicked = true;
cout << x << " and " << y << endl;
points_.push_back({ x, y }); //where the black points are placed.
CreateColors();
CreateSites();
SetSitesPoints();
}
this gets the mouse position and sets it on the x and y and pushes it into the array of points.
and in the main.cpp i asked for the pointsOnMousePosition method reloaded the bmp and saved it as following:
if (e.button.button == SDL_BUTTON_LEFT) {
//bmp.~MyBitmap();
cout << "left button pressed" << endl;
v.GetPointsOnMousePosition();
//adjusts the voronoi map
bmp.SaveBitmap("v.bmp");
gImageSurface = SDL_LoadBMP("v.bmp");
cout << "points added!" << endl;
isClicked = false;
}
Hopefully this helps someone in the future.
add a comment |
I finally got the answer.
I made a method in voronoi which gets the points on mouse position which looks like the following:
void GetPointsOnMousePosition() {
int x, y;
SDL_GetMouseState(&x, &y);
int d;
isClicked = true;
cout << x << " and " << y << endl;
points_.push_back({ x, y }); //where the black points are placed.
CreateColors();
CreateSites();
SetSitesPoints();
}
this gets the mouse position and sets it on the x and y and pushes it into the array of points.
and in the main.cpp i asked for the pointsOnMousePosition method reloaded the bmp and saved it as following:
if (e.button.button == SDL_BUTTON_LEFT) {
//bmp.~MyBitmap();
cout << "left button pressed" << endl;
v.GetPointsOnMousePosition();
//adjusts the voronoi map
bmp.SaveBitmap("v.bmp");
gImageSurface = SDL_LoadBMP("v.bmp");
cout << "points added!" << endl;
isClicked = false;
}
Hopefully this helps someone in the future.
I finally got the answer.
I made a method in voronoi which gets the points on mouse position which looks like the following:
void GetPointsOnMousePosition() {
int x, y;
SDL_GetMouseState(&x, &y);
int d;
isClicked = true;
cout << x << " and " << y << endl;
points_.push_back({ x, y }); //where the black points are placed.
CreateColors();
CreateSites();
SetSitesPoints();
}
this gets the mouse position and sets it on the x and y and pushes it into the array of points.
and in the main.cpp i asked for the pointsOnMousePosition method reloaded the bmp and saved it as following:
if (e.button.button == SDL_BUTTON_LEFT) {
//bmp.~MyBitmap();
cout << "left button pressed" << endl;
v.GetPointsOnMousePosition();
//adjusts the voronoi map
bmp.SaveBitmap("v.bmp");
gImageSurface = SDL_LoadBMP("v.bmp");
cout << "points added!" << endl;
isClicked = false;
}
Hopefully this helps someone in the future.
answered Nov 29 '18 at 19:39
Onur BalliOnur Balli
317
317
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53528722%2finteractive-voronoi-polygons%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown

2
If your count of dots is small enough, just re-calculate the whole thing. If not, you can use the special property of a Delaunay triangulation, which can be re-triangulated locally. The Voronoi cells are just like the bounding contour of the triangulation if you will.
– Thomas Lang
Nov 28 '18 at 22:03