{ 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.