From 7984e9851a73d571e42ac4d4dfa60dc917a493a7 Mon Sep 17 00:00:00 2001 From: ronaldhordijk Date: Sun, 27 Mar 2005 13:28:52 +0000 Subject: [PATCH] Moved the creation of random flames from mainform and into a seperate unit --- 2.10/Source/ControlPoint.pas | 5 +- 2.10/Source/Global.pas | 10 ++- 2.10/Source/Gradient.pas | 76 ++----------------- 2.10/Source/GradientHlpr.pas | 82 +++++++++++++++++++- 2.10/Source/Main.dfm | 8 +- 2.10/Source/Main.pas | 70 ++++++++--------- 2.10/Source/ScriptForm.pas | 124 ++---------------------------- 2.10/Source/XForm.pas | 141 +++++++++++++++++++++++++++++++++++ 8 files changed, 282 insertions(+), 234 deletions(-) diff --git a/2.10/Source/ControlPoint.pas b/2.10/Source/ControlPoint.pas index c9603c2..29a44e3 100644 --- a/2.10/Source/ControlPoint.pas +++ b/2.10/Source/ControlPoint.pas @@ -988,7 +988,7 @@ begin if ((maxx - minx) > 1000) or ((maxy - miny) > 1000) then - raise Exception.Create('Flame area to large'); + raise EMathError.Create('Flame area to large'); center[0] := (minx + maxx) / 2; center[1] := (miny + maxy) / 2; @@ -1084,7 +1084,7 @@ begin if ((maxx - minx) > 1000) or ((maxy - miny) > 1000) then - raise Exception.Create('Flame area to large'); + raise EMathError.Create('Flame area to large'); cp.center[0] := (minx + maxx) / 2; cp.center[1] := (miny + maxy) / 2; @@ -1536,6 +1536,7 @@ begin end; end; +/////////////////////////////////////////////////////////////////////////////// function TControlPoint.HasNewVariants: boolean; var i: integer; diff --git a/2.10/Source/Global.pas b/2.10/Source/Global.pas index c7ed2ea..cfb74f1 100644 --- a/2.10/Source/Global.pas +++ b/2.10/Source/Global.pas @@ -15,12 +15,14 @@ along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. } -{$D-,L-,O+,Q-,R-,Y-,S-} unit Global; interface -uses SysUtils, Classes, SyncObjs, Controls, Graphics, Math, MyTypes, controlpoint; +uses + SysUtils, Classes, SyncObjs, Controls, Graphics, Math, + cmap, MyTypes, controlpoint; + type EFormatInvalid = class(Exception); @@ -52,6 +54,7 @@ const FT_BMP = 1; FT_PNG = 2; FT_JPG = 3; var + MainSeed: integer; MainTriangles: TTriangles; ConfirmDelete: boolean; // Flag confirmation of entry deletion // FlameTitle: string; @@ -123,6 +126,9 @@ var ShowProgress: Boolean; defLibrary: string; LimitVibrancy: Boolean; + DefaultPalette: TColorMap; + + implementation uses dialogs, Main; diff --git a/2.10/Source/Gradient.pas b/2.10/Source/Gradient.pas index 7b69aa9..3889719 100644 --- a/2.10/Source/Gradient.pas +++ b/2.10/Source/Gradient.pas @@ -125,7 +125,9 @@ procedure HSVToRGB(H, S, V: real; var Rb, Gb, Bb: integer); implementation -uses Main, cmapdata, Math, Browser, Editor, Global, Save, Adjust, Mutate, ClipBrd; +uses + RndFlame, Main, cmapdata, Math, Browser, Editor, Global, + Save, Adjust, Mutate, ClipBrd, GradientHlpr; {$R *.DFM} @@ -754,81 +756,13 @@ end; procedure TGradientForm.mnuSaveasDefaultClick(Sender: TObject); begin - MainForm.DefaultPalette := Palette; + DefaultPalette := Palette; SaveMap(AppPath + 'default.map'); end; -procedure RGBBlend(a, b: integer; var Palette: TColorMap); -{ Linear blend between to indices of a palette } -var - c, v: real; - vrange, range: real; - i: integer; -begin - if a = b then - begin - Exit; - end; - range := b - a; - vrange := Palette[b mod 256][0] - Palette[a mod 256][0]; - c := Palette[a mod 256][0]; - v := vrange / range; - for i := (a + 1) to (b - 1) do - begin - c := c + v; - Palette[i mod 256][0] := Round(c); - end; - vrange := Palette[b mod 256][1] - Palette[a mod 256][1]; - c := Palette[a mod 256][1]; - v := vrange / range; - for i := a + 1 to b - 1 do - begin - c := c + v; - Palette[i mod 256][1] := Round(c); - end; - vrange := Palette[b mod 256][2] - Palette[a mod 256][2]; - c := Palette[a mod 256][2]; - v := vrange / range; - for i := a + 1 to b - 1 do - begin - c := c + v; - Palette[i mod 256][2] := Round(c); - end; -end; - function TGradientForm.RandomGradient: TColorMap; -var - a, b, n, nodes: integer; - rgb: array[0..2] of double; - hsv: array[0..2] of double; - pal: TColorMap; begin - inc(MainForm.Seed); - RandSeed := MainForm.seed; - nodes := random((MaxNodes - 1) - (MinNodes - 2)) + (MinNodes - 1); - n := 256 div nodes; - b := 0; - hsv[0] := (random(MaxHue - (MinHue - 1)) + MinHue) / 100; - hsv[1] := (random(MaxSat - (MinSat - 1)) + MinSat) / 100; - hsv[2] := (random(MaxLum - (MinLum - 1)) + MinLum) / 100; - hsv2rgb(hsv, rgb); - Pal[0][0] := Round(rgb[0] * 255); - Pal[0][1] := Round(rgb[1] * 255); - Pal[0][2] := Round(rgb[2] * 255); - repeat - a := b; - b := b + n; - hsv[0] := (random(MaxHue - (MinHue - 1)) + MinHue) / 100; - hsv[1] := (random(MaxSat - (MinSat - 1)) + MinSat) / 100; - hsv[2] := (random(MaxLum - (MinLum - 1)) + MinLum) / 100; - hsv2rgb(hsv, rgb); - if b > 255 then b := 255; - Pal[b][0] := Round(rgb[0] * 255); - Pal[b][1] := Round(rgb[1] * 255); - Pal[b][2] := Round(rgb[2] * 255); - RGBBlend(a, b, pal); - until b = 255; - Result := Pal; + Result := GradientHelper.RandomGradient; end; procedure TGradientForm.mnuRandomizeClick(Sender: TObject); diff --git a/2.10/Source/GradientHlpr.pas b/2.10/Source/GradientHlpr.pas index 87cffa9..09dd3e4 100644 --- a/2.10/Source/GradientHlpr.pas +++ b/2.10/Source/GradientHlpr.pas @@ -3,7 +3,7 @@ unit GradientHlpr; interface uses - windows, Graphics; + windows, Graphics, Cmap; const PixelCountMax = 32768; @@ -15,8 +15,10 @@ type type TGradientHelper = class private + procedure RGBBlend(a, b: integer; var Palette: TColorMap); public function GetGradientBitmap(Index: integer; const hue_rotation: double): TBitmap; + function RandomGradient: TColorMap; end; var @@ -25,7 +27,7 @@ var implementation uses - Cmap; + Global; { TGradientHelper } @@ -55,6 +57,82 @@ begin Result := BitMap; end; +/////////////////////////////////////////////////////////////////////////////// +function TGradientHelper.RandomGradient: TColorMap; +var + a, b, n, nodes: integer; + rgb: array[0..2] of double; + hsv: array[0..2] of double; + pal: TColorMap; +begin + inc(MainSeed); + RandSeed := Mainseed; + nodes := random((MaxNodes - 1) - (MinNodes - 2)) + (MinNodes - 1); + n := 256 div nodes; + b := 0; + hsv[0] := (random(MaxHue - (MinHue - 1)) + MinHue) / 100; + hsv[1] := (random(MaxSat - (MinSat - 1)) + MinSat) / 100; + hsv[2] := (random(MaxLum - (MinLum - 1)) + MinLum) / 100; + hsv2rgb(hsv, rgb); + Pal[0][0] := Round(rgb[0] * 255); + Pal[0][1] := Round(rgb[1] * 255); + Pal[0][2] := Round(rgb[2] * 255); + repeat + a := b; + b := b + n; + hsv[0] := (random(MaxHue - (MinHue - 1)) + MinHue) / 100; + hsv[1] := (random(MaxSat - (MinSat - 1)) + MinSat) / 100; + hsv[2] := (random(MaxLum - (MinLum - 1)) + MinLum) / 100; + hsv2rgb(hsv, rgb); + if b > 255 then b := 255; + Pal[b][0] := Round(rgb[0] * 255); + Pal[b][1] := Round(rgb[1] * 255); + Pal[b][2] := Round(rgb[2] * 255); + RGBBlend(a, b, pal); + until b = 255; + Result := Pal; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TGradientHelper.RGBBlend(a, b: integer; var Palette: TColorMap); +{ Linear blend between to indices of a palette } +var + c, v: real; + vrange, range: real; + i: integer; +begin + if a = b then + begin + Exit; + end; + range := b - a; + vrange := Palette[b mod 256][0] - Palette[a mod 256][0]; + c := Palette[a mod 256][0]; + v := vrange / range; + for i := (a + 1) to (b - 1) do + begin + c := c + v; + Palette[i mod 256][0] := Round(c); + end; + vrange := Palette[b mod 256][1] - Palette[a mod 256][1]; + c := Palette[a mod 256][1]; + v := vrange / range; + for i := a + 1 to b - 1 do + begin + c := c + v; + Palette[i mod 256][1] := Round(c); + end; + vrange := Palette[b mod 256][2] - Palette[a mod 256][2]; + c := Palette[a mod 256][2]; + v := vrange / range; + for i := a + 1 to b - 1 do + begin + c := c + v; + Palette[i mod 256][2] := Round(c); + end; +end; + +/////////////////////////////////////////////////////////////////////////////// initialization GradientHelper := TGradientHelper.create; finalization diff --git a/2.10/Source/Main.dfm b/2.10/Source/Main.dfm index bd55756..23d6dc4 100644 --- a/2.10/Source/Main.dfm +++ b/2.10/Source/Main.dfm @@ -27,7 +27,7 @@ object MainForm: TMainForm Left = 160 Top = 28 Width = 4 - Height = 434 + Height = 454 end object ToolBar: TToolBar Left = 0 @@ -251,7 +251,7 @@ object MainForm: TMainForm Left = 0 Top = 28 Width = 160 - Height = 434 + Height = 454 Align = alLeft Columns = < item @@ -270,7 +270,7 @@ object MainForm: TMainForm Left = 164 Top = 28 Width = 402 - Height = 434 + Height = 454 Align = alClient BevelInner = bvLowered BevelOuter = bvNone @@ -293,7 +293,7 @@ object MainForm: TMainForm end object StatusBar: TStatusBar Left = 0 - Top = 462 + Top = 482 Width = 566 Height = 19 Panels = < diff --git a/2.10/Source/Main.pas b/2.10/Source/Main.pas index 33a6ca4..a49d384 100644 --- a/2.10/Source/Main.pas +++ b/2.10/Source/Main.pas @@ -353,7 +353,6 @@ type procedure DrawZoomWindow(ARect: TRect); procedure DrawRotatelines(Angle: double); - procedure FavoriteClick(Sender: TObject); procedure HandleThreadCompletion(var Message: TMessage); message WM_THREAD_COMPLETE; @@ -361,14 +360,12 @@ type message WM_THREAD_TERMINATE; public { Public declarations } - Seed: Integer; UndoIndex, UndoMax: integer; Center: array[0..1] of double; MainZoom: double; StartTime: TDateTime; Remainder: TDateTime; AnimPal: TColorMap; - DefaultPalette: TColorMap; procedure LoadXMLFlame(filename, name: string); procedure DisableFavorites; procedure EnableFavorites; @@ -428,7 +425,7 @@ implementation uses Editor, Options, Regstry, Gradient, Render, FullScreen, FormRender, Mutate, Adjust, Browser, Save, About, CmapData, HtmlHlp, ScriptForm, FormFavorites, Size, FormExport, msMultiPartFormData, - Sheep, ImageColoring; + Sheep, ImageColoring, RndFlame; {$R *.DFM} @@ -663,8 +660,8 @@ procedure RandomVariation(cp: TControlPoint); var a, b, i, j: integer; begin - inc(MainForm.seed); - RandSeed := MainForm.seed; + inc(MainSeed); + RandSeed := MainSeed; for i := 0 to NumXForms(cp) - 1 do begin for j := 0 to NVARS - 1 do @@ -713,6 +710,9 @@ var r, s, theta, phi: double; skip: boolean; begin + cp1.Free; + cp1 := RandomFlame(MainCP, alg); +(* Min := randMinTransforms; Max := randMaxTransforms; case randGradient of @@ -726,18 +726,18 @@ begin 2: cmap := MainCp.cmap; 3: cmap := GradientForm.RandomGradient; end; - inc(Seed); - RandSeed := Seed; + inc(MainSeed); + RandSeed := MainSeed; transforms := random(Max - (Min - 1)) + Min; repeat try - inc(Seed); - RandSeed := Seed; + inc(MainSeed); + RandSeed := MainSeed; cp1.clear; cp1.RandomCP(transforms, transforms, false); cp1.SetVariation(Variation); - inc(Seed); - RandSeed := Seed; + inc(MainSeed); + RandSeed := MainSeed; case alg of 1: rnd := 0; @@ -861,6 +861,7 @@ begin cp1.zoom := 0; cp1.Nick := SheepNick; cp1.URl := SheepURL; +*) end; function TMainForm.GradientFromPalette(const pal: TColorMap; const title: string): string; @@ -1984,8 +1985,8 @@ var b, RandFile: string; begin b := IntToStr(BatchSize); - inc(seed); - RandSeed := Seed; + inc(MainSeed); + RandSeed := MainSeed; try AssignFile(F, AppPath + 'apophysis.rand'); OpenFile := AppPath + 'apophysis.rand'; @@ -1995,10 +1996,10 @@ begin begin inc(RandomIndex); Statusbar.SimpleText := 'Generating ' + IntToStr(i + 1) + ' of ' + b; - RandSeed := Seed; + RandSeed := MainSeed; if randGradient = 0 then cmap_index := random(NRCMAPS); - inc(Seed); - RandSeed := Seed; + inc(MainSeed); + RandSeed := MainSeed; RandomizeCP(MainCp); MainCp.CalcBoundbox; @@ -2181,8 +2182,8 @@ procedure TMainForm.mnuRWeightsClick(Sender: TObject); begin StopThread; UpdateUndo; - inc(seed); - RandSeed := Seed; + inc(MainSeed); + RandSeed := MainSeed; RandomWeights(MainCp); RedrawTimer.Enabled := True; UpdateWindows; @@ -2191,8 +2192,8 @@ end; procedure TMainForm.mnuRandomBatchClick(Sender: TObject); begin ScriptEditor.Stopped := True; - inc(seed); - RandSeed := Seed; + inc(MainSeed); + RandSeed := MainSeed; RandomBatch; OpenFile := AppPath + 'apophysis.rand'; OpenFileType := ftXML; @@ -2305,7 +2306,7 @@ procedure TMainForm.mnuRandomClick(Sender: TObject); begin StopThread; UpdateUndo; - inc(seed); + inc(MainSeed); RandomizeCP(MainCp); inc(RandomIndex); MainCp.name := RandomPrefix + RandomDate + '-' + @@ -2495,7 +2496,7 @@ begin GetScripts; Compatibility := 1; // for Drave's compatibility Randomize; - Seed := Random(1234567890); + MainSeed := Random(1234567890); maincp := TControlPoint.Create; ParseCp := TControlPoint.create; OpenFileType := ftXML; @@ -2542,8 +2543,8 @@ begin UndoIndex := 0; UndoMax := 0; ListView.RowSelect := True; - inc(seed); - RandSeed := Seed; + inc(MainSeed); + RandSeed := MainSeed; Variation := vRandom; Maincp.brightness := defBrightness; maincp.gamma := defGamma; @@ -2551,8 +2552,8 @@ begin maincp.sample_density := defSampleDensity; maincp.spatial_oversample := defOversample; maincp.spatial_filter_radius := defFilterRadius; - inc(seed); - RandSeed := Seed; + inc(MainSeed); + RandSeed := MainSeed; if FileExists(AppPath + 'default.map') then begin DefaultPalette := GradientBrowser.LoadFractintMap(AppPath + 'default.map'); @@ -2564,7 +2565,8 @@ begin GetCMap(cmap_index, 1, maincp.cmap); DefaultPalette := maincp.cmap; end; - if FileExists(AppPath + 'apophysis.rand') then DeleteFile(AppPath + 'apophysis.rand'); + if FileExists(AppPath + 'apophysis.rand') then + DeleteFile(AppPath + 'apophysis.rand'); if (defFlameFile = '') or (not FileExists(defFlameFile)) then begin MainCp.Width := image.width; @@ -3087,8 +3089,8 @@ begin mnuVRandom.Checked := True; StopThread; UpdateUndo; - inc(seed); - RandSeed := Seed; + inc(MainSeed); + RandSeed := MainSeed; repeat Variation := vRandom; SetVariation(maincp); @@ -3161,8 +3163,8 @@ begin strings := TStringList.Create; try begin - inc(seed); - RandSeed := Seed; + inc(MainSeed); + RandSeed := MainSeed; OpenDialog.Filter := 'All (*.bmp;*.jpg;*.jpeg)|*.bmp;*.jpg;*.jpeg|JPEG images (*.jpg;*.jpeg)|*.jpg;*.jpeg|BMP images (*.bmp)|*.bmp'; OpenDialog.InitialDir := ImageFolder; OpenDialog.Title := 'Select Image File'; @@ -3518,8 +3520,8 @@ procedure TMainForm.mnuRandomizeColorValuesClick(Sender: TObject); var i: integer; begin - inc(seed); - RandSeed := seed; + inc(MainSeed); + RandSeed := MainSeed; StopThread; UpdateUndo; for i := 0 to Transforms - 1 do diff --git a/2.10/Source/ScriptForm.pas b/2.10/Source/ScriptForm.pas index 4977d6d..7ff5f98 100644 --- a/2.10/Source/ScriptForm.pas +++ b/2.10/Source/ScriptForm.pas @@ -308,10 +308,6 @@ var FileList: TStringList; function Mul33(M1, M2: TMatrix): TMatrix; -procedure Rotate(xform: TXForm; const degrees: double); -procedure Scale(xform: TXForm; const s: double); -procedure translate(xform: TXForm; const x, y: double); -procedure multiply(var xform: TXform; const a, b, c, d: double); procedure Normalize(var cp: TControlPoint); implementation @@ -1291,7 +1287,7 @@ begin try if (ActiveTransform < 0) or (ActiveTransform > NXFORMS - 1) then raise EFormatInvalid.Create('Transform out of range.'); with AMachine do - Rotate(ScriptEditor.cp.xform[ActiveTransform], GetInputArgAsFloat(0)); + ScriptEditor.cp.xform[ActiveTransform].Rotate(GetInputArgAsFloat(0)); except on E: EFormatInvalid do begin ScriptEditor.Console.Lines.Add('Rotate: ' + E.message); @@ -1306,10 +1302,10 @@ begin try if (ActiveTransform < 0) or (ActiveTransform > NXFORMS - 1) then raise EFormatInvalid.Create('Transform out of range.'); with AMachine do - Multiply(ScriptEditor.cp.xform[ActiveTransform], GetInputArgAsFloat(0), GetInputArgAsFloat(1), GetInputArgAsFloat(2), GetInputArgAsFloat(3)); + ScriptEditor.cp.xform[ActiveTransform].Multiply(GetInputArgAsFloat(0), GetInputArgAsFloat(1), GetInputArgAsFloat(2), GetInputArgAsFloat(3)); except on E: EFormatInvalid do begin - ScriptEditor.Console.Lines.Add('Rotate: ' + E.message); + ScriptEditor.Console.Lines.Add('Multiply: ' + E.message); Application.ProcessMessages; LastError := E.Message; end; @@ -1624,7 +1620,7 @@ begin try if (ActiveTransform < 0) or (ActiveTransform > NXFORMS - 1) then raise EFormatInvalid.Create('Transform out of range.'); with AMachine do - Scale(ScriptEditor.cp.xform[ActiveTransform], GetInputArgAsFloat(0)); + ScriptEditor.cp.xform[ActiveTransform].Scale(GetInputArgAsFloat(0)); except on E: EFormatInvalid do begin ScriptEditor.Console.Lines.Add('Scale: ' + E.message); @@ -1881,7 +1877,7 @@ begin try if (ActiveTransform < 0) or (ActiveTransform > NXFORMS - 1) then raise EFormatInvalid.Create('Transform out of range.'); with AMachine do - Translate(ScriptEditor.cp.xform[ActiveTransform], GetInputArgAsFloat(0), GetInputArgAsFloat(1)); + ScriptEditor.cp.xform[ActiveTransform].Translate(GetInputArgAsFloat(0), GetInputArgAsFloat(1)); except on E: EFormatInvalid do begin Application.ProcessMessages; @@ -2948,116 +2944,6 @@ end; { ******************************* functions ********************************** } -procedure Rotate(xform: TXForm; const degrees: double); -var - r: double; - Matrix, M1: TMatrix; -begin - r := degrees * pi / 180; - M1 := Identity; - M1[0, 0] := cos(r); - M1[0, 1] := -sin(r); - M1[1, 0] := sin(r); - M1[1, 1] := cos(r); - Matrix := Identity; - with xform do - begin - Matrix[0][0] := c[0, 0]; - Matrix[0][1] := c[0, 1]; - Matrix[1][0] := c[1, 0]; - Matrix[1][1] := c[1, 1]; - Matrix[0][2] := c[2, 0]; - Matrix[1][2] := c[2, 1]; - Matrix := Mul33(Matrix, M1); - c[0, 0] := Matrix[0][0]; - c[0, 1] := Matrix[0][1]; - c[1, 0] := Matrix[1][0]; - c[1, 1] := Matrix[1][1]; - c[2, 0] := Matrix[0][2]; - c[2, 1] := Matrix[1][2]; - end; - -end; - -procedure Scale(xform: TXform; const s: double); -var - Matrix, M1: TMatrix; -begin - M1 := Identity; - M1[0, 0] := s; - M1[1, 1] := s; - Matrix := Identity; - with xform do - begin - Matrix[0][0] := c[0, 0]; - Matrix[0][1] := c[0, 1]; - Matrix[1][0] := c[1, 0]; - Matrix[1][1] := c[1, 1]; - Matrix[0][2] := c[2, 0]; - Matrix[1][2] := c[2, 1]; - Matrix := Mul33(Matrix, M1); - c[0, 0] := Matrix[0][0]; - c[0, 1] := Matrix[0][1]; - c[1, 0] := Matrix[1][0]; - c[1, 1] := Matrix[1][1]; - c[2, 0] := Matrix[0][2]; - c[2, 1] := Matrix[1][2]; - end; - -end; - -procedure translate(xform: TXForm; const x, y: double); -var - Matrix, M1: TMatrix; -begin - M1 := Identity; - M1[0, 2] := x; - M1[1, 2] := y; - Matrix := Identity; - with xform do - begin - Matrix[0][0] := c[0, 0]; - Matrix[0][1] := c[0, 1]; - Matrix[1][0] := c[1, 0]; - Matrix[1][1] := c[1, 1]; - Matrix[0][2] := c[2, 0]; - Matrix[1][2] := c[2, 1]; - Matrix := Mul33(Matrix, M1); - c[0, 0] := Matrix[0][0]; - c[0, 1] := Matrix[0][1]; - c[1, 0] := Matrix[1][0]; - c[1, 1] := Matrix[1][1]; - c[2, 0] := Matrix[0][2]; - c[2, 1] := Matrix[1][2]; - end; -end; - -procedure multiply(var xform: TXform; const a, b, c, d: double); -var - Matrix, M1: TMatrix; -begin - M1 := Identity; - M1[0, 0] := a; - M1[0, 1] := b; - M1[1, 0] := c; - M1[1, 1] := d; -// M1[0, 2] := e; -// M1[1, 2] := f; - Matrix := Identity; - Matrix[0][0] := xform.c[0, 0]; - Matrix[0][1] := xform.c[0, 1]; - Matrix[1][0] := xform.c[1, 0]; - Matrix[1][1] := xform.c[1, 1]; - Matrix[0][2] := xform.c[2, 0]; - Matrix[1][2] := xform.c[2, 1]; - Matrix := Mul33(Matrix, M1); - xform.c[0, 0] := Matrix[0][0]; - xform.c[0, 1] := Matrix[0][1]; - xform.c[1, 0] := Matrix[1][0]; - xform.c[1, 1] := Matrix[1][1]; - xform.c[2, 0] := Matrix[0][2]; - xform.c[2, 1] := Matrix[1][2]; -end; { ******************************* Parseing *********************************** } diff --git a/2.10/Source/XForm.pas b/2.10/Source/XForm.pas index 75cae30..5b86236 100644 --- a/2.10/Source/XForm.pas +++ b/2.10/Source/XForm.pas @@ -20,6 +20,8 @@ type end; PXYpoint = ^TXYpoint; + TMatrix = array[0..2, 0..2] of double; + type TXForm = class private @@ -61,6 +63,9 @@ type procedure Fan; // var[22] + function Mul33(const M1, M2: TMatrix): TMatrix; + function Identity: TMatrix; + public vars: array[0..NVARS - 1] of double; // normalized interp coefs between variations c: array[0..2, 0..1] of double; // the coefs to the affine part of the function @@ -83,6 +88,10 @@ type procedure NextPointXY(var px, py: double); procedure NextPoint2C(var px, py, pc1, pc2: double); + procedure Rotate(const degrees: double); + procedure Translate(const x, y: double); + procedure Multiply(const a, b, c, d: double); + procedure Scale(const s: double); end; implementation @@ -752,4 +761,136 @@ begin py := FPy; end; +/////////////////////////////////////////////////////////////////////////////// +function TXForm.Mul33(const M1, M2: TMatrix): TMatrix; +begin + result[0, 0] := M1[0][0] * M2[0][0] + M1[0][1] * M2[1][0] + M1[0][2] * M2[2][0]; + result[0, 1] := M1[0][0] * M2[0][1] + M1[0][1] * M2[1][1] + M1[0][2] * M2[2][1]; + result[0, 2] := M1[0][0] * M2[0][2] + M1[0][1] * M2[1][2] + M1[0][2] * M2[2][2]; + result[1, 0] := M1[1][0] * M2[0][0] + M1[1][1] * M2[1][0] + M1[1][2] * M2[2][0]; + result[1, 1] := M1[1][0] * M2[0][1] + M1[1][1] * M2[1][1] + M1[1][2] * M2[2][1]; + result[1, 2] := M1[1][0] * M2[0][2] + M1[1][1] * M2[1][2] + M1[1][2] * M2[2][2]; + result[2, 0] := M1[2][0] * M2[0][0] + M1[2][1] * M2[1][0] + M1[2][2] * M2[2][0]; + result[2, 0] := M1[2][0] * M2[0][1] + M1[2][1] * M2[1][1] + M1[2][2] * M2[2][1]; + result[2, 0] := M1[2][0] * M2[0][2] + M1[2][1] * M2[1][2] + M1[2][2] * M2[2][2]; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TXForm.Identity: TMatrix; +var + i, j: integer; +begin + for i := 0 to 2 do + for j := 0 to 2 do + Result[i, j] := 0; + Result[0][0] := 1; + Result[1][1] := 1; + Result[2][2] := 1; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Rotate(const degrees: double); +var + r: double; + Matrix, M1: TMatrix; +begin + r := degrees * pi / 180; + M1 := Identity; + M1[0, 0] := cos(r); + M1[0, 1] := -sin(r); + M1[1, 0] := sin(r); + M1[1, 1] := cos(r); + Matrix := Identity; + + Matrix[0][0] := c[0, 0]; + Matrix[0][1] := c[0, 1]; + Matrix[1][0] := c[1, 0]; + Matrix[1][1] := c[1, 1]; + Matrix[0][2] := c[2, 0]; + Matrix[1][2] := c[2, 1]; + Matrix := Mul33(Matrix, M1); + c[0, 0] := Matrix[0][0]; + c[0, 1] := Matrix[0][1]; + c[1, 0] := Matrix[1][0]; + c[1, 1] := Matrix[1][1]; + c[2, 0] := Matrix[0][2]; + c[2, 1] := Matrix[1][2]; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Translate(const x, y: double); +var + Matrix, M1: TMatrix; +begin + M1 := Identity; + M1[0, 2] := x; + M1[1, 2] := y; + Matrix := Identity; + + Matrix[0][0] := c[0, 0]; + Matrix[0][1] := c[0, 1]; + Matrix[1][0] := c[1, 0]; + Matrix[1][1] := c[1, 1]; + Matrix[0][2] := c[2, 0]; + Matrix[1][2] := c[2, 1]; + Matrix := Mul33(Matrix, M1); + c[0, 0] := Matrix[0][0]; + c[0, 1] := Matrix[0][1]; + c[1, 0] := Matrix[1][0]; + c[1, 1] := Matrix[1][1]; + c[2, 0] := Matrix[0][2]; + c[2, 1] := Matrix[1][2]; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Multiply(const a, b, c, d: double); +var + Matrix, M1: TMatrix; +begin + M1 := Identity; + M1[0, 0] := a; + M1[0, 1] := b; + M1[1, 0] := c; + M1[1, 1] := d; + Matrix := Identity; + Matrix[0][0] := Self.c[0, 0]; + Matrix[0][1] := Self.c[0, 1]; + Matrix[1][0] := Self.c[1, 0]; + Matrix[1][1] := Self.c[1, 1]; + Matrix[0][2] := Self.c[2, 0]; + Matrix[1][2] := Self.c[2, 1]; + Matrix := Mul33(Matrix, M1); + Self.c[0, 0] := Matrix[0][0]; + Self.c[0, 1] := Matrix[0][1]; + Self.c[1, 0] := Matrix[1][0]; + Self.c[1, 1] := Matrix[1][1]; + Self.c[2, 0] := Matrix[0][2]; + Self.c[2, 1] := Matrix[1][2]; +end; + +/////////////////////////////////////////////////////////////////////////////// +procedure TXForm.Scale(const s: double); +var + Matrix, M1: TMatrix; +begin + M1 := Identity; + M1[0, 0] := s; + M1[1, 1] := s; + Matrix := Identity; + Matrix[0][0] := c[0, 0]; + Matrix[0][1] := c[0, 1]; + Matrix[1][0] := c[1, 0]; + Matrix[1][1] := c[1, 1]; + Matrix[0][2] := c[2, 0]; + Matrix[1][2] := c[2, 1]; + Matrix := Mul33(Matrix, M1); + c[0, 0] := Matrix[0][0]; + c[0, 1] := Matrix[0][1]; + c[1, 0] := Matrix[1][0]; + c[1, 1] := Matrix[1][1]; + c[2, 0] := Matrix[0][2]; + c[2, 1] := Matrix[1][2]; +end; + +/////////////////////////////////////////////////////////////////////////////// end.