169 lines
5.0 KiB
ObjectPascal
169 lines
5.0 KiB
ObjectPascal
|
{ Apophysis AV "Phoenix Edition" Copyright (C) 2021 Alice V. Koryagina }
|
||
|
|
||
|
unit Chaos;
|
||
|
|
||
|
interface
|
||
|
|
||
|
uses
|
||
|
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
|
||
|
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.ComCtrls, Editor, Translation,
|
||
|
Vcl.StdCtrls, Math;
|
||
|
|
||
|
type
|
||
|
TChaosForm = class(TForm)
|
||
|
PageControl1: TPageControl;
|
||
|
TabMatrix: TTabSheet;
|
||
|
ChaosMatrix: TStringGrid;
|
||
|
btnClose: TButton;
|
||
|
TabDiagram: TTabSheet;
|
||
|
chkPercents: TCheckBox;
|
||
|
WeightVector: TStringGrid;
|
||
|
procedure ChaosMatrixDrawCell(Sender: TObject; ACol, ARow: Integer;
|
||
|
Rect: TRect; State: TGridDrawState);
|
||
|
procedure FormActivate(Sender: TObject);
|
||
|
procedure FormCreate(Sender: TObject);
|
||
|
procedure btnCloseClick(Sender: TObject);
|
||
|
procedure chkPercentsClick(Sender: TObject);
|
||
|
procedure FormResize(Sender: TObject);
|
||
|
private
|
||
|
{ Private declarations }
|
||
|
public
|
||
|
{ Public declarations }
|
||
|
end;
|
||
|
|
||
|
var
|
||
|
ChaosForm: TChaosForm;
|
||
|
|
||
|
implementation
|
||
|
|
||
|
{$R *.dfm}
|
||
|
|
||
|
|
||
|
procedure TChaosForm.btnCloseClick(Sender: TObject);
|
||
|
begin
|
||
|
Close;
|
||
|
end;
|
||
|
|
||
|
procedure TChaosForm.ChaosMatrixDrawCell(Sender: TObject; ACol, ARow: Integer;
|
||
|
Rect: TRect; State: TGridDrawState);
|
||
|
var
|
||
|
h, ax, ay, bx, by: integer;
|
||
|
val: double;
|
||
|
trgColor : TColor;
|
||
|
newRect: TRect;
|
||
|
begin
|
||
|
if (ARow = 0) and (ACol = 0) then exit;
|
||
|
if not (gdFixed in State) then
|
||
|
begin
|
||
|
trgColor := EditForm.GetTriangleColor(ACol - 1);
|
||
|
with TStringGrid(Sender).Canvas do begin
|
||
|
Brush.Color := trgColor;
|
||
|
FillRect(Rect);
|
||
|
Font.Color := clBlack; //clWindowText;
|
||
|
if Sender = ChaosMatrix then
|
||
|
begin
|
||
|
val := EditForm.cp.xform[ACol - 1].modWeights[ARow - 1];
|
||
|
if not chkPercents.Checked then
|
||
|
TextOut(Rect.Left + 4, Rect.Top + 4, FloatToStr(RoundTo(val, -4)))
|
||
|
else begin
|
||
|
if ChaosMatrix.Cells[ACol, 1] = '0' then
|
||
|
TextOut(Rect.Left + 4, Rect.Top + 4, '0%')
|
||
|
else
|
||
|
TextOut(Rect.Left + 4, Rect.Top + 4, Format('%g%%',
|
||
|
[RoundTo(val / StrToFloat(ChaosMatrix.Cells[ACol, 1]), -4)]));
|
||
|
end;
|
||
|
end else // if Sender = WeightVector then
|
||
|
begin
|
||
|
val := EditForm.cp.xform[ACol - 1].density;
|
||
|
if not chkPercents.Checked then
|
||
|
TextOut(Rect.Left + 4, Rect.Top + 4, FloatToStr(RoundTo(val, -4)))
|
||
|
else // weight sum is always not zero
|
||
|
TextOut(Rect.Left + 4, Rect.Top + 4, Format('%g%%',
|
||
|
[RoundTo(val / StrToFloat(WeightVector.Cells[1,1]), -4)]));
|
||
|
end;
|
||
|
end;
|
||
|
end else
|
||
|
begin
|
||
|
if (ACol = 0) then
|
||
|
trgColor := EditForm.GetTriangleColor(ARow - 1)
|
||
|
else
|
||
|
trgColor := EditForm.GetTriangleColor(ACol - 1);
|
||
|
if (Sender = WeightVector) and (ARow = 1) then exit;
|
||
|
with TStringGrid(Sender).Canvas do begin
|
||
|
h := Rect.Bottom - Rect.Top - 2;
|
||
|
ax := Rect.Right - 3;
|
||
|
ay := Rect.Top + 2;
|
||
|
bx := Rect.Right - h;
|
||
|
by := Rect.Bottom - 3;
|
||
|
|
||
|
pen.Color := clBlack;
|
||
|
Polyline([Point(ax+1, ay-2), Point(ax+1, by+1), Point(bx-2, by+1), Point(ax+1, ay-2)]);
|
||
|
|
||
|
pen.Color := trgColor;
|
||
|
brush.Color := pen.Color shr 1 and $7f7f7f;
|
||
|
Polygon([Point(ax, ay), Point(ax, by), Point(bx, by)]);
|
||
|
end;
|
||
|
end;
|
||
|
end;
|
||
|
|
||
|
procedure TChaosForm.chkPercentsClick(Sender: TObject);
|
||
|
begin
|
||
|
WeightVector.Invalidate;
|
||
|
ChaosMatrix.Invalidate;
|
||
|
end;
|
||
|
|
||
|
procedure TChaosForm.FormActivate(Sender: TObject);
|
||
|
var
|
||
|
i, j, n: integer;
|
||
|
sum: double;
|
||
|
begin
|
||
|
n := EditForm.cp.NumXForms + 1;
|
||
|
sum := 0;
|
||
|
with WeightVector do begin
|
||
|
ColCount := n;
|
||
|
for i := 1 to n do
|
||
|
Cells[i,0] := ' ' + IntToStr(i);
|
||
|
for j := 0 to n-2 do
|
||
|
sum := sum + EditForm.cp.xform[j].density;
|
||
|
Cells[1, 1] := FloatToStr(sum * 0.01);
|
||
|
end;
|
||
|
with ChaosMatrix do begin
|
||
|
ColCount := n;
|
||
|
RowCount := n;
|
||
|
for i := 1 to n do
|
||
|
begin
|
||
|
Cells[0,i] := Format(TextByKey('editor-common-toprefix'), [i]);
|
||
|
Cells[i,0] := Format(TextByKey('editor-common-fromprefix'), [i]);
|
||
|
sum := 0;
|
||
|
for j := 0 to n-2 do
|
||
|
sum := sum + EditForm.cp.xform[i-1].modWeights[j];
|
||
|
Cells[i, 1] := FloatToStr(sum * 0.01);
|
||
|
end;
|
||
|
Height := TabMatrix.Height - Top - 24;
|
||
|
Invalidate;
|
||
|
end;
|
||
|
chkPercents.Top := TabMatrix.Height - 20;
|
||
|
end;
|
||
|
|
||
|
procedure TChaosForm.FormCreate(Sender: TObject);
|
||
|
begin
|
||
|
self.Caption := TextByKey('transitions-title');
|
||
|
TabMatrix.Caption := TextByKey('transitions-matrix');
|
||
|
btnClose.Caption := TextByKey('common-close');
|
||
|
ChaosMatrix.Cells[0,0] := TextByKey('editor-tab-chaos-path');
|
||
|
chkPercents.Caption := TextByKey('transitions-inpercents');
|
||
|
WeightVector.Cells[0,0] := TextByKey('transitions-transform');
|
||
|
WeightVector.Cells[0,1] := TextByKey('editor-common-weight');
|
||
|
// AV: TODO: visualize Markov chain transitions using arrows
|
||
|
// TabDiagram.Caption := TextByKey('transitions-diagram');
|
||
|
end;
|
||
|
|
||
|
procedure TChaosForm.FormResize(Sender: TObject);
|
||
|
begin
|
||
|
ChaosMatrix.Height := TabMatrix.Height - ChaosMatrix.Top - 24;
|
||
|
chkPercents.Top := TabMatrix.Height - 20;
|
||
|
TabMatrix.Invalidate;
|
||
|
end;
|
||
|
|
||
|
end.
|