Spiral of Theodorus: Reversed n Rotate n Fills lazarus / 39-Graphics ---------------------------------------------------------------------- Boleeman · 2024-04-02 20:26 Spiral of Theodorus  in next reply Notice how the Spiral of Theodorus begins with a right angled Isosceles Triangle. ---------------------------------------------------------------------- Boleeman · 2024-04-04 08:41 Finally have it working: " Spiral of Theodorus" Noticed a bug for many triangles the big triangles obscure the smaller triangles. Sorry: Had a few minor corrections so I have re-uploaded. Please download again. ---------------------------------------------------------------------- circular · 2024-04-04 10:33 Very inspiring. Here is a version with rounding: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i 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. ---------------------------------------------------------------------- Boleeman · 2024-04-04 10:42 That's so Cool Circular. I thought maybe even PolyBezier for the outside border? Circular, I just tried your ARC solution. Now I see how the outside border is curved. Nice to learn about this technique. Kinda glad I got it working, as I came across a few dead ends in the creation process. Tried converting the CSharp version, by it had transformations in it. Later realised bgrabmp does some tranforms. Anyhow, I started from the basics in Lazarus, got a few triangles working, and then applied arrays to make it dynamic. Actually a Phong fill/shading using BgraBMP would also be nice to see. I saw a C version on Github that is transparent (attached below is screenshot). Don't know how to do that properly yet. That would show the bigger triangles over the smaller triangles. Just thought of a fix: Looping it in reverse so the bigger triangles are drawn first. ---------------------------------------------------------------------- circular · 2024-04-04 17:18 I thought about PolyBezier but in the end it was easier to compute intermediate points rather than to compute the Bezier control points. Sure with BGRABitmap you could do it with gradients, antialiasing and transparency. ---------------------------------------------------------------------- Boleeman · 2024-04-06 04:43 Now Reversed the order of the triangles to prevent the bigger triangles covering the smaller ones. Also added: Rotate Graduated Fills Alternating graduated fills Save to png Back color What I noticed was that even though there were different colors, the files sizes of the pngs files were still amazingly small in size. ---------------------------------------------------------------------- circular · 2024-04-06 05:41 Very colorful!  It reminds me of some seashells ---------------------------------------------------------------------- AlexTP · 2024-04-06 05:49 On Linux gtk2, SpinEdits are all truncated... and controls are not properly aligned by X. ---------------------------------------------------------------------- Roland57 · 2024-04-06 07:47 @Boleeman Thanks for sharing. Here is a BGRABitmap version (a command line tool using the bgrabitmappack4nogui.lpk package). P.-S. By the way, there are gorgious LaTeX examples in this discussion. ---------------------------------------------------------------------- Boleeman · 2024-04-07 03:26 Thanks Roland57 for your transparent  BGRABitmap version. I checked out those LaTeX examples. Love this sort of geometry stuff. It is quite amazing to think it comes from Surds/Square Roots. When I was a student many years ago my teachers never taught me about this sort of stuff. I learnt about it a at Uni, when I got introduced to fractals. AlexTP: Just delete the long Label and create your own. I was in a hurry to get the code done that I forgot to redo the labels. Been working on about 5 different things, with coding logic not always going the right way! I noticed there were 9549 Views. Not sure what is going on. Seems quite high. ---------------------------------------------------------------------- cdbc · 2024-04-07 06:08 Hi We have to click on the thread, to 'Mark as Read'.... Regards Benny ---------------------------------------------------------------------- Roland57 · 2024-04-18 11:24 Quote from: Boleeman on April 07, 2024, 05:26:09 amThanks Roland57 for your transparent  BGRABitmap version. I replaced the method for computing points, with another method that I find easier to understand (using vectors). Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i   LPoint1 := PointF(0.0, 0.0);  LPoint2 := PointF(1.0, 0.0);   for i := 1 to ANumTriangles do  begin    LPoint3 := Add(LPoint2, Normalize(Perpendicular(LPoint2)));    DrawTriangle(LPoint1, LPoint2, LPoint3);    LPoint2 := LPoint3;  end;