unit Unit8;
{
This software has been designed and it is
CopyLefted by Han de Bruijn:

                          (===)
                         @-O^O-@
                          #/_\#
                           ###

            VORONOI REGIONS BY BRUTE FORCE
            ==============================
}
INTERFACE

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, Algemeen, Grafisch;

type
  TForm1 = class(TForm)
    Image1: TImage;
    procedure Toetsdruk(Sender: TObject; var Key: Char);
    procedure Scheppen(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

IMPLEMENTATION

{$R *.dfm}

type
  punt = record { sites in the plane }
    x,y : double;
    c : TColor;
  end;
  punten = array of punt; { sites }
var
  nodes : integer; { # of sites }
  rij : punten; { sites in the plane }

procedure Some_Help;
begin
  Writeln;
  Writeln('Voronoi regions pixel based');
  Writeln;
  writeln('Syntax: [program] [nodes]');
  Writeln(' nodes = # random sites');
  Halt;
end;

procedure Read_Parameters;
var
  woord : string;
  OK : boolean;
  k : integer;
begin
  nodes := 10;
  if ParamCount > 1 then Some_Help;
  if ParamCount = 0 then
  begin
    Writeln('Default # nodes = 10');
    Exit;
  end;
  woord := ParamStr(1);
  OK := true;
  for k := 1 to Length(woord) do
    if not (woord[k] in ['0'..'9']) then OK := false;
  if not OK then Some_Help;
  nodes := StrToInt(woord);
end;

function Kleur : TColor;
{
  Generates random color
}
var
  even,k : byte;
  effe : Tcolor;
begin
  effe := 0;
  for k := 1 to 3 do
  begin
    even := Round(255*(Random));
    effe := (effe shl 8) or even;
  end;
  Kleur := $00000000 or effe;
end;

function Voronoi(site : integer; x,y : double) : boolean;
{
  Voronoi region that
  belongs to a (site)
}
var
  N,k : integer;
  x1,x2,y1,y2,xm,ym,f : double;
  OK : boolean;
begin
  N := Length(rij);
  OK := true;
  x1 := rij[site].x; y1 := rij[site].y;
  for k := 0 to N-1 do
  begin
    if k = site then Continue;
    x2 := rij[k].x; y2 := rij[k].y;
  { For all Perpendicular Bisectors }
    xm := (x1+x2)/2; ym := (y1+y2)/2;
    f := (x-xm)*(x2-x1)+(y-ym)*(y2-y1);
    OK := OK and (f < 0);
  end;
  Voronoi := OK;
end;
  
procedure tekenen(N : integer);
{
  Make a Painting
}
var
  i,j,k : integer;
  x,y : double;
  OK : boolean;
begin
{ Create random sites }
  SetLength(rij,N);
  for k := 0 to N-1 do
  begin
    rij[k].x := Random;
    rij[k].y := Random;
    rij[k].c := Kleur;
  end;
{ Loop through all pixels }
  for j := 0 to Hoog-1 do
  begin
    y := j2y(j);
    for i := 0 to Wijd-1 do
    begin
      x := i2x(i);
    { Loop through all sites }
      for k := 0 to N-1 do
      begin
        OK := Voronoi(k,x,y);
      { Each Voronoi region gets different random color }
        if OK then Form1.Image1.Canvas.Pixels[i,j] := rij[k].c;
      end;
    end;
  end;
{ Visualize the sites, at last }
  Form1.Image1.Canvas.Pen.Color := clBlack;
  Form1.Image1.Canvas.Pen.Width := 2;
  for k := 0 to N-1 do
  begin
    i := x2i(rij[k].x);
    j := y2j(rij[k].y);
    Form1.Image1.Canvas.Brush.Color := rij[k].c;
    Form1.Image1.Canvas.Ellipse(i-3,j-3,i+3,j+3);
  end;
end;

procedure TForm1.Toetsdruk(Sender: TObject; var Key: Char);
{
  On KeyPress
}
begin
  ClearDevice;
  Tekenen(nodes);
  Form1.Image1.Picture.SaveToFile('voronoi.bmp');
end;

procedure TForm1.Scheppen(Sender: TObject);
{
  At moment of creation
}
begin
  Read_Parameters;
  xmin := -0.1; xmax := 1.1;
  ymin := -0.1; ymax := 1.1;
  TV(Form1.Image1);
  ClearDevice;
  Tekenen(nodes);
  Form1.Image1.Picture.SaveToFile('voronoi.bmp');
end;

END.