Moved the creation of random flames from mainform and into a seperate unit

This commit is contained in:
ronaldhordijk 2005-03-27 13:28:52 +00:00
parent 73b68d554e
commit 7984e9851a
8 changed files with 282 additions and 234 deletions

View File

@ -988,7 +988,7 @@ begin
if ((maxx - minx) > 1000) or if ((maxx - minx) > 1000) or
((maxy - miny) > 1000) then ((maxy - miny) > 1000) then
raise Exception.Create('Flame area to large'); raise EMathError.Create('Flame area to large');
center[0] := (minx + maxx) / 2; center[0] := (minx + maxx) / 2;
center[1] := (miny + maxy) / 2; center[1] := (miny + maxy) / 2;
@ -1084,7 +1084,7 @@ begin
if ((maxx - minx) > 1000) or if ((maxx - minx) > 1000) or
((maxy - miny) > 1000) then ((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[0] := (minx + maxx) / 2;
cp.center[1] := (miny + maxy) / 2; cp.center[1] := (miny + maxy) / 2;
@ -1536,6 +1536,7 @@ begin
end; end;
end; end;
///////////////////////////////////////////////////////////////////////////////
function TControlPoint.HasNewVariants: boolean; function TControlPoint.HasNewVariants: boolean;
var var
i: integer; i: integer;

View File

@ -15,12 +15,14 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
} }
{$D-,L-,O+,Q-,R-,Y-,S-}
unit Global; unit Global;
interface interface
uses SysUtils, Classes, SyncObjs, Controls, Graphics, Math, MyTypes, controlpoint; uses
SysUtils, Classes, SyncObjs, Controls, Graphics, Math,
cmap, MyTypes, controlpoint;
type type
EFormatInvalid = class(Exception); EFormatInvalid = class(Exception);
@ -52,6 +54,7 @@ const
FT_BMP = 1; FT_PNG = 2; FT_JPG = 3; FT_BMP = 1; FT_PNG = 2; FT_JPG = 3;
var var
MainSeed: integer;
MainTriangles: TTriangles; MainTriangles: TTriangles;
ConfirmDelete: boolean; // Flag confirmation of entry deletion ConfirmDelete: boolean; // Flag confirmation of entry deletion
// FlameTitle: string; // FlameTitle: string;
@ -123,6 +126,9 @@ var
ShowProgress: Boolean; ShowProgress: Boolean;
defLibrary: string; defLibrary: string;
LimitVibrancy: Boolean; LimitVibrancy: Boolean;
DefaultPalette: TColorMap;
implementation implementation
uses dialogs, Main; uses dialogs, Main;

View File

@ -125,7 +125,9 @@ procedure HSVToRGB(H, S, V: real; var Rb, Gb, Bb: integer);
implementation 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} {$R *.DFM}
@ -754,81 +756,13 @@ end;
procedure TGradientForm.mnuSaveasDefaultClick(Sender: TObject); procedure TGradientForm.mnuSaveasDefaultClick(Sender: TObject);
begin begin
MainForm.DefaultPalette := Palette; DefaultPalette := Palette;
SaveMap(AppPath + 'default.map'); SaveMap(AppPath + 'default.map');
end; 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; 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 begin
inc(MainForm.Seed); Result := GradientHelper.RandomGradient;
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;
end; end;
procedure TGradientForm.mnuRandomizeClick(Sender: TObject); procedure TGradientForm.mnuRandomizeClick(Sender: TObject);

View File

@ -3,7 +3,7 @@ unit GradientHlpr;
interface interface
uses uses
windows, Graphics; windows, Graphics, Cmap;
const const
PixelCountMax = 32768; PixelCountMax = 32768;
@ -15,8 +15,10 @@ type
type type
TGradientHelper = class TGradientHelper = class
private private
procedure RGBBlend(a, b: integer; var Palette: TColorMap);
public public
function GetGradientBitmap(Index: integer; const hue_rotation: double): TBitmap; function GetGradientBitmap(Index: integer; const hue_rotation: double): TBitmap;
function RandomGradient: TColorMap;
end; end;
var var
@ -25,7 +27,7 @@ var
implementation implementation
uses uses
Cmap; Global;
{ TGradientHelper } { TGradientHelper }
@ -55,6 +57,82 @@ begin
Result := BitMap; Result := BitMap;
end; 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 initialization
GradientHelper := TGradientHelper.create; GradientHelper := TGradientHelper.create;
finalization finalization

View File

@ -27,7 +27,7 @@ object MainForm: TMainForm
Left = 160 Left = 160
Top = 28 Top = 28
Width = 4 Width = 4
Height = 434 Height = 454
end end
object ToolBar: TToolBar object ToolBar: TToolBar
Left = 0 Left = 0
@ -251,7 +251,7 @@ object MainForm: TMainForm
Left = 0 Left = 0
Top = 28 Top = 28
Width = 160 Width = 160
Height = 434 Height = 454
Align = alLeft Align = alLeft
Columns = < Columns = <
item item
@ -270,7 +270,7 @@ object MainForm: TMainForm
Left = 164 Left = 164
Top = 28 Top = 28
Width = 402 Width = 402
Height = 434 Height = 454
Align = alClient Align = alClient
BevelInner = bvLowered BevelInner = bvLowered
BevelOuter = bvNone BevelOuter = bvNone
@ -293,7 +293,7 @@ object MainForm: TMainForm
end end
object StatusBar: TStatusBar object StatusBar: TStatusBar
Left = 0 Left = 0
Top = 462 Top = 482
Width = 566 Width = 566
Height = 19 Height = 19
Panels = < Panels = <

View File

@ -353,7 +353,6 @@ type
procedure DrawZoomWindow(ARect: TRect); procedure DrawZoomWindow(ARect: TRect);
procedure DrawRotatelines(Angle: double); procedure DrawRotatelines(Angle: double);
procedure FavoriteClick(Sender: TObject); procedure FavoriteClick(Sender: TObject);
procedure HandleThreadCompletion(var Message: TMessage); procedure HandleThreadCompletion(var Message: TMessage);
message WM_THREAD_COMPLETE; message WM_THREAD_COMPLETE;
@ -361,14 +360,12 @@ type
message WM_THREAD_TERMINATE; message WM_THREAD_TERMINATE;
public public
{ Public declarations } { Public declarations }
Seed: Integer;
UndoIndex, UndoMax: integer; UndoIndex, UndoMax: integer;
Center: array[0..1] of double; Center: array[0..1] of double;
MainZoom: double; MainZoom: double;
StartTime: TDateTime; StartTime: TDateTime;
Remainder: TDateTime; Remainder: TDateTime;
AnimPal: TColorMap; AnimPal: TColorMap;
DefaultPalette: TColorMap;
procedure LoadXMLFlame(filename, name: string); procedure LoadXMLFlame(filename, name: string);
procedure DisableFavorites; procedure DisableFavorites;
procedure EnableFavorites; procedure EnableFavorites;
@ -428,7 +425,7 @@ implementation
uses Editor, Options, Regstry, Gradient, Render, uses Editor, Options, Regstry, Gradient, Render,
FullScreen, FormRender, Mutate, Adjust, Browser, Save, About, CmapData, FullScreen, FormRender, Mutate, Adjust, Browser, Save, About, CmapData,
HtmlHlp, ScriptForm, FormFavorites, Size, FormExport, msMultiPartFormData, HtmlHlp, ScriptForm, FormFavorites, Size, FormExport, msMultiPartFormData,
Sheep, ImageColoring; Sheep, ImageColoring, RndFlame;
{$R *.DFM} {$R *.DFM}
@ -663,8 +660,8 @@ procedure RandomVariation(cp: TControlPoint);
var var
a, b, i, j: integer; a, b, i, j: integer;
begin begin
inc(MainForm.seed); inc(MainSeed);
RandSeed := MainForm.seed; RandSeed := MainSeed;
for i := 0 to NumXForms(cp) - 1 do for i := 0 to NumXForms(cp) - 1 do
begin begin
for j := 0 to NVARS - 1 do for j := 0 to NVARS - 1 do
@ -713,6 +710,9 @@ var
r, s, theta, phi: double; r, s, theta, phi: double;
skip: boolean; skip: boolean;
begin begin
cp1.Free;
cp1 := RandomFlame(MainCP, alg);
(*
Min := randMinTransforms; Min := randMinTransforms;
Max := randMaxTransforms; Max := randMaxTransforms;
case randGradient of case randGradient of
@ -726,18 +726,18 @@ begin
2: cmap := MainCp.cmap; 2: cmap := MainCp.cmap;
3: cmap := GradientForm.RandomGradient; 3: cmap := GradientForm.RandomGradient;
end; end;
inc(Seed); inc(MainSeed);
RandSeed := Seed; RandSeed := MainSeed;
transforms := random(Max - (Min - 1)) + Min; transforms := random(Max - (Min - 1)) + Min;
repeat repeat
try try
inc(Seed); inc(MainSeed);
RandSeed := Seed; RandSeed := MainSeed;
cp1.clear; cp1.clear;
cp1.RandomCP(transforms, transforms, false); cp1.RandomCP(transforms, transforms, false);
cp1.SetVariation(Variation); cp1.SetVariation(Variation);
inc(Seed); inc(MainSeed);
RandSeed := Seed; RandSeed := MainSeed;
case alg of case alg of
1: rnd := 0; 1: rnd := 0;
@ -861,6 +861,7 @@ begin
cp1.zoom := 0; cp1.zoom := 0;
cp1.Nick := SheepNick; cp1.Nick := SheepNick;
cp1.URl := SheepURL; cp1.URl := SheepURL;
*)
end; end;
function TMainForm.GradientFromPalette(const pal: TColorMap; const title: string): string; function TMainForm.GradientFromPalette(const pal: TColorMap; const title: string): string;
@ -1984,8 +1985,8 @@ var
b, RandFile: string; b, RandFile: string;
begin begin
b := IntToStr(BatchSize); b := IntToStr(BatchSize);
inc(seed); inc(MainSeed);
RandSeed := Seed; RandSeed := MainSeed;
try try
AssignFile(F, AppPath + 'apophysis.rand'); AssignFile(F, AppPath + 'apophysis.rand');
OpenFile := AppPath + 'apophysis.rand'; OpenFile := AppPath + 'apophysis.rand';
@ -1995,10 +1996,10 @@ begin
begin begin
inc(RandomIndex); inc(RandomIndex);
Statusbar.SimpleText := 'Generating ' + IntToStr(i + 1) + ' of ' + b; Statusbar.SimpleText := 'Generating ' + IntToStr(i + 1) + ' of ' + b;
RandSeed := Seed; RandSeed := MainSeed;
if randGradient = 0 then cmap_index := random(NRCMAPS); if randGradient = 0 then cmap_index := random(NRCMAPS);
inc(Seed); inc(MainSeed);
RandSeed := Seed; RandSeed := MainSeed;
RandomizeCP(MainCp); RandomizeCP(MainCp);
MainCp.CalcBoundbox; MainCp.CalcBoundbox;
@ -2181,8 +2182,8 @@ procedure TMainForm.mnuRWeightsClick(Sender: TObject);
begin begin
StopThread; StopThread;
UpdateUndo; UpdateUndo;
inc(seed); inc(MainSeed);
RandSeed := Seed; RandSeed := MainSeed;
RandomWeights(MainCp); RandomWeights(MainCp);
RedrawTimer.Enabled := True; RedrawTimer.Enabled := True;
UpdateWindows; UpdateWindows;
@ -2191,8 +2192,8 @@ end;
procedure TMainForm.mnuRandomBatchClick(Sender: TObject); procedure TMainForm.mnuRandomBatchClick(Sender: TObject);
begin begin
ScriptEditor.Stopped := True; ScriptEditor.Stopped := True;
inc(seed); inc(MainSeed);
RandSeed := Seed; RandSeed := MainSeed;
RandomBatch; RandomBatch;
OpenFile := AppPath + 'apophysis.rand'; OpenFile := AppPath + 'apophysis.rand';
OpenFileType := ftXML; OpenFileType := ftXML;
@ -2305,7 +2306,7 @@ procedure TMainForm.mnuRandomClick(Sender: TObject);
begin begin
StopThread; StopThread;
UpdateUndo; UpdateUndo;
inc(seed); inc(MainSeed);
RandomizeCP(MainCp); RandomizeCP(MainCp);
inc(RandomIndex); inc(RandomIndex);
MainCp.name := RandomPrefix + RandomDate + '-' + MainCp.name := RandomPrefix + RandomDate + '-' +
@ -2495,7 +2496,7 @@ begin
GetScripts; GetScripts;
Compatibility := 1; // for Drave's compatibility Compatibility := 1; // for Drave's compatibility
Randomize; Randomize;
Seed := Random(1234567890); MainSeed := Random(1234567890);
maincp := TControlPoint.Create; maincp := TControlPoint.Create;
ParseCp := TControlPoint.create; ParseCp := TControlPoint.create;
OpenFileType := ftXML; OpenFileType := ftXML;
@ -2542,8 +2543,8 @@ begin
UndoIndex := 0; UndoIndex := 0;
UndoMax := 0; UndoMax := 0;
ListView.RowSelect := True; ListView.RowSelect := True;
inc(seed); inc(MainSeed);
RandSeed := Seed; RandSeed := MainSeed;
Variation := vRandom; Variation := vRandom;
Maincp.brightness := defBrightness; Maincp.brightness := defBrightness;
maincp.gamma := defGamma; maincp.gamma := defGamma;
@ -2551,8 +2552,8 @@ begin
maincp.sample_density := defSampleDensity; maincp.sample_density := defSampleDensity;
maincp.spatial_oversample := defOversample; maincp.spatial_oversample := defOversample;
maincp.spatial_filter_radius := defFilterRadius; maincp.spatial_filter_radius := defFilterRadius;
inc(seed); inc(MainSeed);
RandSeed := Seed; RandSeed := MainSeed;
if FileExists(AppPath + 'default.map') then if FileExists(AppPath + 'default.map') then
begin begin
DefaultPalette := GradientBrowser.LoadFractintMap(AppPath + 'default.map'); DefaultPalette := GradientBrowser.LoadFractintMap(AppPath + 'default.map');
@ -2564,7 +2565,8 @@ begin
GetCMap(cmap_index, 1, maincp.cmap); GetCMap(cmap_index, 1, maincp.cmap);
DefaultPalette := maincp.cmap; DefaultPalette := maincp.cmap;
end; 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 if (defFlameFile = '') or (not FileExists(defFlameFile)) then
begin begin
MainCp.Width := image.width; MainCp.Width := image.width;
@ -3087,8 +3089,8 @@ begin
mnuVRandom.Checked := True; mnuVRandom.Checked := True;
StopThread; StopThread;
UpdateUndo; UpdateUndo;
inc(seed); inc(MainSeed);
RandSeed := Seed; RandSeed := MainSeed;
repeat repeat
Variation := vRandom; Variation := vRandom;
SetVariation(maincp); SetVariation(maincp);
@ -3161,8 +3163,8 @@ begin
strings := TStringList.Create; strings := TStringList.Create;
try try
begin begin
inc(seed); inc(MainSeed);
RandSeed := Seed; RandSeed := MainSeed;
OpenDialog.Filter := 'All (*.bmp;*.jpg;*.jpeg)|*.bmp;*.jpg;*.jpeg|JPEG images (*.jpg;*.jpeg)|*.jpg;*.jpeg|BMP images (*.bmp)|*.bmp'; OpenDialog.Filter := 'All (*.bmp;*.jpg;*.jpeg)|*.bmp;*.jpg;*.jpeg|JPEG images (*.jpg;*.jpeg)|*.jpg;*.jpeg|BMP images (*.bmp)|*.bmp';
OpenDialog.InitialDir := ImageFolder; OpenDialog.InitialDir := ImageFolder;
OpenDialog.Title := 'Select Image File'; OpenDialog.Title := 'Select Image File';
@ -3518,8 +3520,8 @@ procedure TMainForm.mnuRandomizeColorValuesClick(Sender: TObject);
var var
i: integer; i: integer;
begin begin
inc(seed); inc(MainSeed);
RandSeed := seed; RandSeed := MainSeed;
StopThread; StopThread;
UpdateUndo; UpdateUndo;
for i := 0 to Transforms - 1 do for i := 0 to Transforms - 1 do

View File

@ -308,10 +308,6 @@ var
FileList: TStringList; FileList: TStringList;
function Mul33(M1, M2: TMatrix): TMatrix; 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); procedure Normalize(var cp: TControlPoint);
implementation implementation
@ -1291,7 +1287,7 @@ begin
try try
if (ActiveTransform < 0) or (ActiveTransform > NXFORMS - 1) then raise EFormatInvalid.Create('Transform out of range.'); if (ActiveTransform < 0) or (ActiveTransform > NXFORMS - 1) then raise EFormatInvalid.Create('Transform out of range.');
with AMachine do with AMachine do
Rotate(ScriptEditor.cp.xform[ActiveTransform], GetInputArgAsFloat(0)); ScriptEditor.cp.xform[ActiveTransform].Rotate(GetInputArgAsFloat(0));
except on E: EFormatInvalid do except on E: EFormatInvalid do
begin begin
ScriptEditor.Console.Lines.Add('Rotate: ' + E.message); ScriptEditor.Console.Lines.Add('Rotate: ' + E.message);
@ -1306,10 +1302,10 @@ begin
try try
if (ActiveTransform < 0) or (ActiveTransform > NXFORMS - 1) then raise EFormatInvalid.Create('Transform out of range.'); if (ActiveTransform < 0) or (ActiveTransform > NXFORMS - 1) then raise EFormatInvalid.Create('Transform out of range.');
with AMachine do 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 except on E: EFormatInvalid do
begin begin
ScriptEditor.Console.Lines.Add('Rotate: ' + E.message); ScriptEditor.Console.Lines.Add('Multiply: ' + E.message);
Application.ProcessMessages; Application.ProcessMessages;
LastError := E.Message; LastError := E.Message;
end; end;
@ -1624,7 +1620,7 @@ begin
try try
if (ActiveTransform < 0) or (ActiveTransform > NXFORMS - 1) then raise EFormatInvalid.Create('Transform out of range.'); if (ActiveTransform < 0) or (ActiveTransform > NXFORMS - 1) then raise EFormatInvalid.Create('Transform out of range.');
with AMachine do with AMachine do
Scale(ScriptEditor.cp.xform[ActiveTransform], GetInputArgAsFloat(0)); ScriptEditor.cp.xform[ActiveTransform].Scale(GetInputArgAsFloat(0));
except on E: EFormatInvalid do except on E: EFormatInvalid do
begin begin
ScriptEditor.Console.Lines.Add('Scale: ' + E.message); ScriptEditor.Console.Lines.Add('Scale: ' + E.message);
@ -1881,7 +1877,7 @@ begin
try try
if (ActiveTransform < 0) or (ActiveTransform > NXFORMS - 1) then raise EFormatInvalid.Create('Transform out of range.'); if (ActiveTransform < 0) or (ActiveTransform > NXFORMS - 1) then raise EFormatInvalid.Create('Transform out of range.');
with AMachine do 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 except on E: EFormatInvalid do
begin begin
Application.ProcessMessages; Application.ProcessMessages;
@ -2948,116 +2944,6 @@ end;
{ ******************************* functions ********************************** } { ******************************* 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 *********************************** } { ******************************* Parseing *********************************** }

View File

@ -20,6 +20,8 @@ type
end; end;
PXYpoint = ^TXYpoint; PXYpoint = ^TXYpoint;
TMatrix = array[0..2, 0..2] of double;
type type
TXForm = class TXForm = class
private private
@ -61,6 +63,9 @@ type
procedure Fan; // var[22] procedure Fan; // var[22]
function Mul33(const M1, M2: TMatrix): TMatrix;
function Identity: TMatrix;
public public
vars: array[0..NVARS - 1] of double; // normalized interp coefs between variations 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 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 NextPointXY(var px, py: double);
procedure NextPoint2C(var px, py, pc1, pc2: 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; end;
implementation implementation
@ -752,4 +761,136 @@ begin
py := FPy; py := FPy;
end; 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. end.