From c187e6817f07151c6a074bbe68a0787c5024f323 Mon Sep 17 00:00:00 2001 From: Erich Eckner Date: Tue, 18 Jan 2022 22:31:22 +0100 Subject: geht erst mal - Farben sind noch Quatsch --- penrose | Bin 0 -> 26443368 bytes penrose.lpi | 6 +- penrose.lpr | 2 +- penrose.lps | 182 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- penroseunit.pas | 161 +++++++++++++++++++++++++++++++++++++++++++++++++ unit1.lfm | 20 ++++++- unit1.pas | 21 ++++++- 7 files changed, 383 insertions(+), 9 deletions(-) create mode 100755 penrose create mode 100644 penroseunit.pas diff --git a/penrose b/penrose new file mode 100755 index 0000000..c4d8278 Binary files /dev/null and b/penrose differ diff --git a/penrose.lpi b/penrose.lpi index f31ac51..94f79d2 100644 --- a/penrose.lpi +++ b/penrose.lpi @@ -30,7 +30,7 @@ - + @@ -42,6 +42,10 @@ + + + + diff --git a/penrose.lpr b/penrose.lpr index f362a29..16a59f9 100644 --- a/penrose.lpr +++ b/penrose.lpr @@ -7,7 +7,7 @@ uses cthreads, {$ENDIF}{$ENDIF} Interfaces, // this includes the LCL widgetset - Forms, Unit1 + Forms, Unit1, penroseunit { you can add units after this }; {$R *.res} diff --git a/penrose.lps b/penrose.lps index 2956bcd..a3e1982 100644 --- a/penrose.lps +++ b/penrose.lps @@ -3,7 +3,7 @@ - + @@ -17,15 +17,191 @@ + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/penroseunit.pas b/penroseunit.pas new file mode 100644 index 0000000..eac0a69 --- /dev/null +++ b/penroseunit.pas @@ -0,0 +1,161 @@ +unit penroseunit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, Graphics, lowlevelunit, matheunit; + +type + tTeil = record + Drachen: boolean; + Ursprung: tExtPoint; + Richtung,Groesze: extended; + id: int64; + end; + + tPenrose = class + private + teile: array of tTeil; + function teilEcken(i: longint): tExtPointArray; + function id2color(id: int64): tColor; + public + constructor create(level: longint); + procedure Zeichnen(breite, hoehe: longint; Canvas: TCanvas); + end; + +implementation + +uses + math; + +constructor tPenrose.create(level: longint); +var + i,j: longint; +begin + setlength(teile,5); + for j:=0 to 4 do begin + teile[j].Drachen:=true; + teile[j].Ursprung:=extPoint(0,0); + teile[j].Richtung:=2*pi/5*j; + teile[j].Groesze:=1; + teile[j].id:=0; + end; + for i:=0 to level-1 do + for j:=length(teile)-1 downto 0 do begin + if teile[j].Richtung<0 then + teile[j].Richtung:=teile[j].Richtung + 2*pi; + if teile[j].Richtung>=2*pi then + teile[j].Richtung:=teile[j].Richtung - 2*pi; + if teile[j].Drachen then begin + setlength(teile,length(teile)+2); + teile[length(teile)-1].Drachen:=false; + teile[length(teile)-1].Ursprung:=teile[j].Ursprung; + teile[length(teile)-1].Richtung:=teile[j].Richtung + 36/180*pi; + teile[length(teile)-1].Groesze:=teile[j].Groesze / 2 / cos(36/180*pi); + teile[length(teile)-1].id:=2*teile[j].id; + teile[length(teile)-2].Drachen:=true; + teile[length(teile)-2].Ursprung:=teile[j].Ursprung + teile[j].Groesze * + extPoint(cos(teile[j].Richtung + 36/180*pi),sin(teile[j].Richtung + 36/180*pi)); + teile[length(teile)-2].Richtung:=teile[j].Richtung - 108/180*pi; + teile[length(teile)-2].Groesze:=teile[j].Groesze / 2 / cos(36/180*pi); + teile[length(teile)-2].id:=2*teile[j].id+1; + teile[j].Ursprung:=teile[j].Ursprung + teile[j].Groesze * + extPoint(cos(teile[j].Richtung - 36/180*pi),sin(teile[j].Richtung - 36/180*pi)); + teile[j].Richtung:=teile[j].Richtung + 108/180*pi; + teile[j].Groesze:=teile[j].Groesze / 2 / cos(36/180*pi); + teile[j].id:=2*teile[j].id+1; + end + else begin + setlength(teile,length(teile)+1); + teile[length(teile)-1].Drachen:=true; + teile[length(teile)-1].Ursprung:=teile[j].Ursprung; + teile[length(teile)-1].Richtung:=teile[j].Richtung; + teile[length(teile)-1].Groesze:=teile[j].Groesze / 2 / cos(36/180*pi); + teile[length(teile)-1].id:=2*teile[j].id+1; + teile[j].Ursprung:=teile[j].Ursprung + teile[j].Groesze * + extPoint(cos(teile[j].Richtung - 36/180*pi),sin(teile[j].Richtung - 36/180*pi)); + teile[j].Richtung:=teile[j].Richtung + 144/180*pi; + teile[j].Groesze:=teile[j].Groesze / 2 / cos(36/180*pi); + teile[j].id:=2*teile[j].id; + end; + end; +end; + +function tPenrose.teilEcken(i: longint): tExtPointArray; +var + j: longint; +begin + setLength(result,4); + result[0]:=extPoint(0,0); + result[1]:=extPoint(cos(36/180*pi),sin(36/180*pi)); + result[2]:=extPoint(cos(36/180*pi) + (2*byte(teile[i].Drachen)-1)*sin(36/180*pi)*tan(18/180*pi),0); + result[3]:=extPoint(cos(-36/180*pi),sin(-36/180*pi)); + for j:=0 to 3 do + result[j]:=teile[i].Groesze * rotationsMatrix(teile[i].Richtung) * result[j] + teile[i].Ursprung; +end; + +function tPenrose.id2color(id: int64): tColor; +const + steps = 256; +var + farben: array[0..6] of tExt3dPoint; + r: tExt3dPoint; +var + i: integer; +begin + for i:=0 to 2 do + farben[2*i]:=ext3dPoint($ff*byte(i=2),$ff*byte(i=1),$ff*byte(i=0)); + for i:=0 to 2 do + farben[7-2*i]:=ext3dPoint($ff,$ff,$ff)-farben[2*i]; + farben[6]:=farben[0]; + id:=id mod (steps*(length(farben)-1)); + i:=id div steps; + r:=(id/steps - i) * farben[i+1] + (1+i-id/steps) * farben[i]; + result:=round(r['x']) + (round(r['y']) shl 8) + (round(r['z']) shl 16) +end; + +procedure tPenrose.Zeichnen(breite, hoehe: longint; Canvas: TCanvas); +var + lo,ru: tExtPoint; + ecken: tExtPointArray; + i,j: longint; + c: char; + Groesze: extended; + Verschiebung: tExtPoint; + points: array of tPoint; +begin + lo:=extPoint(0,0); + ru:=lo; + for i:=0 to length(teile)-1 do begin + ecken:=teilEcken(i); + for j:=0 to length(ecken)-1 do + for c:='x' to 'y' do begin + lo[c]:=min(lo[c],ecken[j][c]); + ru[c]:=max(ru[c],ecken[j][c]); + end; + end; + Groesze:=min( + (breite-1) / (ru['x']-lo['x']), + (hoehe-1) / (ru['y']-lo['y']) + ); + Verschiebung:=-Groesze * lo; + + canvas.brush.Color:=$ffffff; + canvas.rectangle(-10,-10,breite+10,hoehe+10); + for i:=0 to length(teile)-1 do begin + ecken:=teilEcken(i); + setLength(points,length(ecken)); + for j:=0 to length(ecken)-1 do begin + ecken[j]:=Verschiebung + Groesze * ecken[j]; + points[j]:=point(round(ecken[j]['x']),round(ecken[j]['y'])); + end; + canvas.brush.Color:=id2color(teile[i].id); + canvas.pen.Color:=canvas.brush.Color; + canvas.Polygon(points); + end; +end; + +end. + diff --git a/unit1.lfm b/unit1.lfm index bdd5c9b..099a630 100644 --- a/unit1.lfm +++ b/unit1.lfm @@ -1,9 +1,25 @@ object Form1: TForm1 Left = 1690 - Height = 268 + Height = 665 Top = 180 - Width = 357 + Width = 1021 Caption = 'Form1' + ClientHeight = 665 + ClientWidth = 1021 DesignTimePPI = 107 LCLVersion = '2.0.12.0' + object Image1: TImage + Left = 8 + Height = 608 + Top = 40 + Width = 988 + end + object SpinEdit1: TSpinEdit + Left = 8 + Height = 25 + Top = 8 + Width = 256 + OnChange = SpinEdit1Change + TabOrder = 0 + end end diff --git a/unit1.pas b/unit1.pas index ec73033..2a39e11 100644 --- a/unit1.pas +++ b/unit1.pas @@ -5,12 +5,19 @@ unit Unit1; interface uses - Classes, SysUtils, Forms, Controls, Graphics, Dialogs; + Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, Spin, + Penroseunit; type + + { TForm1 } + TForm1 = class(TForm) + Image1: TImage; + SpinEdit1: TSpinEdit; + procedure SpinEdit1Change(Sender: TObject); private - + P: tPenrose; public end; @@ -22,5 +29,15 @@ implementation {$R *.lfm} +{ TForm1 } + +procedure TForm1.SpinEdit1Change(Sender: TObject); +begin + P:=TPenrose.create(SpinEdit1.Value); + P.Zeichnen(Image1.Width,Image1.Height,Image1.Canvas); + P.Free; + form1.caption:=floattostr(cos(90)); +end; + end. -- cgit v1.2.3-54-g00ecf