Using a PaintBox

This demonstration is based on our Lazarus version. See that page for the theory of the recursion involved and for the original reference of the Pascal solution.

The next page demonstrates the display of the Sierpinski carpet (another fractal) in a PaintBox.

Demonstration

If the demo does not work in your current browser, try another such as Chrome. If you see no display at school, the security system might have blocked it. You can try instead this direct link to the program running on its own page.

SierpinskiCurves.html

Smart Pascal Code of Form

unit Form1;

interface

uses 
  SmartCL.System, SmartCL.Graphics, SmartCL.Components, SmartCL.Forms, 
  SmartCL.Fonts, SmartCL.Borders, SmartCL.Application,
  SmartCL.Controls.PaintBox, SmartCL.Controls.EditBox,
  SmartCL.Controls.Label;

type
  TForm1 = class(TW3Form)
    procedure W3EditBox1Click(Sender: TObject);
    procedure W3EditBox1KeyUp(Sender: TObject; aKeyCode: Integer);
  private
    {$I 'Form1:intf'}
    LeftMargin, BottomMargin, GraphicWidth, x, y, h, UserOrder: integer;
  protected
    procedure InitializeObject; override;
    procedure N(i: integer);
    procedure S(i: integer);
    procedure E(i: integer);
    procedure W(i: integer);
    procedure LineN;
    procedure LineS;
    procedure LineE;
    procedure LineW;
    procedure LineNE;
    procedure LineNW;
    procedure LineSE;
    procedure LineSW;
    procedure Sierpinski(i: integer);
  end;

implementation

procedure TForm1.W3EditBox1KeyUp(Sender: TObject; aKeyCode: Integer);
begin
  if not (aKeyCode in [8, 49 .. 53]) then
    showMessage('Digits 1 to 5 only !')
  else
    begin
      UserOrder := StrToInt(W3EditBox1.Text);
      GraphicWidth := trunc(power(2, UserOrder + 2) - 2); // GraphicWidth is number of units
      Sierpinski(UserOrder);
    end;
end;

procedure TForm1.W3EditBox1Click(Sender: TObject);
begin
  UserOrder := StrToInt(W3EditBox1.Text);
  GraphicWidth := trunc(power(2, UserOrder + 2) - 2); // GraphicWidth is number of units
  Sierpinski(UserOrder);
end;

procedure TForm1.InitializeObject;
begin
  inherited;
  {$I 'Form1:impl'}
  W3EditBox1.InputType := itNumber;
  W3EditBox1.setMax(5);
  W3EditBox1.setMin(1);
  W3EditBox1.Font.Size := 16;
  W3EditBox1.Text := '5';
end;
procedure TForm1.LineN;
begin
  y := y - 2 * h;
  pb.Canvas.lineToF(x, y);
end;

procedure TForm1.LineS;
begin
  y := y + 2 * h;
  pb.Canvas.lineToF(x, y);
end;

procedure TForm1.LineE;
begin
  x := x + 2 * h;
  pb.Canvas.lineToF(x, y);
end;

procedure TForm1.LineW;
begin
  x := x - 2 * h;
  pb.Canvas.lineToF(x, y);
end;

procedure TForm1.LineNW;
begin
  x := x - h;
  y := y - h;
  pb.Canvas.lineToF(x, y);
end;

procedure TForm1.LineNE;
begin
  x := x + h;
  y := y - h;
  pb.Canvas.lineToF(x, y);
end;

procedure TForm1.LineSE;
begin
  x := x + h;
  y := y + h;
  pb.Canvas.lineToF(x, y);
end;

procedure TForm1.LineSW;
begin
  x := x - h;
  y := y + h;
  pb.Canvas.lineToF(x, y);
end;

procedure TForm1.N(i: integer);
begin
  if i = 1 then
    begin
      LineNE;
      LineN;
      LineNW;
    end
  else
    begin
      N(i - 1);
      LineNE;
      E(i - 1);
      LineN;
      W(i - 1);
      LineNW;
      N(i - 1);
    end;
end;

procedure TForm1.S(i: integer);
begin
  if i = 1 then
    begin
      LineSW;
      LineS;
      LineSE;
    end
  else
    begin
      S(i - 1);
      LineSW;
      W(i - 1);
      LineS;
      E(i - 1);
      LineSE;
      S(i - 1);
    end;
end;

procedure TForm1.E(i: integer);
begin
  if i = 1 then
    begin
      LineSE;
      LineE;
      LineNE;
    end
  else
    begin
      E(i-1);
      LineSE;
      S(i-1);
      LineE;
      N(i-1);
      LineNE;
      E(i-1);
    end;
end;

procedure TForm1.W(i: integer);
begin
  if i = 1 then
    begin
      LineNW;
      LineW;
      LineSW;
    end
  else
    begin
      W(i - 1);
      LineNW;
      N(i - 1);
      LineW;
      S(i - 1);
      LineSW;
      W(i - 1);
    end;
end;

procedure TForm1.Sierpinski(i: integer);
begin
  pb.Canvas.Clear;
  h := pb.Height DIV GraphicWidth;   // h is size of 1 unit
  LeftMargin := (pb.Width - h * GraphicWidth) DIV 2;
  BottomMargin := (pb.Height - h * GraphicWidth) DIV 2;
  pb.Canvas.StrokeStyle:= 'red';
  x := LeftMargin;
  y := pb.Height - (h + BottomMargin);
  pb.Canvas.BeginPath;
  pb.Canvas.moveToF(x, y);
  N(i);
  LineNE;
  E(i);
  LineSE;
  S(i);
  LineSW;
  W(i);
  LineNW;
  pb.Canvas.Stroke;
end;
 
initialization
  Forms.RegisterForm({$I %FILE%}, TForm1);
end.    

XML Code of Form

<SMART>
  <Form version="2" subversion="2">
    <Created>2017-06-01T09:32:48.293</Created>
    <Modified>2017-06-01T16:51:23.188</Modified>
    <object type="TW3Form">
      <Caption>W3Form</Caption>
      <Name>Form1</Name>
      <object type="TW3PaintBox">
        <Width>400</Width>
        <Top>96</Top>
        <Left>24</Left>
        <Height>300</Height>
        <Color>16513751</Color>
        <Name>pb</Name>
      </object>
      <object type="TW3EditBox">
        <Value></Value>
        <Text>W3EditBox</Text>
        <Range></Range>
        <Width>43</Width>
        <Top>45</Top>
        <Left>376</Left>
        <Height>40</Height>
        <Name>W3EditBox1</Name>
        <OnKeyUp>W3EditBox1KeyUp</OnKeyUp>
        <OnClick>W3EditBox1Click</OnClick>
      </object>
      <object type="TW3Label">
        <Caption>Click in edit box and set order from 1 to 5:</Caption>
        <Width>320</Width>
        <Top>48</Top>
        <Left>32</Left>
        <Height>32</Height>
        <Name>W3Label1</Name>
      </object>
      <object type="TW3Label">
        <Caption>Sierpinski Curves</Caption>
        <Zoom>1.2</Zoom>
        <Width>168</Width>
        <Top>9</Top>
        <Left>136</Left>
        <Height>40</Height>
        <Name>W3Label2</Name>
      </object>
    </object>
  </Form>
</SMART>

Programming - a skill for life!

How to use a range of visual components such as edit boxes, combo boxes, grids and charts on one or multiple forms (including a modal form)