Voronoi diagram: Difference between revisions

Added Easylang
(Added Easylang)
 
(109 intermediate revisions by 41 users not shown)
Line 1:
{{task}}
A [[wp:Voronoi diagram|Voronoi diagram]] is a diagram consisting of a number of sites. Each Voronoi site ''s'' also has a Voronoi cell consisting of all points closest to ''s''.
 
Each Voronoi site ''s'' also has a Voronoi cell consisting of all points closest to ''s''.
 
 
;Task:
Demonstrate how to generate and display a Voroni diagram.
 
 
See algo [[K-means++ clustering]].
<br><br>
 
=={{header|AutoHotkey}}==
Requires [https://www.autohotkey.com/boards/viewtopic.php?f=6&t=6517 GDIP Library]
<syntaxhighlight lang="autohotkey">;------------------------------------------------------------------------
Gui, 1: +E0x20 +Caption +E0x80000 +LastFound +AlwaysOnTop +ToolWindow +OwnDialogs
Gui, 1: Show, NA
hwnd1 := WinExist()
OnExit, Exit
If !pToken := Gdip_Startup()
{
MsgBox, 48, gdiplus error!, Gdiplus failed to start. Please ensure you have gdiplus on your system
ExitApp
}
Width :=1400, Height := 1050
hbm := CreateDIBSection(Width, Height)
hdc := CreateCompatibleDC()
obm := SelectObject(hdc, hbm)
G := Gdip_GraphicsFromHDC(hdc)
Gdip_SetSmoothingMode(G, 4)
;------------------------------------------------------------------------
w := 300, h := 200
xmin := A_ScreenWidth/2-w/2 , xmax := A_ScreenWidth/2+w/2
ymin := A_ScreenHeight/2-h/2 , ymax := A_ScreenHeight/2+h/2
colors := ["C0C0C0","808080","FFFFFF","800000","FF0000","800080","FF00FF","008000"
,"00FF00","808000","FFFF00","000080","0000FF","008080","00FFFF"]
site := []
loop, 15
{
Random, x, % xmin, % xmax
Random, y, % ymin, % ymax
site[A_Index, "x"] := x
site[A_Index, "y"] := y
}
y:= ymin
while (y<=ymax)
{
x:=xmin
while (x<=xmax)
{
distance := []
for S, coord in site
distance[dist(x, y, coord.x, coord.y)] := S
CS := Closest_Site(distance)
pBrush := Gdip_BrushCreateSolid("0xFF" . colors[CS])
Gdip_FillEllipse(G, pBrush, x, y, 2, 2)
x++
}
UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)
y++
}
pBrush := Gdip_BrushCreateSolid(0xFF000000)
for S, coord in site
Gdip_FillEllipse(G, pBrush, coord.x, coord.y, 4, 4)
UpdateLayeredWindow(hwnd1, hdc, 0, 0, Width, Height)
;------------------------------------------------------------------------
Gdip_DeleteBrush(pBrush)
SelectObject(hdc, obm)
DeleteObject(hbm)
DeleteDC(hdc)
Gdip_DeleteGraphics(G)
return
;------------------------------------------------------------------------
Dist(x1,y1,x2,y2){
return Sqrt((x2-x1)**2 + (y2-y1)**2)
}
;------------------------------------------------------------------------
Closest_Site(distance){
for d, i in distance
if A_Index = 1
min := d, site := i
else
min := min < d ? min : d
, site := min < d ? site : i
return site
}
;------------------------------------------------------------------------
Exit:
Gdip_Shutdown(pToken)
ExitApp
Return
;------------------------------------------------------------------------</syntaxhighlight>
 
 
=={{header|BASIC256}}==
{{trans|Python}}
<syntaxhighlight lang="basic256">global ancho, alto
ancho = 500 : alto = 500
 
clg
graphsize ancho, alto
 
function hypot(a, b)
return sqr(a^2+b^2)
end function
 
subroutine Generar_diagrama_Voronoi(ancho, alto, num_celdas)
dim nx(num_celdas+1)
dim ny(num_celdas+1)
dim nr(num_celdas+1)
dim ng(num_celdas+1)
dim nb(num_celdas+1)
 
for i = 0 to num_celdas
nx[i] = int(rand * ancho)
ny[i] = int(rand * alto)
nr[i] = int(rand * 256) + 1
ng[i] = int(rand * 256) + 1
nb[i] = int(rand * 256) + 1
next i
for y = 1 to alto
for x = 1 to ancho
dmin = hypot(ancho-1, alto-1)
j = -1
for i = 1 to num_celdas
d = hypot(nx[i]-x, ny[i]-y)
if d < dmin then dmin = d : j = i
next i
color rgb(nr[j], ng[j], nb[j])
plot (x, y)
next x
next y
end subroutine
 
call Generar_diagrama_Voronoi(ancho, alto, 25)
refresh
imgsave "Voronoi_diagram.jpg", "jpg"
end</syntaxhighlight>
 
The task is to demonstrate how to generate and display a Voroni diagram. See algo [[K-means++ clustering]].
 
=={{header|C}}==
[[File:voronoi-C.png|center|300px]]
C code drawing a color map of a set of Voronoi sites. Image is in PNM P6, written to stdout. Run as <code>a.out > stuff.pnm</code>.
Image is in PNM P6, written to stdout.
<lang c>#include <stdio.h>
Run as <code>a.out > stuff.pnm</code>.
<syntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <string.h>
Line 125 ⟶ 263:
gen_map();
return 0;
}</langsyntaxhighlight>
 
=={{header|C++}}==
[[File:voronoi_cpp.png|256px]]
<langsyntaxhighlight lang="cpp">
#include <windows.h>
#include <vector>
#include <string>
 
//--------------------------------------------------------------------------------------------------
using namespace std;
 
//////////////////////////////////////////////////////
//--------------------------------------------------------------------------------------------------
struct Point {
class point
int x, y;
{
};
public:
int x, y;
 
//////////////////////////////////////////////////////
point() { x = y = 0; }
class MyBitmap {
point( int a, int b ) { x = a; y = b; }
public:
int distanceSqrd( const point& p )
MyBitmap() : pen_(nullptr) {}
{
~MyBitmap() {
int xd = p.x - x,
yd = p.y - yDeleteObject(pen_);
DeleteDC(hdc_);
DeleteObject(bmp_);
}
 
bool Create(int w, int h) {
return xd * xd + yd * yd;
}BITMAPINFO bi;
ZeroMemory(&bi, sizeof(bi));
};
//--------------------------------------------------------------------------------------------------
class myBitmap
{
public:
myBitmap() : pen( NULL ) {}
~myBitmap()
{
DeleteObject( pen );
DeleteDC( hdc );
DeleteObject( bmp );
}
 
bi.bmiHeader.biSize = sizeof(bi.bmiHeader);
bool create( int w, int h )
bi.bmiHeader.biBitCount = sizeof(DWORD) * 8;
{
bi.bmiHeader.biCompression = BI_RGB;
BITMAPINFO bi;
bi.bmiHeader.biPlanes = 1;
void *pBits;
bi.bmiHeader.biWidth = w;
ZeroMemory( &bi, sizeof( bi ) );
bi.bmiHeader.biHeight = -h;
 
void *bits_ptr = nullptr;
bi.bmiHeader.biSize = sizeof( bi.bmiHeader );
HDC dc = GetDC(GetConsoleWindow());
bi.bmiHeader.biBitCount = sizeof( DWORD ) * 8;
bmp_ = CreateDIBSection(dc, &bi, DIB_RGB_COLORS, &bits_ptr, nullptr, 0);
bi.bmiHeader.biCompression = BI_RGB;
if (!bmp_) return false;
bi.bmiHeader.biPlanes = 1;
bi.bmiHeader.biWidth = w;
bi.bmiHeader.biHeight = -h;
 
hdc_ = CreateCompatibleDC(dc);
HDC dc = GetDC( GetConsoleWindow() );
SelectObject(hdc_, bmp_);
bmp = CreateDIBSection( dc, &bi, DIB_RGB_COLORS, &pBits, NULL, 0 );
ReleaseDC(GetConsoleWindow(), dc);
if( !bmp ) return false;
 
width_ = w;
hdc = CreateCompatibleDC( dc );
height_ = h;
SelectObject( hdc, bmp );
ReleaseDC( GetConsoleWindow(), dc );
 
return true;
width = w; height = h;
}
 
void SetPenColor(DWORD clr) {
return true;
if (pen_) DeleteObject(pen_);
}
pen_ = CreatePen(PS_SOLID, 1, clr);
SelectObject(hdc_, pen_);
}
 
bool SaveBitmap(const char* path) {
void setPenColor( DWORD clr )
HANDLE file = CreateFile(path, GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, nullptr);
{
if (file == INVALID_HANDLE_VALUE) {
if( pen ) DeleteObject( pen );
return false;
pen = CreatePen( PS_SOLID, 1, clr );
SelectObject( hdc, pen );
}
 
BITMAPFILEHEADER fileheader;
void saveBitmap( string path )
BITMAPINFO infoheader;
{
BITMAP bitmap;
BITMAPFILEHEADER fileheader;
GetObject(bmp_, sizeof(bitmap), &bitmap);
BITMAPINFO infoheader;
BITMAP bitmap;
DWORD* dwpBits;
DWORD wb;
HANDLE file;
 
DWORD* dwp_bits = new DWORD[bitmap.bmWidth * bitmap.bmHeight];
GetObject( bmp, sizeof( bitmap ), &bitmap );
ZeroMemory(dwp_bits, bitmap.bmWidth * bitmap.bmHeight * sizeof(DWORD));
ZeroMemory(&infoheader, sizeof(BITMAPINFO));
ZeroMemory(&fileheader, sizeof(BITMAPFILEHEADER));
 
infoheader.bmiHeader.biBitCount = sizeof(DWORD) * 8;
dwpBits = new DWORD[bitmap.bmWidth * bitmap.bmHeight];
infoheader.bmiHeader.biCompression = BI_RGB;
ZeroMemory( dwpBits, bitmap.bmWidth * bitmap.bmHeight * sizeof( DWORD ) );
infoheader.bmiHeader.biPlanes = 1;
ZeroMemory( &infoheader, sizeof( BITMAPINFO ) );
infoheader.bmiHeader.biSize = sizeof(infoheader.bmiHeader);
ZeroMemory( &fileheader, sizeof( BITMAPFILEHEADER ) );
infoheader.bmiHeader.biHeight = bitmap.bmHeight;
infoheader.bmiHeader.biWidth = bitmap.bmWidth;
infoheader.bmiHeader.biSizeImage = bitmap.bmWidth * bitmap.bmHeight * sizeof(DWORD);
 
fileheader.bfType = 0x4D42;
infoheader.bmiHeader.biBitCount = sizeof( DWORD ) * 8;
fileheader.bfOffBits = sizeof(infoheader.bmiHeader.biCompression) =+ BI_RGBsizeof(BITMAPFILEHEADER);
fileheader.bfSize = fileheader.bfOffBits + infoheader.bmiHeader.biSizeImage;
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 );
 
GetDIBits(hdc_, bmp_, 0, height_, (LPVOID)dwp_bits, &infoheader, DIB_RGB_COLORS);
fileheader.bfType = 0x4D42;
fileheader.bfOffBits = sizeof( infoheader.bmiHeader ) + sizeof( BITMAPFILEHEADER );
fileheader.bfSize = fileheader.bfOffBits + infoheader.bmiHeader.biSizeImage;
 
DWORD wb;
GetDIBits( hdc, bmp, 0, height, ( LPVOID )dwpBits, &infoheader, DIB_RGB_COLORS );
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;
file = CreateFile( path.c_str(), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
return true;
WriteFile( file, &fileheader, sizeof( BITMAPFILEHEADER ), &wb, NULL );
}
WriteFile( file, &infoheader.bmiHeader, sizeof( infoheader.bmiHeader ), &wb, NULL );
WriteFile( file, dwpBits, bitmap.bmWidth * bitmap.bmHeight * 4, &wb, NULL );
CloseHandle( file );
 
HDC hdc() { return hdc_; }
delete [] dwpBits;
int width() { return width_; }
}
int height() { return height_; }
 
private:
HDC getDC() { return hdc; }
HBITMAP bmp_;
int getWidth() { return width; }
HDC hdc_;
int getHeight() { return height; }
HPEN pen_;
 
int width_, height_;
private:
HBITMAP bmp;
HDC hdc;
HPEN pen;
int width, height;
};
//--------------------------------------------------------------------------------------------------
class Voronoi
{
public:
void make( myBitmap* bmp, int count )
{
_bmp = bmp;
createPoints( count );
createColors();
createSites();
setSitesPoints();
}
 
static int DistanceSqrd(const Point& point, int x, int y) {
private:
int xd = x - point.x;
void createSites()
int yd = y - point.y;
{
return (xd * xd) + (yd * yd);
int w = _bmp->getWidth(), h = _bmp->getHeight(), d;
}
for( int hh = 0; hh < h; hh++ )
{
for( int ww = 0; ww < w; ww++ )
{
point bpt( ww, hh );
int ind = -1, dist = INT_MAX;
for( int it = 0; it < points.size(); it++ )
{
d = ( points[it] ).distanceSqrd( bpt );
if( d < dist )
{
dist = d;
ind = it;
}
}
 
//////////////////////////////////////////////////////
if( ind > -1 )
class Voronoi {
SetPixel( _bmp->getDC(), ww, hh, colors[ind] );
public:
else
void Make(MyBitmap* bmp, int count) {
__asm nop // should never happen!
}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 setSitesPointsSetSitesPoints() {
for (const auto& point : points_) {
{
int x = point.x, y = point.y;
for( vector<point>::iterator it = points.begin(); it < points.end(); it++ )
for (int i = -1; i < 2; i++)
{
int x = ( *itfor ).x,(int yj = (-1; *itj ).y< 2; j++)
for( int i = -1; i <SetPixel(bmp_->hdc(), 2;x + i+, y + j, 0);
for( int j = -1; j < 2; j++ )
SetPixel( _bmp->getDC(), x + i, y + j, 0 );
}
}
}
 
void createPointsCreatePoints( int count) ){
const int w = bmp_->width() - 20, h = bmp_->height() - 20;
{
for (int i = 0; i < count; i++) {
int w = _bmp->getWidth() - 20, h = _bmp->getHeight() - 20;
points_.push_back({ rand() % w + 10, rand() % h + 10 });
for( int i = 0; i < count; i++ )
{
point p( rand() % w + 10, rand() % h + 10 );
points.push_back( p );
}
}
}
 
void createColorsCreateColors() {
for (size_t i = 0; i < points_.size(); i++) {
{
DWORD c = RGB(rand() % 200 + 50, rand() % 200 + 55, rand() % 200 + 50);
for( int i = 0; i < points.size(); i++ )
colors_.push_back(c);
{
DWORD c = RGB( rand() % 200 + 50, rand() % 200 + 55, rand() % 200 + 50 );
colors.push_back( c );
}
}
}
 
vector<pointPoint> pointspoints_;
vector<DWORD> colorscolors_;
myBitmapMyBitmap* _bmpbmp_;
};
//--------------------------------------------------------------------------------------------------
int main(int argc, char* argv[])
{
ShowWindow( GetConsoleWindow(), SW_MAXIMIZE );
srand( GetTickCount() );
 
//////////////////////////////////////////////////////
myBitmap bmp;
int main(int argc, char* argv[]) {
bmp.create( 512, 512 );
ShowWindow(GetConsoleWindow(), SW_MAXIMIZE);
bmp.setPenColor( 0 );
srand(GetTickCount());
 
Voronoi v;
MyBitmap v.make( &bmp, 50 );
bmp.Create(512, 512);
bmp.SetPenColor(0);
 
Voronoi v;
BitBlt( GetDC( GetConsoleWindow() ), 20, 20, 532, 532, bmp.getDC(), 0, 0, SRCCOPY );
bmpv.saveBitmapMake( "f://rc//v.&bmp", 50);
 
BitBlt(GetDC(GetConsoleWindow()), 20, 20, 512, 512, bmp.hdc(), 0, 0, SRCCOPY);
system( "pause" );
bmp.SaveBitmap("v.bmp");
 
system("pause");
return 0;
 
return 0;
}
</syntaxhighlight>
//--------------------------------------------------------------------------------------------------
</lang>
 
=={{header|D}}==
{{trans|Go}}
<langsyntaxhighlight lang="d">import std.random, std.algorithm, std.range, bitmap;
 
struct Point { intuint x, y; }
 
Point[]enum randomPoints = (in size_t nPoints, in size_t nx, in size_t ny) {=>
nPoints.iota
immutable RndPt = (int) => Point(uniform(0, nx), uniform(0, ny));
.map!((int) => Point(uniform(0, nx), uniform(0, ny)))
return iota(nPoints).map!RndPt().array();
.array;
}
 
Image!RGB generateVoronoi(in Point[] pts,
in size_t nx, in size_t ny) /*nothrow*/ {
// Generate a random color for each sitecentroid.
immutable RndRBGrndRBG = (int) => RGB(castuniform!"[]"(ubyte)uniform(0.min, 256ubyte.max),
cast(ubyte)uniform!"[]"(0ubyte.min, 256ubyte.max),
cast(ubyte)uniform!"[]"(0ubyte.min, 256ubyte.max));
const colors = iota(pts.length).iota.map!RndRBG()rndRBG.array();
 
// Generate diagram by coloring pixels with color of nearest site.
Line 368 ⟶ 484:
foreach (immutable x; 0 .. nx)
foreach (immutable y; 0 .. ny) {
immutable dCmp = (in Point a, in Point b) pure nothrow =>
((a.x - x) ^^ 2 + (a.y - y) ^^ 2) <
((b.x - x) ^^ 2 + (b.y - y) ^^ 2);
// img[x, y] = colors[pts.length - minPosreduce!(min!dCmp(pts).length];
img[x, y] = colors[pts.length - pts.minPos!dCmp.length];
}
 
// Mark each sitecentroid with a blackwhite dot.
foreach (immutable p; pts)
img[p.x, p.ytupleof] = RGB.blackwhite;
return img;
}
Line 386 ⟶ 503:
.generateVoronoi(imageWidth, imageHeight)
.savePPM6("voronoi.ppm");
}</langsyntaxhighlight>
 
=={{header|Delphi}}==
<syntaxhighlight lang="delphi">
uses System.Generics.Collections;
procedure TForm1.Voronoi;
const
p = 3;
cells = 100;
size = 1000;
 
var
aCanvas : TCanvas;
px, py: array of integer;
color: array of Tcolor;
Img: TBitmap;
lastColor:Integer;
auxList: TList<TPoint>;
poligonlist : TDictionary<integer,TList<TPoint>>;
pointarray : array of TPoint;
 
n,i,x,y,k,j: Integer;
d1,d2: double;
 
function distance(x1,x2,y1,y2 :Integer) : Double;
begin
result := sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); ///Euclidian
// result := abs(x1 - x2) + abs(y1 - y2); // Manhattan
// result := power(power(abs(x1 - x2), p) + power(abs(y1 - y2), p), (1 / p)); // Minkovski
end;
 
begin
 
poligonlist := TDictionary<integer,TList<Tpoint>>.create;
 
n := 0;
Randomize;
 
img := TBitmap.Create;
img.Width :=1000;
img.Height :=1000;
 
setlength(px,cells);
setlength(py,cells);
setlength(color,cells);
 
for i:= 0 to cells-1 do
begin
px[i] := Random(size);
py[i] := Random(size);
 
color[i] := Random(16777215);
auxList := TList<Tpoint>.Create;
poligonlist.Add(i,auxList);
end;
 
for x := 0 to size - 1 do
begin
lastColor:= 0;
for y := 0 to size - 1 do
begin
n:= 0;
 
for i := 0 to cells - 1 do
begin
d1:= distance(px[i], x, py[i], y);
d2:= distance(px[n], x, py[n], y);
 
if d1 < d2 then
begin
n := i;
end;
end;
if n <> lastColor then
begin
poligonlist[n].Add(Point(x,y));
poligonlist[lastColor].Add(Point(x,y));
lastColor := n;
end;
end;
 
poligonlist[n].Add(Point(x,y));
poligonlist[lastColor].Add(Point(x,y));
lastColor := n;
end;
 
for j := 0 to cells -1 do
begin
 
SetLength(pointarray, poligonlist[j].Count);
for I := 0 to poligonlist[j].Count - 1 do
begin
if Odd(i) then
pointarray[i] := poligonlist[j].Items[i];
end;
for I := 0 to poligonlist[j].Count - 1 do
begin
if not Odd(i) then
pointarray[i] := poligonlist[j].Items[i];
end;
Img.Canvas.Pen.Color := color[j];
Img.Canvas.Brush.Color := color[j];
Img.Canvas.Polygon(pointarray);
 
Img.Canvas.Pen.Color := clBlack;
Img.Canvas.Brush.Color := clBlack;
Img.Canvas.Rectangle(px[j] -2, py[j] -2, px[j] +2, py[j] +2);
end;
Canvas.Draw(0,0, img);
end;
</syntaxhighlight>
 
 
=={{header|EasyLang}}==
[https://easylang.dev/show/#cod=fZBBboMwFET3PsVbVZAqjl2JXTlJxAIMqJYS0xqngttXtqlo2qgb+H4zns8w3pzhbX2faOmQAvBDuHnH/OEDRcuBlmc6DnSlkMLNNgwzNS+VGCePJUxkGC+75dzwVONb11sX0Eppjuikrf9o5o+mkibTlpUaFTdFHv0RLr8h0F+to0Zz4hs9+MrNS52rF24524YjS0nh1jyv5e60Iz2vKXyH+7b+DtoM7Q6luH+b6TL5WDlamw1ep8+BhRM6FldSVaw/T5vNDyagpNbpIVKqFDkx/oYHbVNyrpjycsM4RtVYby4DSlZCii8= Run it]
 
{{trans|BASIC256}}
<syntaxhighlight>
func hypo a b .
return sqrt (a * a + b * b)
.
nsites = 25
for i to nsites
nx[] &= randint 1001 - 1
ny[] &= randint 1001 - 1
nc[] &= randint 1000 - 1
.
for y = 0 to 1000
for x = 0 to 1000
dmin = 1 / 0
for i to nsites
d = hypo (nx[i] - x) (ny[i] - y)
if d < dmin
dmin = d
imin = i
.
.
color nc[imin]
move x / 10 - 0.05 y / 10 - 0.05
rect 0.11 0.11
.
.
color 000
for i to nsites
move nx[i] / 10 ny[i] / 10
circle 0.5
.
</syntaxhighlight>
 
=={{header|FreeBASIC}}==
{{trans|Python}}
<syntaxhighlight lang="freebasic">Dim Shared As Integer ancho = 500, alto = 500
Screenres ancho, alto, 8
Cls
Randomize Timer
 
Function hypot(a As Integer, b As Integer) As Double
Return Sqr(a^2 + b^2)
End Function
 
Sub Generar_Diagrama_Voronoi(ancho As Integer, alto As Integer, num_celdas As Integer)
Dim As Integer nx(num_celdas), ny(num_celdas), nr(num_celdas), ng(num_celdas), nb(num_celdas)
Dim As Integer x, i, y, j, dmin, d
For i = 1 To num_celdas
nx(i) = (Rnd * ancho)
ny(i) = (Rnd * alto)
nr(i) = (Rnd * 256)
ng(i) = (Rnd * 256)
nb(i) = (Rnd * 256)
Next i
For y = 1 To alto
For x = 1 To ancho
dmin = hypot(ancho-1, alto-1)
j = -1
For i = 1 To num_celdas
d = hypot(nx(i)-x, ny(i)-y)
If d < dmin Then dmin = d : j = i
Next i
Pset (x, y), Rgb(nr(j), ng(j), ng(j))
Next x
Next y
End Sub
 
Generar_Diagrama_Voronoi(ancho, alto, 25)
Bsave "Voronoi_diadram.bmp",0
Sleep</syntaxhighlight>
 
=={{header|Go}}==
[[file:GoVoronoi.png|thumb|right|Output png]]
<langsyntaxhighlight lang="go">package main
 
import (
Line 472 ⟶ 776:
fmt.Println(err)
}
}</langsyntaxhighlight>
 
=={{header|Haskell}}==
Uses the repa and repa-io libraries.
<syntaxhighlight lang="haskell">
-- Compile with: ghc -O2 -fllvm -fforce-recomp -threaded --make
{-# LANGUAGE BangPatterns #-}
module Main where
 
import System.Random
 
import Data.Word
import Data.Array.Repa as Repa
import Data.Array.Repa.IO.BMP
 
{-# INLINE sqDistance #-}
sqDistance :: Word32 -> Word32 -> Word32 -> Word32 -> Word32
sqDistance !x1 !y1 !x2 !y2 = ((x1-x2)^2) + ((y1-y2)^2)
 
centers :: Int -> Int -> Array U DIM2 Word32
centers nCenters nCells =
fromListUnboxed (Z :. nCenters :. 2) $ take (2*nCenters) $ randomRs (0, fromIntegral nCells) (mkStdGen 1)
 
applyReduce2 arr f =
traverse arr (\(i :. j) -> i) $ \lookup (Z:.i) ->
f (lookup (Z:.i:.0)) (lookup (Z:.i:.1))
 
minimize1D arr = foldS f h t
where
indexed arr = traverse arr id (\src idx@(Z :. i) -> (src idx, (fromIntegral i)))
(Z :. n) = extent arr
iarr = indexed arr
h = iarr ! (Z :. 0)
t = extract (Z :. 1) (Z :. (n-1)) iarr
 
f min@(!valMin, !iMin ) x@(!val, !i) | val < valMin = x
| otherwise = min
 
voronoi :: Int -> Int -> Array D DIM2 Word32
voronoi nCenters nCells =
let
{-# INLINE cellReducer #-}
cellReducer = applyReduce2 (centers nCenters nCells)
{-# INLINE nearestCenterIndex #-}
nearestCenterIndex = snd . (Repa.! Z) . minimize1D
in
Repa.fromFunction (Z :. nCells :. nCells :: DIM2) $ \ (Z:.i:.j) ->
nearestCenterIndex $ cellReducer (sqDistance (fromIntegral i) (fromIntegral j))
 
genColorTable :: Int -> Array U DIM1 (Word8, Word8, Word8)
genColorTable n = fromListUnboxed (Z :. n) $ zip3 l1 l2 l3
where
randoms = randomRs (0,255) (mkStdGen 1)
(l1, rest1) = splitAt n randoms
(l2, rest2) = splitAt n rest1
l3 = take n rest2
 
colorize :: Array U DIM1 (Word8, Word8, Word8) -> Array D DIM2 Word32 -> Array D DIM2 (Word8, Word8, Word8)
colorize ctable = Repa.map $ \x -> ctable Repa.! (Z:. fromIntegral x)
 
main = do
let nsites = 150
let ctable = genColorTable nsites
voro <- computeP $ colorize ctable (voronoi nsites 512) :: IO (Array U DIM2 (Word8, Word8, Word8))
writeImageToBMP "out.bmp" voro
 
</syntaxhighlight>
 
=={{header|Icon}} and {{header|Unicon}}==
Line 478 ⟶ 848:
[[File:Voronoi-normal_unicon.PNG|right]]
[[File:Voronoi-taxi_unicon.PNG|right]]
<langsyntaxhighlight Iconlang="icon">link graphics,printf,strings
 
record site(x,y,colour) # site data position and colour
Line 548 ⟶ 918:
every site := !siteL do # mark sites
DrawCircle(site.x,site.y,1)
end</langsyntaxhighlight>
 
{{libheader|Icon Programming Library}}
Line 554 ⟶ 924:
[http://www.cs.arizona.edu/icon/library/src/procs/graphics.icn graphics.icn provides graphics support]
[http://www.cs.arizona.edu/icon/library/src/procs/strings.icn strings.icn provides cat ]
 
 
=={{header|J}}==
 
=== Explicit version ===
 
A straightforward solution: generate random points and for each pixel find the index of the least distance. Note that the square root is avoided to improve performance.
<langsyntaxhighlight lang="j">NB. (number of points) voronoi (shape)
NB. Generates an array of indices of the nearest point
voronoi =: 4 :0
Line 564 ⟶ 936:
(i.<./)@:(+/@:*:@:-"1&p)"1 ,"0/&i./ y
)
viewmat 25 voronoi 500 500</lang>
 
load'viewmat'
Another solution generates Voronoi cells from Delaunay triangulation. The page [[Voronoi diagram/J/Delaunay triangulation]] also contains a convex hull algorithm.
viewmat 25 voronoi 500 500</syntaxhighlight>
 
Another solution generates Voronoi cells from Delaunay triangulation. The page [[Voronoi diagram/J/Delaunay triangulation]] also contains a convex hull algorithm. This is a vector based approach instead of a pixel based approach and is about twice as fast for this task's example.
 
=== Tacit version ===
 
This a direct reformulation of the explicit version.
 
<syntaxhighlight lang="j">Voronoi=. ,"0/&i./@:] (i. <./)@:(+/@:*:@:-"1)"1 _ ] ?@$~ 2 ,~ [
viewmat 25 Voronoi 500 500 [ load'viewmat'</syntaxhighlight>
 
=={{header|Java}}==
{{libheader|Swing}} {{libheader|AWT}}
<syntaxhighlight lang="java">import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
 
import javax.imageio.ImageIO;
import javax.swing.JFrame;
 
public class Voronoi extends JFrame {
static double p = 3;
static BufferedImage I;
static int px[], py[], color[], cells = 100, size = 1000;
 
public Voronoi() {
super("Voronoi Diagram");
setBounds(0, 0, size, size);
setDefaultCloseOperation(EXIT_ON_CLOSE);
int n = 0;
Random rand = new Random();
I = new BufferedImage(size, size, BufferedImage.TYPE_INT_RGB);
px = new int[cells];
py = new int[cells];
color = new int[cells];
for (int i = 0; i < cells; i++) {
px[i] = rand.nextInt(size);
py[i] = rand.nextInt(size);
color[i] = rand.nextInt(16777215);
 
}
for (int x = 0; x < size; x++) {
for (int y = 0; y < size; y++) {
n = 0;
for (byte i = 0; i < cells; i++) {
if (distance(px[i], x, py[i], y) < distance(px[n], x, py[n], y)) {
n = i;
 
}
}
I.setRGB(x, y, color[n]);
 
}
}
 
Graphics2D g = I.createGraphics();
g.setColor(Color.BLACK);
for (int i = 0; i < cells; i++) {
g.fill(new Ellipse2D .Double(px[i] - 2.5, py[i] - 2.5, 5, 5));
}
 
try {
ImageIO.write(I, "png", new File("voronoi.png"));
} catch (IOException e) {
 
}
 
}
 
public void paint(Graphics g) {
g.drawImage(I, 0, 0, this);
}
 
static double distance(int x1, int x2, int y1, int y2) {
double d;
d = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); // Euclidian
// d = Math.abs(x1 - x2) + Math.abs(y1 - y2); // Manhattan
// d = Math.pow(Math.pow(Math.abs(x1 - x2), p) + Math.pow(Math.abs(y1 - y2), p), (1 / p)); // Minkovski
return d;
}
 
public static void main(String[] args) {
new Voronoi().setVisible(true);
}
}
</syntaxhighlight>
 
=={{header|JavaScript}}==
===Version #1.===
The obvious route to this in JavaScript would be to use Mike Bostock's D3.js library.
 
There are various examples of Voronoi tesselations,
 
some dynamic:
 
https://bl.ocks.org/mbostock/d1d81455dc21e10f742f
 
some interactive:
 
https://bl.ocks.org/mbostock/4060366
 
and all with source code, at https://bl.ocks.org/mbostock
 
===Version #2.===
I would agree: using D3.js library can be very helpful. But having stable and compact algorithm in Python (Sidef) made it possible to develop looking the same Voronoi diagram in "pure" JavaScript.
A few custom helper functions simplified code, and they can be used for any other applications.
{{Works with|Chrome}}
[[File:VDjs1150.png|200px|right|thumb|Output VDjs1150.png]]
[[File:VDjs210.png|200px|right|thumb|Output VDjs210.png]]
[[File:VDjs310.png|200px|right|thumb|Output VDjs310.png]]
 
<syntaxhighlight lang="javascript"><!-- VoronoiD.html -->
<html>
<head><title>Voronoi diagram</title>
<script>
// HF#1 Like in PARI/GP: return random number 0..max-1
function randgp(max) {return Math.floor(Math.random()*max)}
// HF#2 Random hex color
function randhclr() {
return "#"+
("00"+randgp(256).toString(16)).slice(-2)+
("00"+randgp(256).toString(16)).slice(-2)+
("00"+randgp(256).toString(16)).slice(-2)
}
// HF#3 Metrics: Euclidean, Manhattan and Minkovski 3/20/17
function Metric(x,y,mt) {
if(mt==1) {return Math.sqrt(x*x + y*y)}
if(mt==2) {return Math.abs(x) + Math.abs(y)}
if(mt==3) {return(Math.pow(Math.pow(Math.abs(x),3) + Math.pow(Math.abs(y),3),0.33333))}
}
// Plotting Voronoi diagram. aev 3/10/17
function pVoronoiD() {
var cvs=document.getElementById("cvsId");
var ctx=cvs.getContext("2d");
var w=cvs.width, h=cvs.height;
var x=y=d=dm=j=0, w1=w-2, h1=h-2;
var n=document.getElementById("sites").value;
var mt=document.getElementById("mt").value;
var X=new Array(n), Y=new Array(n), C=new Array(n);
ctx.fillStyle="white"; ctx.fillRect(0,0,w,h);
for(var i=0; i<n; i++) {
X[i]=randgp(w1); Y[i]=randgp(h1); C[i]=randhclr();
}
for(y=0; y<h1; y++) {
for(x=0; x<w1; x++) {
dm=Metric(h1,w1,mt); j=-1;
for(var i=0; i<n; i++) {
d=Metric(X[i]-x,Y[i]-y,mt)
if(d<dm) {dm=d; j=i;}
}//fend i
ctx.fillStyle=C[j]; ctx.fillRect(x,y,1,1);
}//fend x
}//fend y
ctx.fillStyle="black";
for(var i=0; i<n; i++) {
ctx.fillRect(X[i],Y[i],3,3);
}
}
</script></head>
<body style="font-family: arial, helvatica, sans-serif;">
<b>Please input number of sites: </b>
<input id="sites" value=100 type="number" min="10" max="150" size="3">&nbsp;&nbsp;
<b>Metric: </b>
<select id="mt">
<option value=1 selected>Euclidean</option>
<option value=2>Manhattan</option>
<option value=3>Minkovski</option>
</select>&nbsp;
<input type="button" value="Plot it!" onclick="pVoronoiD();">&nbsp;&nbsp;
<h3>Voronoi diagram</h3>
<canvas id="cvsId" width="640" height="640" style="border: 2px inset;"></canvas>
</body>
</html>
</syntaxhighlight>
{{Output}}
<pre>
Page demonstrating Voronoi diagram for any reasonable number of sites and selected metric.
Right clicking on canvas with image allows you to save it as png-file, for example.
</pre>
 
=={{header|Julia}}==
First version generates an image with random colors as centroids for the voronoi tesselation:
<syntaxhighlight lang="julia">
using Images
function voronoi(w, h, n_centroids)
dist = (point,vector) -> sqrt.((point[1].-vector[:,1]).^2 .+ (point[2].-vector[:,2]).^2)
dots = [rand(1:h, n_centroids) rand(1:w, n_centroids) rand(RGB{N0f8}, n_centroids)]
img = zeros(RGB{N0f8}, h, w)
for x in 1:h, y in 1:w
distances = dist([x,y],dots) # distance
nn = findmin(distances)[2]
img[x,y] = dots[nn,:][3]
end
return img
end
img = voronoi(800, 600, 200)
</syntaxhighlight>
 
Second version takes an image as an input, samples random centroids for the voronoi cells, and asignes every pixel within that cell the color of the centroid:
 
<syntaxhighlight lang="julia">
using TestImages, Images
function voronoi_img!(img, n_centroids)
n,m = size(img)
w = minimum([n,m])
dist = (point,vector) -> sqrt.((point[1].-vector[:,1]).^2 .+ (point[2].-vector[:,2]).^2)
dots = [rand(1:n, n_centroids) rand(1:m, n_centroids)]
c = []
for i in 1:size(dots,1)
p = dots[i,:]
append!(c, [img[p[1],p[2]]])
end
dots = [dots c]
for x in 1:n, y in 1:m
distances = dist([x,y],dots) # distance
nn = findmin(distances)[2]
img[x,y] = dots[nn,:][3]
end
end
img = testimage("mandrill")
voronoi_img!(img, 300)
</syntaxhighlight>
 
=={{header|Kotlin}}==
{{trans|Java}}
<syntaxhighlight lang="scala">// version 1.1.3
 
import java.awt.Color
import java.awt.Graphics
import java.awt.Graphics2D
import java.awt.geom.Ellipse2D
import java.awt.image.BufferedImage
import java.util.Random
import javax.swing.JFrame
 
fun distSq(x1: Int, x2: Int, y1: Int, y2: Int): Int {
val x = x1 - x2
val y = y1 - y2
return x * x + y * y
}
 
class Voronoi(val cells: Int, val size: Int) : JFrame("Voronoi Diagram") {
val bi: BufferedImage
 
init {
setBounds(0, 0, size, size)
defaultCloseOperation = EXIT_ON_CLOSE
val r = Random()
bi = BufferedImage(size, size, BufferedImage.TYPE_INT_RGB)
val px = IntArray(cells) { r.nextInt(size) }
val py = IntArray(cells) { r.nextInt(size) }
val cl = IntArray(cells) { r.nextInt(16777215) }
for (x in 0 until size) {
for (y in 0 until size) {
var n = 0
for (i in 0 until cells) {
if (distSq(px[i], x, py[i], y) < distSq(px[n], x, py[n], y)) n = i
}
bi.setRGB(x, y, cl[n])
}
}
val g = bi.createGraphics()
g.color = Color.BLACK
for (i in 0 until cells) {
g.fill(Ellipse2D.Double(px[i] - 2.5, py[i] - 2.5, 5.0, 5.0))
}
}
 
override fun paint(g: Graphics) {
g.drawImage(bi, 0, 0, this)
}
}
 
fun main(args: Array<String>) {
Voronoi(70, 700).isVisible = true
}</syntaxhighlight>
 
=={{header|Liberty BASIC}}==
Line 573 ⟶ 1,226:
If no place on a vertical line is closer to the current site, then there's no point looking further left or right.
Don't bother square-rooting to get distances..
<syntaxhighlight lang="lb">
<lang lb>
WindowWidth =600
WindowHeight =600
Line 665 ⟶ 1,318:
next y
end function
</syntaxhighlight>
</lang>
 
=={{header|MathematicaLua}}==
{{libheader|LÖVE}}
<lang Mathematica>Needs["ComputationalGeometry`"]
{{works with|LÖVE|11.3}}
{{trans|Python}}
<syntaxhighlight lang="lua">
function love.load( )
love.math.setRandomSeed( os.time( ) ) --set the random seed
keys = { } --an empty table where we will store key presses
number_cells = 50 --the number of cells we want in our diagram
--draw the voronoi diagram to a canvas
voronoiDiagram = generateVoronoi( love.graphics.getWidth( ), love.graphics.getHeight( ), number_cells )
end
 
function hypot( x, y )
return math.sqrt( x*x + y*y )
end
 
function generateVoronoi( width, height, num_cells )
canvas = love.graphics.newCanvas( width, height )
local imgx = canvas:getWidth( )
local imgy = canvas:getHeight( )
local nx = { }
local ny = { }
local nr = { }
local ng = { }
local nb = { }
for a = 1, num_cells do
table.insert( nx, love.math.random( 0, imgx ) )
table.insert( ny, love.math.random( 0, imgy ) )
table.insert( nr, love.math.random( 0, 1 ) )
table.insert( ng, love.math.random( 0, 1 ) )
table.insert( nb, love.math.random( 0, 1 ) )
end
love.graphics.setColor( { 1, 1, 1 } )
love.graphics.setCanvas( canvas )
for y = 1, imgy do
for x = 1, imgx do
dmin = hypot( imgx-1, imgy-1 )
j = -1
for i = 1, num_cells do
d = hypot( nx[i]-x, ny[i]-y )
if d < dmin then
dmin = d
j = i
end
end
love.graphics.setColor( { nr[j], ng[j], nb[j] } )
love.graphics.points( x, y )
end
end
--reset color
love.graphics.setColor( { 1, 1, 1 } )
--draw points
for b = 1, num_cells do
love.graphics.points( nx[b], ny[b] )
end
love.graphics.setCanvas( )
return canvas
end
 
--RENDER
function love.draw( )
--reset color
love.graphics.setColor( { 1, 1, 1 } )
--draw diagram
love.graphics.draw( voronoiDiagram )
--draw drop shadow text
love.graphics.setColor( { 0, 0, 0 } )
love.graphics.print( "space: regenerate\nesc: quit", 1, 1 )
--draw text
love.graphics.setColor( { 0.7, 0.7, 0 } )
love.graphics.print( "space: regenerate\nesc: quit" )
end
 
--CONTROL
function love.keyreleased( key )
if key == 'space' then
voronoiDiagram = generateVoronoi( love.graphics.getWidth( ), love.graphics.getHeight( ), number_cells )
elseif key == 'escape' then
love.event.quit( )
end
end
</syntaxhighlight>
 
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<syntaxhighlight lang="mathematica">Needs["ComputationalGeometry`"]
DiagramPlot[{{4.4, 14}, {6.7, 15.25}, {6.9, 12.8}, {2.1, 11.1}, {9.5, 14.9}, {13.2, 11.9}, {10.3, 12.3},
{6.8, 9.5}, {3.3, 7.7}, {0.6, 5.1}, {5.3, 2.4}, {8.45, 4.7}, {11.5, 9.6}, {13.8, 7.3}, {12.9, 3.1}, {11, 1.1}}]</langsyntaxhighlight>
[[File:mma_voronoi.png|Right]]
 
=={{header|МК-61/52}}==
<syntaxhighlight lang="text">0 П4
0 П5
ИП0 1 - x^2 ИП1 1 - x^2 + КвКор П3
9 П6
КИП6 П8 {x} 2 10^x * П9
[x] ИП5 - x^2 ИП9 {x} 2 10^x * ИП4 - x^2 + КвКор П9
ИП3 - x<0 47 ИП9 П3 ИП6 П7
ИП6 ИП2 - 9 - x>=0 17
КИП7 [x] С/П
КИП5 ИП5 ИП1 - x>=0 04
КИП4 ИП4 ИП0 - x>=0 02</syntaxhighlight>
 
''Input'': Р0 - diagram width; Р1 - diagram height; Р0 - number of the points; РA - РE - coordinates and colors of the points in format ''C,XXYY'' (example: 3,0102).
 
Example of the manually compiled output (graphical output from this class of devices is missing):
 
{| border="0" width="250"
|- align="center" bgcolor="#F0C0C0"
|·||·||·||·||·||·||·||·||·||·
|- align="center" bgcolor="#F0C0C0"
|·||·||·||·||·||·||·||·||·||·
|- align="center" bgcolor="#F0C0C0"
|·||·||·||·||·||·||·||·||·||·
|- align="center" bgcolor="#F0C0C0"
|·||·||·||•||·||·||·||·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·
|- align="center" bgcolor="#F0C0C0"
| bgcolor="#C0F0C0" |·|| bgcolor="#C0F0C0" |·||·||·||·||·|||·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·
|- align="center" bgcolor="#C0F0C0"
|·||·||·||·|| bgcolor="#F0C0C0" |·|| bgcolor="#F0C0C0" |·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·
|- align="center" bgcolor="#C0F0C0"
|·||·||•||·||·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·
|- align="center" bgcolor="#C0F0C0"
|·||·||·||·||·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·|| bgcolor="#C0C0F0" |·
|- align="center" bgcolor="#C0C0F0"
| bgcolor="#C0F0C0" |·|| bgcolor="#C0F0C0" |·|| bgcolor="#C0F0C0" |·|| bgcolor="#C0F0C0" |·|| bgcolor="#C0F0C0" |·||·||·||•||·||·
|- align="center" bgcolor="#C0C0F0"
| bgcolor="#C0F0C0" |·|| bgcolor="#C0F0C0" |·|| bgcolor="#C0F0C0" |·|| bgcolor="#C0F0C0" |·||·||·||·||·||·||·
|}
 
=={{header|Nim}}==
{{works with|nim|0.19.4}}
{{libheader|nim-libgd}}
<syntaxhighlight lang="nim">
from sequtils import newSeqWith
from random import rand, randomize
from times import now
import libgd
 
const
img_width = 400
img_height = 300
nSites = 20
 
proc dot(x, y: int): int = x * x + y * y
 
proc generateVoronoi(img: gdImagePtr) =
 
randomize(cast[int64](now()))
 
# random sites
let sx = newSeqWith(nSites, rand(img_width))
let sy = newSeqWith(nSites, rand(img_height))
# generate a random color for each site
let sc = newSeqWith(nSites, img.setColor(rand(255), rand(255), rand(255)))
 
# generate diagram by coloring each pixel with color of nearest site
for x in 0 ..< img_width:
for y in 0 ..< img_height:
var dMin = dot(img_width, img_height)
var sMin: int
for s in 0 ..< nSites:
if (let d = dot(sx[s] - x, sy[s] - y); d) < dMin:
(sMin, dMin) = (s, d)
 
img.setPixel(point=[x, y], color=sc[sMin])
 
# mark each site with a black box
let black = img.setColor(0x000000)
for s in 0 ..< nSites:
img.drawRectangle(
startCorner=[sx[s] - 2, sy[s] - 2],
endCorner=[sx[s] + 2, sy[s] + 2],
color=black,
fill=true)
 
proc main() =
 
withGd imageCreate(img_width, img_height, trueColor=true) as img:
img.generateVoronoi()
 
let png_out = open("outputs/voronoi_diagram.png", fmWrite)
img.writePng(png_out)
png_out.close()
 
main()
</syntaxhighlight>
 
=={{header|OCaml}}==
{{works with|ocaml|4.07.1}}
 
<syntaxhighlight lang="ocaml">let n_sites = 220
let size_x = 640
let size_y = 480
let sq2 ~x ~y =
(x * x + y * y)
let rand_int_range a b =
a + Random.int (b - a + 1)
 
let nearest_site ~site ~x ~y =
let ret = ref 0 in
let dist = ref 0 in
Array.iteri (fun k (sx, sy) ->
let d = sq2 (x - sx) (y - sy) in
if k = 0 || d < !dist then begin
dist := d;
ret := k;
end
) site;
!ret
 
let gen_map ~site ~rgb =
let nearest = Array.make (size_x * size_y) 0 in
let buf = Bytes.create (3 * size_x * size_y) in
 
for y = 0 to pred size_y do
for x = 0 to pred size_x do
nearest.(y * size_x + x) <-
nearest_site ~site ~x ~y;
done;
done;
 
for i = 0 to pred (size_y * size_x) do
let j = i * 3 in
let r, g, b = rgb.(nearest.(i)) in
Bytes.set buf (j+0) (char_of_int r);
Bytes.set buf (j+1) (char_of_int g);
Bytes.set buf (j+2) (char_of_int b);
done;
Printf.printf "P6\n%d %d\n255\n" size_x size_y;
print_bytes buf;
;;
 
let () =
Random.self_init ();
let site =
Array.init n_sites (fun i ->
(Random.int size_x,
Random.int size_y))
in
let rgb =
Array.init n_sites (fun i ->
(rand_int_range 160 255,
rand_int_range 40 160,
rand_int_range 20 140))
in
gen_map ~site ~rgb</syntaxhighlight>
 
=={{header|Perl}}==
{{trans|Raku}}
<syntaxhighlight lang="perl">use strict;
use warnings;
use Imager;
 
my %type = (
Taxicab => sub { my($px, $py, $x, $y) = @_; abs($px - $x) + abs($py - $y) },
Euclidean => sub { my($px, $py, $x, $y) = @_; ($px - $x)**2 + ($py - $y)**2 },
Minkowski => sub { my($px, $py, $x, $y) = @_; abs($px - $x)**3 + abs($py - $y)**3 },
);
 
my($xmax, $ymax) = (400, 400);
my @domains;
for (1..30) {
push @domains, {
x => int 5 + rand $xmax-10,
y => int 5 + rand $ymax-10,
rgb => [int rand 255, int rand 255, int rand 255]
}
}
 
for my $type (keys %type) {
our $img = Imager->new(xsize => $xmax, ysize => $ymax, channels => 3);
voronoi($type, $xmax, $ymax, @domains);
dot(1,@domains);
$img->write(file => "voronoi-$type.png");
 
sub voronoi {
my($type, $xmax, $ymax, @d) = @_;
for my $x (0..$xmax) {
for my $y (0..$ymax) {
my $i = 0;
my $d = 10e6;
for (0..$#d) {
my $dd = &{$type{$type}}($d[$_]{'x'}, $d[$_]{'y'}, $x, $y);
if ($dd < $d) { $d = $dd; $i = $_ }
}
$img->setpixel(x => $x, y => $y, color => $d[$i]{rgb} );
}
}
}
 
sub dot {
my($radius, @d) = @_;
for (0..$#d) {
my $dx = $d[$_]{'x'};
my $dy = $d[$_]{'y'};
for my $x ($dx-$radius .. $dx+$radius) {
for my $y ($dy-$radius .. $dy+$radius) {
$img->setpixel(x => $x, y => $y, color => [0,0,0]);
}
}
}
}
}</syntaxhighlight>
[https://github.com/SqrtNegInf/Rosettacode-Perl5-Smoke/blob/master/ref/voronoi-Euclidean.png Euclidean Voronoi diagram] (offsite image)
 
=={{header|Phix}}==
{{trans|Liberty_BASIC}}
{{libheader|Phix/pGUI}}
{{libheader|Phix/online}}
Lifted the calculation strategy from Liberty Basic. <br>
Can resize, double or halve sites (press +/-), and toggle between Euclid, Manhattan, and Minkowski (press e/m/w).
You can run this online [http://phix.x10.mx/p2js/voronoi.htm here] (it' a bit slow tho).
<!--<syntaxhighlight lang="phix">(phixonline)-->
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\VoronoiDiagram.exw
-- ===============================
--
-- Can resize, double or halve the number of sites (press +/-), and toggle
-- between Euclid, Manhattan, and Minkowski (press e/m/w).
--</span>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">include</span> <span style="color: #000000;">pGUI</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
<span style="color: #004080;">Ihandle</span> <span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">timer</span>
<span style="color: #004080;">cdCanvas</span> <span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span>
<span style="color: #000080;font-style:italic;">-- Stop any current drawing process before starting a new one:
-- Without this it /is/ going to crash, if it tries to finish
-- drawing all 100 sites, when there are now only 50, for eg.</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">timer_active</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">nsites</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">200</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">last_width</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">last_height</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">siteX</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">siteY</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">siteC</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">EUCLID</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">MANHATTAN</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">MINKOWSKI</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">dmodes</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"Euclid"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Manhattan"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Minkowski"</span><span style="color: #0000FF;">}</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">dmode</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">EUCLID</span><span style="color: #0000FF;">,</span>
<span style="color: #000000;">drawn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- (last dmode actually shown)</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">distance</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">y1</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">x2</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">y2</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">d</span>
<span style="color: #000000;">x1</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">x2</span>
<span style="color: #000000;">y1</span> <span style="color: #0000FF;">-=</span> <span style="color: #000000;">y2</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">dmode</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">EUCLID</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">*</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">+</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">*</span><span style="color: #000000;">y1</span> <span style="color: #000080;font-style:italic;">-- (no need for sqrt)</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">MANHATTAN</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">)+</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">MINKOWSKI</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">),</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)+</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">),</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- ("" power(d,1/3))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">d</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #004080;">sequence</span> <span style="color: #000000;">nearestIndex</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">dist</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">checkRow</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">site</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">height</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">dxSquared</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">x1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">siteX</span><span style="color: #0000FF;">[</span><span style="color: #000000;">site</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">x</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">dmode</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">EUCLID</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">dxSquared</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x1</span><span style="color: #0000FF;">*</span><span style="color: #000000;">x1</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">MANHATTAN</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">dxSquared</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">MINKOWSKI</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">dxSquared</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">),</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">height</span> <span style="color: #008080;">do</span>
<span style="color: #000080;font-style:italic;">-- atom dSquared = distance(siteX[site],siteY[site],x,y) -- (sub-optimal..)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">dSquared</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">y1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">siteY</span><span style="color: #0000FF;">[</span><span style="color: #000000;">site</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">y</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">dmode</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">EUCLID</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">dSquared</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dxSquared</span><span style="color: #0000FF;">+</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">*</span><span style="color: #000000;">y1</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">MANHATTAN</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">dSquared</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dxSquared</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">case</span> <span style="color: #000000;">MINKOWSKI</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">dSquared</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dxSquared</span><span style="color: #0000FF;">+</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">abs</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">),</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">dSquared</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">dist</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span>
<span style="color: #000000;">dist</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dSquared</span>
<span style="color: #000000;">nearestIndex</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">site</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">true</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">redraw_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">width</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">height</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupGetIntInt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"DRAWSIZE"</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">width</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">last_width</span>
<span style="color: #008080;">or</span> <span style="color: #000000;">height</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">last_height</span>
<span style="color: #008080;">or</span> <span style="color: #000000;">nsites</span><span style="color: #0000FF;">!=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">siteX</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">nsites</span><span style="color: #0000FF;"><</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #000000;">nsites</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">siteX</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_rand</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">width</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nsites</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">siteY</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_rand</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">height</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nsites</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">siteC</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_rand</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">#FFFFFF</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nsites</span><span style="color: #0000FF;">))</span>
<span style="color: #000000;">last_width</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">width</span>
<span style="color: #000000;">last_height</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">height</span>
<span style="color: #000000;">drawn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">drawn</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">dmode</span> <span style="color: #000080;font-style:italic;">-- (prevent double-draw, and)</span>
<span style="color: #008080;">and</span> <span style="color: #008080;">not</span> <span style="color: #000000;">timer_active</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- (drawing when rug moved..)</span>
<span style="color: #000000;">drawn</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dmode</span>
<span style="color: #7060A8;">cdCanvasActivate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasClear</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">(),</span> <span style="color: #000000;">t1</span>
<span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()+</span><span style="color: #000000;">0.25</span>
<span style="color: #000000;">nearestIndex</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">height</span><span style="color: #0000FF;">),</span><span style="color: #000000;">width</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">dist</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">height</span><span style="color: #0000FF;">),</span><span style="color: #000000;">width</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- fill distance table with distances from the first site</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">x1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">siteX</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">y1</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">siteY</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">width</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">height</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">dist</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">distance</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">timer_active</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000080;font-style:italic;">--for other towns</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">nsites</span> <span style="color: #008080;">do</span>
<span style="color: #000080;font-style:italic;">-- look left</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">siteX</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">checkRow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">height</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000080;font-style:italic;">-- look right</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">siteX</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]+</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">width</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">checkRow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">height</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">timer_active</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()></span><span style="color: #000000;">t1</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Voronoi diagram (generating - %3.2f%%)"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">100</span><span style="color: #0000FF;">*</span><span style="color: #000000;">i</span><span style="color: #0000FF;">/</span><span style="color: #000000;">nsites</span><span style="color: #0000FF;">})</span>
<span style="color: #7060A8;">IupFlush</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()+</span><span style="color: #000000;">0.25</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">height</span> <span style="color: #008080;">do</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">nearest</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nearestIndex</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">]</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">width</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">nearestIndex</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">]<></span><span style="color: #000000;">nearest</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">siteC</span><span style="color: #0000FF;">[</span><span style="color: #000000;">nearest</span><span style="color: #0000FF;">])</span>
<span style="color: #7060A8;">cdCanvasLine</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">nearest</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nearestIndex</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">y</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">x</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">timer_active</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">siteC</span><span style="color: #0000FF;">[</span><span style="color: #000000;">nearest</span><span style="color: #0000FF;">])</span>
<span style="color: #7060A8;">cdCanvasLine</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">width</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">timer_active</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_BLACK</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">nsites</span> <span style="color: #008080;">do</span>
<span style="color: #7060A8;">cdCanvasSector</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">siteX</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">siteY</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">360</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #7060A8;">cdCanvasFlush</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetStrAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"TITLE"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"Voronoi diagram - %s, %dx%d, %d sites, %3.2fs"</span><span style="color: #0000FF;">,</span>
<span style="color: #0000FF;">{</span><span style="color: #000000;">dmodes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">dmode</span><span style="color: #0000FF;">],</span><span style="color: #000000;">width</span><span style="color: #0000FF;">,</span><span style="color: #000000;">height</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nsites</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">map_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">cdcanvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_IUP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ih</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">cddbuffer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">cdCreateCanvas</span><span style="color: #0000FF;">(</span><span style="color: #004600;">CD_DBUFFER</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cdcanvas</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasSetBackground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_WHITE</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">cdCanvasSetForeground</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cddbuffer</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">CD_BLACK</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_DEFAULT</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">key_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">=</span><span style="color: #004600;">K_ESC</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CLOSE</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">wasdmode</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dmode</span>
<span style="color: #008080;">switch</span> <span style="color: #000000;">c</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'+'</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">nsites</span> <span style="color: #0000FF;">*=</span> <span style="color: #000000;">2</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'-'</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">nsites</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">floor</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nsites</span><span style="color: #0000FF;">/</span><span style="color: #000000;">2</span><span style="color: #0000FF;">),</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'E'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'e'</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">dmode</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">EUCLID</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'M'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'m'</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">dmode</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">MANHATTAN</span>
<span style="color: #008080;">case</span> <span style="color: #008000;">'W'</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'w'</span><span style="color: #0000FF;">:</span> <span style="color: #000000;">dmode</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">MINKOWSKI</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">dmode</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">wasdmode</span>
<span style="color: #008080;">or</span> <span style="color: #000000;">nsites</span><span style="color: #0000FF;">!=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">siteX</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #000080;font-style:italic;">-- give any current drawing process 0.1s to abandon:</span>
<span style="color: #000000;">timer_active</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #7060A8;">IupStoreAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"RUN"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"YES"</span><span style="color: #0000FF;">)</span>
<span style="color: #000080;font-style:italic;">-- IupUpdate(canvas)</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_CONTINUE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">timer_cb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">Ihandle</span> <span style="color: #000080;font-style:italic;">/*ih*/</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">timer_active</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
<span style="color: #7060A8;">IupStoreAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">timer</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"RUN"</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"NO"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupUpdate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004600;">IUP_IGNORE</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupOpen</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">canvas</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupCanvas</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"RASTERSIZE=600x400"</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetCallbacks</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"MAP_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"map_cb"</span><span style="color: #0000FF;">),</span>
<span style="color: #008000;">"ACTION"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"redraw_cb"</span><span style="color: #0000FF;">)})</span>
<span style="color: #000000;">timer</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupTimer</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"timer_cb"</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">100</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (inactive)</span>
<span style="color: #000000;">dlg</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">IupDialog</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span><span style="color: #008000;">`TITLE="Voronoi diagram"`</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetCallback</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"KEY_CB"</span><span style="color: #0000FF;">,</span> <span style="color: #7060A8;">Icallback</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"key_cb"</span><span style="color: #0000FF;">))</span>
<span style="color: #7060A8;">IupShow</span><span style="color: #0000FF;">(</span><span style="color: #000000;">dlg</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">IupSetAttribute</span><span style="color: #0000FF;">(</span><span style="color: #000000;">canvas</span><span style="color: #0000FF;">,</span> <span style="color: #008000;">"RASTERSIZE"</span><span style="color: #0000FF;">,</span> <span style="color: #004600;">NULL</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- release the minimum limitation</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">platform</span><span style="color: #0000FF;">()!=</span><span style="color: #004600;">JS</span> <span style="color: #008080;">then</span>
<span style="color: #7060A8;">IupMainLoop</span><span style="color: #0000FF;">()</span>
<span style="color: #7060A8;">IupClose</span><span style="color: #0000FF;">()</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #000000;">main</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
 
=={{header|Processing}}==
{{trans|Python}}
<syntaxhighlight lang="java">void setup() {
size(500, 500);
generateVoronoiDiagram(width, height, 25);
saveFrame("VoronoiDiagram.png");
}
 
void generateVoronoiDiagram(int w, int h, int num_cells) {
int nx[] = new int[num_cells];
int ny[] = new int[num_cells];
int nr[] = new int[num_cells];
int ng[] = new int[num_cells];
int nb[] = new int[num_cells];
for (int n=0; n < num_cells; n++) {
nx[n]=int(random(w));
ny[n]=int(random(h));
nr[n]=int(random(256));
ng[n]=int(random(256));
nb[n]=int(random(256));
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
float dmin = dist(0, 0, w - 1, h - 1);
int j = -1;
for (int i=0; i < num_cells; i++) {
float d = dist(0, 0, nx[i] - x, ny[i] - y);
if (d < dmin) {
dmin = d;
j = i;
}
}
set(x, y, color(nr[j], ng[j], nb[j]));
}
}
}
}
</syntaxhighlight>
 
==={{header|Processing Python mode}}===
{{trans|Python}}
<syntaxhighlight lang="python">def setup():
size(500, 500)
generate_voronoi_diagram(width, height, 25)
saveFrame("VoronoiDiagram.png")
 
def generate_voronoi_diagram(w, h, num_cells):
nx, ny, nr, ng, nb = [], [], [], [], []
for i in range(num_cells):
nx.append(int(random(w)))
ny.append(int(random(h)))
nr.append(int(random(256)))
ng.append(int(random(256)))
nb.append(int(random(256)))
for y in range(h):
for x in range(w):
dmin = dist(0, 0, w - 1, h - 1)
j = -1
for i in range(num_cells):
d = dist(0, 0, nx[i] - x, ny[i] - y)
if d < dmin:
dmin = d
j = i
set(x, y, color(nr[j], ng[j], nb[j]))
</syntaxhighlight>
 
=={{header|Prolog}}==
Line 678 ⟶ 1,912:
 
 
<langsyntaxhighlight Prologlang="prolog">:- dynamic pt/6.
voronoi :-
V is random(20) + 20,
Line 739 ⟶ 1,973:
minkowski_3(X1, Y1, X2, Y2, D) :-
D is (abs(X2 - X1)**3 + abs(Y2-Y1)**3)**0.33.
</syntaxhighlight>
</lang>
[[File:prolog_manhattan.png|320px]]
[[File:prolog_euclide.png‎|320px]]
Line 748 ⟶ 1,982:
===Euclidean===
[[File:Voronoi_PureBasic.png‎|320px|thumb|center|Voronoi Diagram in PureBasic]]
<langsyntaxhighlight PureBasiclang="purebasic">Structure VCoo
x.i: y.i
Colour.i: FillColour.i
Line 817 ⟶ 2,051:
If file$ <> ""
SaveImage(img, file$, #PB_ImagePlugin_PNG)
EndIf</langsyntaxhighlight>
 
===Taxicab===
[[File:Voronoi_Diagram_in_PureBasic_(Taxicab).png‎|320px|thumb|center|Voronoi Diagram in PureBasic]]
<langsyntaxhighlight PureBasiclang="purebasic">Structure VCoo
x.i: y.i
Colour.i: FillColour.i
Line 888 ⟶ 2,122:
If file$ <> ""
SaveImage(img, file$, #PB_ImagePlugin_PNG)
EndIf</langsyntaxhighlight>
 
=={{header|Python}}==
 
This implementation takes in a list of points, each point being a tuple and returns a dictionary consisting of all the points at a given site.
<langsyntaxhighlight lang="python">from PIL import Image
import random
import math
Line 924 ⟶ 2,158:
image.show()
generate_voronoi_diagram(500, 500, 25)</langsyntaxhighlight>
{{out}}
=== Sample Output: ===
[[File:Voronoi_python.png|500px|thumb|center|Voronoi Diagram in Python]]
 
Alternatively, vectorized code leveraging numpy and scipy is 2x shorter and 10x faster, as seen below.
 
Note that for large numbers of points, using a KDTree will be much faster thanks to lookups in log(N) time rather than N comparisons at every coordinate. The code below has running time O(X*Y*log(N)), whereas the code above has running time O(X*Y*N). For 1000 points, the code below is 250x faster than the above.
 
Alternative metrics can be supported by using a [https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KDTree.html#sklearn.neighbors.KDTree.query scikit-learn KDTree ].
 
<syntaxhighlight lang="python">
import numpy as np
from PIL import Image
from scipy.spatial import KDTree
 
def generate_voronoi_diagram(X, Y, num_cells):
# Random colors and points
colors = np.random.randint((256, 256, 256), size=(num_cells, 3), dtype=np.uint8)
points = np.random.randint((Y, X), size=(num_cells, 2))
 
# Construct a list of all possible (y,x) coordinates
idx = np.indices((Y, X))
coords = np.moveaxis(idx, 0, -1).reshape((-1, 2))
 
# Find the closest point to each coordinate
_d, labels = KDTree(points).query(coords)
labels = labels.reshape((Y, X))
 
# Export an RGB image
rgb = colors[labels]
img = Image.fromarray(rgb, mode='RGB')
img.save('VoronoiDiagram.png', 'PNG')
img.show()
return rgb
</syntaxhighlight>
 
=={{header|QB64}}==
{{trans|Liberty Basic}}
<syntaxhighlight lang="qb64">_Title "Voronoi Diagram"
 
Dim As Integer pnt, px, py, i, x, y, adjct, sy, ly
Dim As Double st
 
'=====================================================================
' Changes number of points and screen size here
'=====================================================================
pnt = 100
px = 512
py = 512
'=====================================================================
Screen _NewImage(px, py, 32)
Randomize Timer
 
Dim Shared As Integer pax(pnt), pay(pnt), indx(px, py)
Dim Shared As Long dSqr(px, py)
Dim As Long col(pnt)
 
For i = 1 To pnt
pax(i) = Int(Rnd * px)
pay(i) = Int(Rnd * py)
col(i) = _RGB(Rnd * 256, Rnd * 256, Rnd * 256)
Next
st = Timer
For x = 0 To px - 1
For y = 0 To py - 1
dSqr(x, y) = (pax(1) - x) * (pax(1) - x) + (pay(1) - y) * (pay(1) - y)
indx(x, y) = 1
Next
Next
 
For i = 2 To pnt
ly = py - 1
For x = pax(i) To 0 Step -1
If (scan(i, x, ly)) = 0 Then Exit For
Next x
For x = pax(i) + 1 To px - 1
If (scan(i, x, ly)) = 0 Then Exit For
Next
Next
 
For x = 0 To px - 1
For y = 0 To py - 1
sy = y
adjct = indx(x, y)
For y = y + 1 To py
If indx(x, y) <> adjct Then y = y - 1: Exit For
Next
Line (x, sy)-(x, y + 1), col(adjct)
Next
Next
 
Sleep
System
 
Function scan (site As Integer, x As Integer, ly As Integer)
Dim As Integer ty
Dim As Long delt2, dsq
delt2 = (pax(site) - x) * (pax(site) - x)
For ty = 0 To ly
dsq = (pay(site) - ty) * (pay(site) - ty) + delt2
If dsq <= dSqr(x, ty) Then
dSqr(x, ty) = dsq
indx(x, ty) = site
scan = 1
End If
Next
End Function</syntaxhighlight>
 
=={{header|R}}==
One of the R's great powers is its unlimited number of packages, virtually thousands of them. For any applications big or small you can find a package.
In case of Voronoi diagram there are many of packages, e.g.: deldir, alphahull, dismo, ggplot, ggplot2, tripack, CGAL, etc.
Not to mention all linked packages.
Do you need random colors? Again, find a few packages more...<br>
So, I've decided to use proven algorithms instead. Result - small compact code and
beautiful diagrams with any reasonable amount of sites.
A few custom helper functions simplified code, and they can be used for any other applications.<br>
If you have not a super fast computer, you can watch animation of plotting in "R Graphics" sub-window of the "RGui" window.
{{trans|JavaScript v.#2}}
{{Works with|R|3.3.3 and above}}
[[File:VDR1150.png|200px|right|thumb|Output VDR1150.png]]
[[File:VDR210.png|200px|right|thumb|Output VDR210.png]]
[[File:VDR310.png|200px|right|thumb|Output VDR310.png]]
 
<syntaxhighlight lang="r">
## HF#1 Random Hex color
randHclr <- function() {
m=255;r=g=b=0;
r <- sample(0:m, 1, replace=TRUE);
g <- sample(0:m, 1, replace=TRUE);
b <- sample(0:m, 1, replace=TRUE);
return(rgb(r,g,b,maxColorValue=m));
}
## HF#2 Metrics: Euclidean, Manhattan and Minkovski
Metric <- function(x, y, mt) {
if(mt==1) {return(sqrt(x*x + y*y))}
if(mt==2) {return(abs(x) + abs(y))}
if(mt==3) {return((abs(x)^3 + abs(y)^3)^0.33333)}
}
 
## Plotting Voronoi diagram. aev 3/12/17
## ns - number of sites, fn - file name, ttl - plot title.
## mt - type of metric: 1 - Euclidean, 2 - Manhattan, 3 - Minkovski.
pVoronoiD <- function(ns, fn="", ttl="",mt=1) {
cat(" *** START VD:", date(), "\n");
if(mt<1||mt>3) {mt=1}; mts=""; if(mt>1) {mts=paste0(", mt - ",mt)};
m=640; i=j=k=m1=m-2; x=y=d=dm=0;
if(fn=="") {pf=paste0("VDR", mt, ns, ".png")} else {pf=paste0(fn, ".png")};
if(ttl=="") {ttl=paste0("Voronoi diagram, sites - ", ns, mts)};
cat(" *** Plot file -", pf, "title:", ttl, "\n");
plot(NA, xlim=c(0,m), ylim=c(0,m), xlab="", ylab="", main=ttl);
X=numeric(ns); Y=numeric(ns); C=numeric(ns);
for(i in 1:ns) {
X[i]=sample(0:m1, 1, replace=TRUE);
Y[i]=sample(0:m1, 1, replace=TRUE);
C[i]=randHclr();
}
for(i in 0:m1) {
for(j in 0:m1) {
dm=Metric(m1,m1,mt); k=-1;
for(n in 1:ns) {
d=Metric(X[n]-j,Y[n]-i, mt);
if(d<dm) {dm=d; k=n;}
}
clr=C[k]; segments(j, i, j, i, col=clr);
}
}
points(X, Y, pch = 19, col = "black", bg = "white")
dev.copy(png, filename=pf, width=m, height=m);
dev.off(); graphics.off();
cat(" *** END VD:",date(),"\n");
}
## Executing:
pVoronoiD(150) ## Euclidean metric
pVoronoiD(10,"","",2) ## Manhattan metric
pVoronoiD(10,"","",3) ## Minkovski metric
</syntaxhighlight>
{{Output}}
<pre>
> pVoronoiD(150) ## Euclidean metric
*** START VD: Sun Mar 12 19:04:26 2017
*** Plot file - VDR1150.png title: Voronoi diagram, sites - 150
*** END VD: Sun Mar 12 19:11:03 2017
> pVoronoiD(10,"","",2) ## Manhattan metric
*** START VD: Mon Mar 20 13:57:46 2017
*** Plot file - VDR210.png title: Voronoi diagram, sites - 10, mt - 2
*** END VD: Mon Mar 20 13:59:42 2017
> pVoronoiD(10,"","",3) ## Minkovski metric
*** START VD: Mon Mar 20 14:45:15 2017
*** Plot file - VDR310.png title: Voronoi diagram, sites - 10, mt - 3
*** END VD: Mon Mar 20 14:47:21 2017
</pre>
 
=={{header|Racket}}==
 
[[File:voronoi1.png|200px|thumb|right|Clustering using the nearest neigbour approach.]]
 
First approach
 
<syntaxhighlight lang="racket">
#lang racket
 
(require plot)
 
;; Performs clustering of points in a grid
;; using the nearest neigbour approach and shows
;; clusters in different colors
(define (plot-Voronoi-diagram point-list)
(define pts
(for*/list ([x (in-range 0 1 0.005)]
[y (in-range 0 1 0.005)])
(vector x y)))
(define clusters (clusterize pts point-list))
(plot
(append
(for/list ([r (in-list clusters)] [i (in-naturals)])
(points (rest r) #:color i #:sym 'fullcircle1))
(list (points point-list #:sym 'fullcircle5 #:fill-color 'white)))))
 
;; Divides the set of points into clusters
;; using given centroids
(define (clusterize data centroids)
(for*/fold ([res (map list centroids)]) ([x (in-list data)])
(define c (argmin (curryr (metric) x) centroids))
(dict-set res c (cons x (dict-ref res c)))))
</syntaxhighlight>
 
Different metrics
<syntaxhighlight lang="racket">
(define (euclidean-distance a b)
(for/sum ([x (in-vector a)] [y (in-vector b)])
(sqr (- x y))))
 
(define (manhattan-distance a b)
(for/sum ([x (in-vector a)] [y (in-vector b)])
(abs (- x y))))
 
(define metric (make-parameter euclidean-distance))
</syntaxhighlight>
 
[[File:voronoi2.png|200px|thumb|right|The contour plot of the classification function.]]
[[File:voronoi3.png|200px|thumb|right|Using Manhattan metric.]]
[[File:voronoi4.png|200px|thumb|right|Voronoi diagram in 3D space.]]
 
Alternative approach
 
<syntaxhighlight lang="racket">
;; Plots the Voronoi diagram as a contour plot of
;; the classification function built for a set of points
(define (plot-Voronoi-diagram2 point-list)
(define n (length point-list))
(define F (classification-function point-list))
(plot
(list
(contour-intervals (compose F vector) 0 1 0 1
#:samples 300
#:levels n
#:colors (range n)
#:contour-styles '(solid)
#:alphas '(1))
(points point-list #:sym 'fullcircle3))))
 
;; For a set of centroids returns a function
;; which finds the index of the centroid nearest
;; to a given point
(define (classification-function centroids)
(define tbl
(for/hash ([p (in-list centroids)] [i (in-naturals)])
(values p i)))
(λ (x)
(hash-ref tbl (argmin (curry (metric) x) centroids))))
</syntaxhighlight>
 
 
{{out}}
<syntaxhighlight lang="racket">
(define pts
(for/list ([i 50]) (vector (random) (random))))
 
(display (plot-Voronoi-diagram pts))
 
(display (plot-Voronoi-diagram2 pts))
 
(parameterize ([metric manhattan-distance])
(display (plot-Voronoi-diagram2 pts)))
 
;; Using the classification function it is possible to plot Voronoi diagram in 3D.
(define pts3d (for/list ([i 7]) (vector (random) (random) (random))))
(plot3d (list
(isosurfaces3d (compose (classification-function pts3d) vector)
0 1 0 1 0 1
#:line-styles '(transparent)
#:samples 100
#:colors (range 7)
#:alphas '(1))
(points3d pts3d #:sym 'fullcircle3)))
</syntaxhighlight>
 
=={{header|Raku}}==
(formerly Perl 6)
{{works with|Rakudo|2018.09}}
{{trans|Python}}
Perhaps "Inspired by Python" would be more accurate.
 
Generates a Euclidean, a Taxicab and a Minkowski Voronoi diagram using the same set of domain points and colors.
 
<syntaxhighlight lang="raku" line>use Image::PNG::Portable;
 
my @bars = '▁▂▃▅▆▇▇▆▅▃▂▁'.comb;
 
my %type = ( # Voronoi diagram type distance calculation
'Taxicab' => sub ($px, $py, $x, $y) { ($px - $x).abs + ($py - $y).abs },
'Euclidean' => sub ($px, $py, $x, $y) { ($px - $x)² + ($py - $y)² },
'Minkowski' => sub ($px, $py, $x, $y) { ($px - $x)³.abs + ($py - $y)³.abs },
);
 
my $width = 400;
my $height = 400;
my $dots = 30;
 
my @domains = map { Hash.new(
'x' => (5..$width-5).roll,
'y' => (5..$height-5).roll,
'rgb' => [(64..255).roll xx 3]
) }, ^$dots;
 
for %type.keys -> $type {
print "\nGenerating $type diagram... ", ' ' x @bars;
my $img = voronoi(@domains, :w($width), :h($height), :$type);
@domains.map: *.&dot($img);
$img.write: "Voronoi-{$type}-perl6.png";
}
 
sub voronoi (@domains, :$w, :$h, :$type) {
my $png = Image::PNG::Portable.new: :width($w), :height($h);
(^$w).race.map: -> $x {
print "\b" x 2+@bars, @bars.=rotate(1).join , ' ';
for ^$h -> $y {
my ($, $i) = min @domains.map: { %type{$type}(%($_)<x>, %($_)<y>, $x, $y), $++ };
$png.set: $x, $y, |@domains[$i]<rgb>
}
}
$png
}
 
sub dot (%h, $png, $radius = 3) {
for (%h<x> X+ -$radius .. $radius) X (%h<y> X+ -$radius .. $radius) -> ($x, $y) {
$png.set($x, $y, 0, 0, 0) if ( %h<x> - $x + (%h<y> - $y) * i ).abs <= $radius;
}
}
</syntaxhighlight>
 
See [https://github.com/thundergnat/rc/blob/master/img/Voronoi-Euclidean-perl6.png Euclidean], [https://github.com/thundergnat/rc/blob/master/img/Voronoi-Taxicab-perl6.png Taxicab] & [https://github.com/thundergnat/rc/blob/master/img/Voronoi-Minkowski-perl6.png Minkowski] Voronoi diagram example images.
 
=={{header|Red}}==
<syntaxhighlight lang="red">Red [
Source: https://github.com/vazub/rosetta-red
Tabs: 4
Needs: 'View
]
 
comment {
This is a naive and therefore inefficient approach. For production-related tasks,
a proper full implementation of Fortune's algorithm should be preferred.
}
 
canvas: 500x500
num-points: 50
diagram-l1: make image! canvas
diagram-l2: make image! canvas
 
distance: function [
"Find Taxicab (d1) and Euclidean (d2) distances between two points"
pt1 [pair!]
pt2 [pair!]
][
d1: (absolute (pt1/x - pt2/x)) + absolute (pt1/y - pt2/y)
d2: square-root ((pt1/x - pt2/x) ** 2 + ((pt1/y - pt2/y) ** 2))
reduce [d1 d2]
]
 
;-- Generate random origin points with respective region colors
points: collect [
random/seed now/time/precise
loop num-points [
keep random canvas
keep random white
]
]
 
;-- Color each pixel, based on region it belongs to
repeat y canvas/y [
repeat x canvas/x [
coord: as-pair x y
min-dist: distance 1x1 canvas
color-l1: color-l2: none
foreach [point color] points [
d: distance point coord
if d/1 < min-dist/1 [min-dist/1: d/1 color-l1: color]
if d/2 < min-dist/2 [min-dist/2: d/2 color-l2: color]
]
poke diagram-l1 coord color-l1
poke diagram-l2 coord color-l2
]
]
 
;-- Draw origin points for regions
foreach [point color] points [
draw diagram-l1 compose [circle (point) 1]
draw diagram-l2 compose [circle (point) 1]
]
 
;-- Put results on screen
view [
title "Voronoi Diagram"
image diagram-l1 image diagram-l2
]
</syntaxhighlight>
 
=={{header|ReScript}}==
<syntaxhighlight lang="rescript">let n_sites = 60
 
let size_x = 640
let size_y = 480
 
let rand_int_range = (a, b) => a + Random.int(b - a + 1)
 
let dist_euclidean = (x, y) => { (x * x + y * y) }
let dist_minkowski = (x, y) => { (x * x * x + y * y * y) }
let dist_taxicab = (x, y) => { abs(x) + abs(y) }
 
let dist_f = dist_euclidean
let dist_f = dist_minkowski
let dist_f = dist_taxicab
 
let nearest_site = (site, x, y) => {
let ret = ref(0)
let dist = ref(0)
Js.Array2.forEachi(site, ((sx, sy), k) => {
let d = dist_f((x - sx), (y - sy))
if (k == 0 || d < dist.contents) {
dist.contents = d
ret.contents = k
}
})
ret.contents
}
 
let gen_map = (site, rgb) => {
let nearest = Belt.Array.make((size_x * size_y), 0)
let buf = Belt.Array.make((3 * size_x * size_y), 0)
for y in 0 to size_y - 1 {
for x in 0 to size_x - 1 {
nearest[y * size_x + x] = nearest_site(site, x, y)
}
}
for i in 0 to (size_y * size_x) - 1 {
let j = i * 3
let (r, g, b) = rgb[nearest[i]]
buf[j+0] = r
buf[j+1] = g
buf[j+2] = b
}
Printf.printf("P3\n%d %d\n255\n", size_x, size_y)
Js.Array2.forEach(buf, (d) => Printf.printf("%d\n", d))
}
 
{
Random.self_init ();
let site =
Belt.Array.makeBy(n_sites, (i) => {
(Random.int(size_x),
Random.int(size_y))
})
 
let rgb =
Belt.Array.makeBy(n_sites, (i) => {
(rand_int_range( 50, 120),
rand_int_range( 80, 180),
rand_int_range(140, 240))
})
gen_map(site, rgb)
}
</syntaxhighlight>
 
=={{header|Ring}}==
<syntaxhighlight lang="ring">
# Project : Voronoi diagram
 
load "guilib.ring"
load "stdlib.ring"
paint = null
 
new qapp
{
spots = 100
leftside = 400
rightside = 400
locx = list(spots)
locy = list(spots)
rgb = newlist(spots,3)
seal = newlist(leftside, rightside)
reach = newlist(leftside, rightside)
 
win1 = new qwidget() {
setwindowtitle("Voronoi diagram")
setgeometry(100,100,800,600)
label1 = new qlabel(win1) {
setgeometry(10,10,800,600)
settext("")
}
new qpushbutton(win1) {
setgeometry(150,550,100,30)
settext("draw")
setclickevent("draw()")
}
show()
}
exec()
}
 
func draw
p1 = new qpicture()
color = new qcolor() {
setrgb(0,0,255,255)
}
pen = new qpen() {
setcolor(color)
setwidth(1)
}
paint = new qpainter() {
begin(p1)
setpen(pen)
 
for i =1 to spots
locx[i] = floor(leftside * randomf())
locy[i] = floor(rightside * randomf())
rgb[i][1] = floor(256 * randomf())
rgb[i][2] = floor(256 * randomf())
rgb[i][3] = floor(256 * randomf())
next
for x = 1 to leftside
for y = 1 to rightside
reach[x][y] = pow((locx[1] - x),2) + pow((locy[1] - y),2)
seal[x][y] = 1
next
next
for i = 2 to spots
for x = locx[i] to 0 step -1
if not (chkpos(i,x,1, rightside-1))
exit
ok
next
for x = locx[i] + 1 to leftside - 1
if not (chkpos(i, x, 1, rightside-1))
exit
ok
next
next
for x = 1 to leftside
for y = 1 to rightside
c1 = rgb[seal[x][y]][1]
c2 = rgb[seal[x][y]][2]
c3 = rgb[seal[x][y]][3]
color = new qcolor() { setrgb(c1,c2,c3,255) }
pen = new qpen() { setcolor(color) setwidth(10) }
setpen(pen)
starty = y
nearest = seal[x][y]
for y = (y + 1) to rightside
if seal[x][y] != nearest
y = y - 1
exit
ok
next
paint.drawline(x,starty,x,y + 1)
next
next
endpaint()
}
label1 { setpicture(p1) show() }
return
 
func chkpos(site,x,starty,endy)
chkpos = 0
dxsqr = 0
dxsqr = pow((locx[site]- x),2)
for y = starty to endy
dsqr = pow((locy[site] - y),2) + dxsqr
if x <= leftside and y <= leftside and x > 0 and y > 0
if dsqr <= reach[x][y]
reach[x][y] = dsqr
seal[x][y] = site
chkpos = 1
ok
ok
next
return chkpos
 
func randomf()
decimals(10)
str = "0."
for i = 1 to 10
nr = random(9)
str = str + string(nr)
next
return number(str)
</syntaxhighlight>
Output image:
 
https://www.dropbox.com/s/bjv9dhd0esnnokx/Voronoi.jpg?dl=0
 
=={{header|Ruby}}==
Uses [[Raster graphics operations/Ruby]]
[[File:voronoi_rb.png|thumb|right|Sample output from Ruby program]]
<syntaxhighlight lang="ruby"># frozen_string_literal: true
<lang ruby>load 'raster_graphics.rb'
 
require_relative 'raster_graphics'
 
class ColourPixel < Pixel
Line 941 ⟶ 2,790:
 
def distance_to(px, py)
Math::.hypot(px - x, py - y)
end
end
 
width, height = 300, 200
height = 200
npoints = 20
pixmap = Pixmap.new(width, height)
 
@bases = npoints.times.collect do |i_i|
ColourPixel.new(
3 + rand(width - 6), 3 + rand(height - 6), # provide a margin to draw a circle
RGBColour.new(rand(256), rand(256), rand(256))
)
end
 
pixmap.each_pixel do |x, y|
nearest = @bases.min_by { |base| base.distance_to(x, y) }
pixmap[x, y] = nearest.colour
end
 
@bases.each do |base|
pixmap[base.x, base.y] = RGBColour::BLACK
pixmap.draw_circle(base, 2, RGBColour::BLACK)
end
 
pixmap.save_as_png("'voronoi_rb.png"')</langsyntaxhighlight>
 
{{libheader|RubyGems}}
{{libheader|JRubyArt}}
JRubyArt is a port of processing to ruby
<syntaxhighlight lang="ruby"># frozen_string_literal: true
 
Tile = Struct.new(:x, :y, :color) do
def sq_dist(a, b)
(x - a)**2 + (y - b)**2
end
end
 
attr_reader :tiles
 
def settings
size 500, 500
end
 
def setup
sketch_title 'Voronoi Diagram'
load_pixels
color_mode(HSB, 1.0)
@tiles = generate_tiles(30)
draw_voronoi
update_pixels
draw_voronoi_centers
end
 
def generate_tiles(num)
(0..num).map { Tile.new(rand(width), rand(height), color(rand, 1.0, 1.0)) }
end
 
def draw_voronoi
grid(width, height) do |x, y|
closest = tiles.min_by { |tile| tile.sq_dist(x, y) }
pixels[x + y * width] = closest.color
end
end
 
def draw_voronoi_centers
tiles.each do |center|
no_stroke
fill 0
ellipse(center.x, center.y, 4, 4)
end
end
 
 
</syntaxhighlight>
 
=={{header|Run BASIC}}==
<syntaxhighlight lang="runbasic">graphic #g, 400,400
#g flush()
spots = 100
leftSide = 400
rightSide = 400
dim locX(spots)
dim locY(spots)
dim rgb(spots,3)
dim seal(leftSide, rightSide)
dim reach(leftSide, rightSide)
 
for i =1 to spots
locX(i) = int(leftSide * rnd(1))
locY(i) = int(rightSide * rnd(1))
rgb(i,1) = int(256 * rnd(1))
rgb(i,2) = int(256 * rnd(1))
rgb(i,3) = int(256 * rnd(1))
#g color(rgb(i,1),rgb(i,2),rgb(i,3))
#g set(locX(i),locY(i))
next i
#g size(1)
' find reach to the first site
for x = 0 to leftSide - 1
for y = 0 to rightSide - 1
reach(x, y) = (locX(1) - x) ^ 2 + (locY(1) - y) ^ 2
seal(x, y) = 1
next y
next x
#g color("darkblue")
 
' spots other than 1st spot
for i = 2 to spots
for x = locX(i) to 0 step -1 ' looking left
if not(chkPos(i,x,0, rightSide - 1)) then exit for
next x
for x = locX(i) + 1 to leftSide - 1 ' looking right
if not(chkPos(i, x, 0, rightSide - 1)) then exit for
next x
next i
for x = 0 to leftSide - 1
for y = 0 to rightSide - 1
c1 = rgb(seal(x, y),1)
c2 = rgb(seal(x, y),2)
c3 = rgb(seal(x, y),3)
#g color(c1,c2,c3)
startY = y
nearest = seal(x, y)
for y = y + 1 to rightSide
if seal(x, y) <> nearest then y = y - 1 : exit for
next y
#g line(x,startY,x,y + 1)
next y
next x
 
#g color("black")
#g size(4)
for i =1 to spots
#g set(locX(i),locY(i))
next i
render #g
end
 
function chkPos(site, x, startY, endY)
dxSqr = (locX(site) - x) ^ 2
for y = startY to endY
dSqr = (locY(site) - y) ^ 2 + dxSqr
if dSqr <= reach(x, y) then
reach(x,y) = dSqr
seal(x,y) = site
chkPos = 1
end if
next y
end function</syntaxhighlight>
 
=={{header|Rust}}==
 
This implementation uses SDL to display the diagram. The actual implementation of the Voronoi diagram is very fast because it's not pixel based, it's vector based, using [https://en.wikipedia.org/wiki/Fortune%27s_algorithm Fortune's Linesweep algorithm]. It can be found in the crate [https://crates.io/crates/voronoi voronoi].
 
The entire code, including the Crate.toml and a precompiled binary for Windows x86_64, can be found at https://github.com/ctrlcctrlv/interactive-voronoi/
 
<syntaxhighlight lang="rust">extern crate piston;
extern crate opengl_graphics;
extern crate graphics;
extern crate touch_visualizer;
 
#[cfg(feature = "include_sdl2")]
extern crate sdl2_window;
 
extern crate getopts;
extern crate voronoi;
extern crate rand;
 
use touch_visualizer::TouchVisualizer;
use opengl_graphics::{ GlGraphics, OpenGL };
use graphics::{ Context, Graphics };
use piston::window::{ Window, WindowSettings };
use piston::input::*;
use piston::event_loop::*;
#[cfg(feature = "include_sdl2")]
use sdl2_window::Sdl2Window as AppWindow;
use voronoi::{voronoi, Point, make_polygons};
use rand::Rng;
 
static DEFAULT_WINDOW_HEIGHT: u32 = 600;
static DEFAULT_WINDOW_WIDTH: u32 = 600;
 
struct Settings {
lines_only: bool,
random_count: usize
}
 
fn main() {
let args: Vec<String> = std::env::args().collect();
let mut opts = getopts::Options::new();
opts.optflag("l", "lines_only", "Don't color polygons, just outline them");
opts.optopt("r", "random_count", "On keypress \"R\", put this many random points on-screen", "RANDOMCOUNT");
let matches = opts.parse(&args[1..]).expect("Failed to parse args");
 
let settings = Settings{
lines_only: matches.opt_present("l"),
random_count: match matches.opt_str("r") {
None => { 50 },
Some(s) => { s.parse().expect("Random count of bad format") }
}
};
 
event_loop(&settings);
 
}
 
fn random_point() -> [f64; 2] {
[rand::thread_rng().gen_range(0., DEFAULT_WINDOW_HEIGHT as f64), rand::thread_rng().gen_range(0., DEFAULT_WINDOW_WIDTH as f64)]
}
 
fn random_color() -> [f32; 4] {
[rand::random::<f32>(), rand::random::<f32>(), rand::random::<f32>(), 1.0]
}
 
fn random_voronoi(dots: &mut Vec<[f64;2]>, colors: &mut Vec<[f32;4]>, num: usize) {
dots.clear();
colors.clear();
 
for _ in 0..num {
dots.push(random_point());
colors.push(random_color());
}
}
 
fn event_loop(settings: &Settings) {
let opengl = OpenGL::V3_2;
let mut window: AppWindow = WindowSettings::new("Interactive Voronoi", [DEFAULT_WINDOW_HEIGHT, DEFAULT_WINDOW_WIDTH])
.exit_on_esc(true).opengl(opengl).build().unwrap();
 
let ref mut gl = GlGraphics::new(opengl);
let mut touch_visualizer = TouchVisualizer::new();
let mut events = Events::new(EventSettings::new().lazy(true));
let mut dots = Vec::new();
let mut colors = Vec::new();
 
let mut mx = 0.0;
let mut my = 0.0;
 
while let Some(e) = events.next(&mut window) {
touch_visualizer.event(window.size(), &e);
if let Some(button) = e.release_args() {
match button {
Button::Keyboard(key) => {
if key == piston::input::keyboard::Key::N { dots.clear(); colors.clear(); }
if key == piston::input::keyboard::Key::R { random_voronoi(&mut dots, &mut colors, settings.random_count); }
}
Button::Mouse(_) => {
dots.push([mx, my]);
colors.push(random_color());
},
_ => ()
}
};
e.mouse_cursor(|x, y| {
mx = x;
my = y;
});
if let Some(args) = e.render_args() {
gl.draw(args.viewport(), |c, g| {
graphics::clear([1.0; 4], g);
let mut vor_pts = Vec::new();
for d in &dots {
vor_pts.push(Point::new(d[0], d[1]));
}
if vor_pts.len() > 0 {
let vor_diagram = voronoi(vor_pts, DEFAULT_WINDOW_WIDTH as f64);
let vor_polys = make_polygons(&vor_diagram);
for (i, poly) in vor_polys.iter().enumerate() {
if settings.lines_only {
draw_lines_in_polygon(poly, &c, g);
} else {
draw_polygon(poly, &c, g, colors[i]);
}
}
}
for d in &dots {
draw_ellipse(&d, &c, g);
}
});
}
}
 
}
 
fn draw_lines_in_polygon<G: Graphics>(
poly: &Vec<Point>,
c: &Context,
g: &mut G,
)
{
let color = [0.0, 0.0, 1.0, 1.0];
 
for i in 0..poly.len()-1 {
graphics::line(
color,
2.0,
[poly[i].x.into(), poly[i].y.into(), poly[i+1].x.into(), poly[i+1].y.into()],
c.transform,
g
)
}
}
 
fn draw_polygon<G: Graphics>(
poly: &Vec<Point>,
c: &Context,
g: &mut G,
color: [f32; 4]
) {
let mut polygon_points: Vec<[f64; 2]> = Vec::new();
 
for p in poly {
polygon_points.push([p.x.into(), p.y.into()]);
}
 
graphics::polygon(
color,
polygon_points.as_slice(),
c.transform,
g
)
}
 
fn draw_ellipse<G: Graphics>(
cursor: &[f64; 2],
c: &Context,
g: &mut G,
) {
let color = [0.0, 0.0, 0.0, 1.0];
graphics::ellipse(
color,
graphics::ellipse::circle(cursor[0], cursor[1], 4.0),
c.transform,
g
);
}
</syntaxhighlight>
 
=={{header|Scala}}==
===Java Swing Interoperability===
{{libheader|Scala Java Swing interoperability}}
{{works with|Scala|2.13}}
<syntaxhighlight lang="scala">import java.awt.geom.Ellipse2D
import java.awt.image.BufferedImage
import java.awt.{Color, Graphics, Graphics2D}
 
import scala.math.sqrt
 
object Voronoi extends App {
private val (cells, dim) = (100, 1000)
private val rand = new scala.util.Random
private val color = Vector.fill(cells)(rand.nextInt(0x1000000))
private val image = new BufferedImage(dim, dim, BufferedImage.TYPE_INT_RGB)
private val g: Graphics2D = image.createGraphics()
private val px = Vector.fill(cells)(rand.nextInt(dim))
private val py = Vector.fill(cells)(rand.nextInt(dim))
 
for (x <- 0 until dim;
y <- 0 until dim) {
var n = 0
 
def distance(x1: Int, x2: Int, y1: Int, y2: Int) =
sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2).toDouble) // Euclidian
 
for (i <- px.indices
if distance(px(i), x, py(i), y) < distance(px(n), x, py(n), y))
n = i
image.setRGB(x, y, color(n))
}
 
g.setColor(Color.BLACK)
for (i <- px.indices) g.fill(new Ellipse2D.Double(px(i) - 2.5, py(i) - 2.5, 5, 5))
 
new javax.swing.JFrame("Voronoi Diagram") {
override def paint(g: Graphics): Unit = {g.drawImage(image, 0, 0, this); ()}
 
setBounds(0, 0, dim, dim)
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE)
setLocationRelativeTo(null)
setResizable(false)
setVisible(true)
}
 
}</syntaxhighlight>
 
=={{header|Seed7}}==
[[file:Seed7Voronoi.png|thumb|right]]
<langsyntaxhighlight lang="seed7">$ include "seed7_05.s7i";
include "draw.s7i";
include "keybd.s7i";
Line 1,021 ⟶ 3,232:
KEYBOARD := GRAPH_KEYBOARD;
readln(KEYBOARD);
end func;</langsyntaxhighlight>
 
Original source: [http://seed7.sourceforge.net/algorith/graphic.htm#voronoi]
 
=={{header|Sidef}}==
{{trans|Python}}
<syntaxhighlight lang="ruby">require('Imager')
 
func generate_voronoi_diagram(width, height, num_cells) {
var img = %O<Imager>.new(xsize => width, ysize => height)
var (nx,ny,nr,ng,nb) = 5.of { [] }...
 
for i in (^num_cells) {
nx << rand(^width)
ny << rand(^height)
nr << rand(^256)
ng << rand(^256)
nb << rand(^256)
}
 
for y=(^height), x=(^width) {
var j = (^num_cells -> min_by {|i| hypot(nx[i]-x, ny[i]-y) })
img.setpixel(x => x, y => y, color => [nr[j], ng[j], nb[j]])
}
return img
}
 
var img = generate_voronoi_diagram(500, 500, 25)
img.write(file => 'VoronoiDiagram.png')</syntaxhighlight>
Output image: [https://github.com/trizen/rc/blob/master/img/voronoi-diagram-sidef.png Voronoi diagram]
 
=={{header|Tcl}}==
{{libheader|Tk}}
<langsyntaxhighlight lang="tcl">package require Tk
proc r to {expr {int(rand()*$to)}}; # Simple helper
 
Line 1,061 ⟶ 3,299:
# To display while generating, uncomment this line and the other one so commented
#update
voronoi demo 60</langsyntaxhighlight>
 
=={{header|Wren}}==
{{trans|Kotlin}}
{{libheader|DOME}}
<syntaxhighlight lang="wren">import "graphics" for Canvas, Color
import "dome" for Window
import "random" for Random
 
class Game {
static init() {
Window.title = "Voronoi diagram"
var cells = 70
var size = 700
Window.resize(size, size)
Canvas.resize(size, size)
voronoi(cells, size)
}
 
static update() {}
 
static draw(alpha) {}
 
static distSq(x1, x2, y1, y2) { (x1-x2)*(x1-x2) + (y1-y2)*(y1-y2) }
 
static voronoi(cells, size) {
var r = Random.new()
var px = List.filled(cells, 0)
var py = List.filled(cells, 0)
var cl = List.filled(cells, 0)
for (i in 0...cells) {
px[i] = r.int(size)
py[i] = r.int(size)
cl[i] = Color.rgb(r.int(256), r.int(256), r.int(256))
}
for (x in 0...size) {
for (y in 0...size) {
var n = 0
for (i in 0...cells) {
if (distSq(px[i], x, py[i], y) < distSq(px[n], x, py[n], y)) n = i
}
Canvas.pset(x, y, cl[n])
}
}
for (i in 0...cells) {
Canvas.circlefill(px[i], py[i], 2, Color.black)
}
}
}</syntaxhighlight>
 
=={{header|XPL0}}==
[[File:VoronoiXPL0.gif|right]]
<syntaxhighlight lang="xpl0">include c:\cxpl\codes; \intrinsic 'code' declarations
 
def N = 15; \number of sites
int SiteX(N), SiteY(N), \coordinates of sites
Dist2, MinDist2, MinI, \distance squared, and minimums
X, Y, I;
[SetVid($13); \set 320x200x8 graphics
for I:= 0 to N-1 do \create a number of randomly placed sites
[SiteX(I):= Ran(160); SiteY(I):= Ran(100)];
for Y:= 0 to 100-1 do \generate Voronoi diagram
for X:= 0 to 160-1 do \for all points...
[MinDist2:= -1>>1; \find closest site
for I:= 0 to N-1 do
[Dist2:= sq(X-SiteX(I)) + sq(Y-SiteY(I));
if Dist2 < MinDist2 then
[MinDist2:= Dist2; MinI:= I];
];
if MinDist2 then Point(X, Y, MinI+1); \leave center black
];
I:= ChIn(1); \wait for keystroke
SetVid($03); \restore normal text screen
]</syntaxhighlight>
 
=={{header|Yabasic}}==
<syntaxhighlight lang="yabasic">
clear screen
 
sites = 200
xEdge = 600
yEdge = 400
 
open window xEdge, yEdge
dim townX(sites), townY(sites), col$(sites)
for i =1 to sites
townX(i) =int(xEdge *ran(1))
townY(i) =int(yEdge *ran(1))
col$(i) = str$(int(256 * ran(1))) + ", " + str$(int(256 * ran(1))) + ", " + str$(int(256 * ran(1)))
color col$(i)
fill circle townX(i), townY(i), 2
next i
dim nearestIndex(xEdge, yEdge)
dim dist(xEdge, yEdge)
 
//fill distance table with distances from the first site
for x = 0 to xEdge - 1
for y = 0 to yEdge - 1
dist(x, y) = (townX(1) - x) ^ 2 + (townY(1) - y) ^ 2
nearestIndex(x, y) = 1
next y
next x
color 0,0,255
//for other towns
for i = 2 to sites
//display some progress
//print at(0,20) "computing: ", (i/sites*100) using "###.#", " %"
//look left
for x = townX(i) to 0 step -1
if not(checkRow(i, x,0, yEdge - 1)) break
next x
//look right
for x = townX(i) + 1 to xEdge - 1
if not(checkRow(i, x, 0, yEdge - 1)) break
next x
next i
for x = 0 to xEdge - 1
for y =0 to yEdge - 1
color col$(nearestIndex(x, y))
startY = y
nearest = nearestIndex(x, y)
for y = y + 1 to yEdge
if nearestIndex(x, y) <> nearest then y = y - 1 : break : end if
next y
line x, startY, x, y + 1
next y
next x
color 0,0,0
for i =1 to sites
fill circle townX( i), townY( i), 2
next i
print peek("millisrunning"), " ms"
 
sub checkRow(site, x, startY, endY)
local dxSquared, y, check
dxSquared = (townX(site) - x) ^ 2
for y = startY to endY
dSquared = (townY(site) - y) ^ 2 + dxSquared
if dSquared <= dist(x, y) then
dist(x, y) = dSquared
nearestIndex(x, y) = site
check = 1
end if
next y
return check
end sub</syntaxhighlight>
 
{{trans|Python}}
<syntaxhighlight lang="yabasic">width = 500 : height = 500
open window width, height
 
export sub hypot(a, b)
return (sqrt(a^2+b^2))
end sub
sub generate_voronoi_diagram(width, height, num_cells)
local nx(num_cells), ny(num_cells), nr(num_cells), ng(num_cells), nb(num_cells)
 
for i = 1 to num_cells
nx(i) = ran(width)
ny(i) = ran(height)
nr(i) = ran(256)
ng(i) = ran(256)
nb(i) = ran(256)
next
for y = 1 to height
for x = 1 to width
dmin = hypot(width-1, height-1)
j = -1
for i = 1 to num_cells
d = hypot(nx(i)-x, ny(i)-y)
if d < dmin dmin = d : j = i
next
color nr(j), ng(j), ng(j)
dot x, y
next
next
 
end sub
generate_voronoi_diagram(width, height, 25)</syntaxhighlight>
 
=={{header|zkl}}==
Uses the PPM class from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#zkl
{{trans|Python}}
[[File:VoronoiDiagram.zkl.jpg|250px|thumb|right]]
<syntaxhighlight lang="zkl">fcn generate_voronoi_diagram(width,height,num_cells){
image,imgx,imgy:=PPM(width,height),width,height;
nx:=num_cells.pump(List,(0).random.fp(imgx));
ny:=num_cells.pump(List,(0).random.fp(imgy));
nr:=num_cells.pump(List,(0).random.fp(256)); // red
ng:=num_cells.pump(List,(0).random.fp(256)); // blue
nb:=num_cells.pump(List,(0).random.fp(256)); // green
 
foreach y,x in (imgy,imgx){
dmin:=(imgx-1).toFloat().hypot(imgy-1);
j:=-1;
foreach i in (num_cells){
d:=(nx[i] - x).toFloat().hypot(ny[i] - y);
if(d<dmin) dmin,j = d,i
}
image[x,y]=(nr[j]*0xff00 + ng[j])*0xff00 + nb[j];
}
image
}</syntaxhighlight>
<syntaxhighlight lang="zkl">generate_voronoi_diagram(500,500,25).write(File("VoronoiDiagram.ppm","wb"));</syntaxhighlight>
 
{{omit from|GUISS}}
{{omit from|Lilypond}}
{{omit from|TPP}}
 
[[Category:Geometry]]
2,063

edits