Forum > Graphics

Spiral of Theodorus: Reversed n Rotate n Fills

(1/3) > >>

Spiral of Theodorus  in next reply

Notice how the Spiral of Theodorus begins with a right angled Isosceles Triangle.

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.

Very inspiring.

Here is a version with rounding:

--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---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.

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.

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.


[0] Message Index

[#] Next page

Go to full version