unit Unit1;

{$mode objfpc}{$H+}

interface

uses

Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, Spin,

StdCtrls, Math, LCLIntf;

const ArcPrecision = 5;

type

{ TForm1 }

TForm1 = class(TForm)

chkFill: TCheckBox;

Label1: TLabel;

sbPencolor: TColorButton;

PaintBox1: TPaintBox;

Panel1: TPanel;

seNumTriangs: TSpinEdit;

seMybasesize: TSpinEdit;

sePenwidth: TSpinEdit;

procedure chkFillChange(Sender: TObject);

procedure PaintBox1Paint(Sender: TObject);

procedure sbPencolorColorChanged(Sender: TObject);

procedure seMybasesizeChange(Sender: TObject);

procedure seNumTriangsChange(Sender: TObject);

procedure sePenwidthChange(Sender: TObject);

private

rotpoint: TPoint;

endpt: array of TPoint;

public

end;

var

Form1: TForm1;

implementation

{$R *.lfm}

{ TForm1 }

procedure TForm1.PaintBox1Paint(Sender: TObject);

var

NumTriangles: Integer;

i, j, basesize: Integer;

Angle, PreviousAngle, IntermediateAngle,

Hypo, PreviousHypo, IntermediateHypo: Double;

RandomColor: TColor;

Points: array of TPoint;

begin

rotpoint := Point(350, 350);

NumTriangles := seNumTriangs.Value;

basesize := seMybasesize.Value;

Angle := 0; // Reset angle

Hypo := Sqrt((basesize**2) + (basesize**2));

SetLength(endpt, NumTriangles*ArcPrecision + 1);

endpt[0] := Point(round(rotpoint.x + Hypo), rotpoint.y);

for i := 1 to NumTriangles do

begin

PreviousAngle := Angle;

PreviousHypo := Hypo;

// next angle

Angle := Angle + ArcTan(1/Sqrt(i));

Hypo := Sqrt((PreviousHypo**2) + (basesize**2));

for j := 1 to ArcPrecision do

begin

IntermediateAngle := (Angle*j + PreviousAngle*(ArcPrecision-j))/ArcPrecision;

IntermediateHypo := (Hypo*j + PreviousHypo*(ArcPrecision-j))/ArcPrecision;

endpt[(i-1)*ArcPrecision + j] := Point(

Round(rotpoint.x + IntermediateHypo * Cos(IntermediateAngle)),

Round(rotpoint.y - IntermediateHypo * Sin(IntermediateAngle))

);

end;

end;

paintbox1.Canvas.Pen.Width := sePenwidth.Value;

paintbox1.Canvas.Brush.Style := bsSolid;

for i := 0 to NumTriangles - 1 do

begin

with PaintBox1.Canvas do

begin

if chkFill.Checked then

begin

// Generate random RGB color components

repeat

RandomColor := TColor(RGB(Random(256), Random(256), Random(256)));

until (Red(RandomColor) > 120) or (Green(RandomColor) > 120) or (Blue(RandomColor) > 120);

Brush.Color := RandomColor;

Brush.Style := bsSolid;

end else

Brush.Style := bsClear;

setlength(points, ArcPrecision + 2);

points[0] := rotpoint;

move(endpt[i*ArcPrecision], points[1], sizeof(TPoint)*(ArcPrecision+1));

Polygon(points);

end;

end;

end;

procedure TForm1.chkFillChange(Sender: TObject);

begin

Paintbox1.Invalidate;

end;

procedure TForm1.sbPencolorColorChanged(Sender: TObject);

begin

Paintbox1.Invalidate;

end;

procedure TForm1.seMybasesizeChange(Sender: TObject);

begin

Paintbox1.Invalidate;

end;

procedure TForm1.seNumTriangsChange(Sender: TObject);

begin

Paintbox1.Invalidate;

end;

procedure TForm1.sePenwidthChange(Sender: TObject);

begin

Paintbox1.Invalidate;

end;

end.