7
LCLType, SysUtils, Variants, Classes, Graphics, Controls, Forms,
8
Dialogs, GLHUDObjects, GLObjects, GLGraph, GLScene, GLGeomObjects,
9
GLCoordinates, GLCrossPlatform, GLLCLViewer, GLBitmapFont,
10
GLWindowsFont, ComCtrls, GLParticles, GLColor, OpenGLTokens,
11
uGlobal, Menus, GLBaseClasses, GLVectorGeometry, ExtDlgs ;
14
TViewForm = class(TForm)
15
GLSViewer: TGLSceneViewer;
17
GLLight: TGLLightSource;
18
CameraCube: TGLDummyCube;
22
GLWinBmpFont: TGLWindowsBitmapFont;
23
StatusBar: TStatusBar;
28
DefaultLayout1: TMenuItem;
34
GridColours1: TMenuItem;
38
TargetCube: TGLDummyCube;
46
CoordText1: TMenuItem;
47
YCoordsCube: TGLDummyCube;
48
XCoordsCube: TGLDummyCube;
49
ZCoordsCube: TGLDummyCube;
53
DerivativeOps: TMenuItem;
54
AddedField: TGLDummyCube;
58
PlotColours1: TMenuItem;
59
DerivativePlotColours1: TMenuItem;
60
VolumeLines: TGLDummyCube;
64
procedure FormCreate(Sender: TObject);
65
procedure FormShow(Sender: TObject);
66
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
68
procedure GLSViewerMouseDown(Sender: TObject; Button: TMouseButton;
69
Shift: TShiftState; X, Y: Integer);
70
procedure GLSViewerMouseMove(Sender: TObject;
71
Shift: TShiftState; X, Y: Integer);
72
procedure GLSViewerMouseUp(Sender: TObject; Button: TMouseButton;
73
Shift: TShiftState; X, Y: Integer);
74
procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
75
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
76
procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
77
procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
78
procedure DefaultLayout1Click(Sender: TObject);
79
procedure Exit1Click(Sender: TObject);
80
procedure Grid1Click(Sender: TObject);
81
procedure GridColours1Click(Sender: TObject);
82
procedure Evaluate1Click(Sender: TObject);
83
procedure New1Click(Sender: TObject);
84
procedure Open1Click(Sender: TObject);
85
procedure Save1Click(Sender: TObject);
86
procedure Saveas1Click(Sender: TObject);
87
procedure FormDestroy(Sender: TObject);
88
procedure FormActivate(Sender: TObject);
89
procedure CoordText1Click(Sender: TObject);
90
procedure RecentFilesClick(Sender: TObject);
91
procedure FormClose(Sender: TObject; var Action: TCloseAction);
92
procedure DerivativeOpsClick(Sender: TObject);
93
procedure PlotColours1Click(Sender: TObject);
94
procedure DerivativePlotColours1Click(Sender: TObject);
96
{ Private declarations }
98
SelectedData: TPlotData; { data used to evaluate dz/dx or dz/dy }
99
procedure ShowCameraLocation;
100
procedure ShowFocalLength;
101
procedure ShowLightLocation;
102
procedure DefaultView;
103
procedure DefaultLayout;
105
procedure Formulate(const x, y: Single; var z: Single;
106
var color: TColorVector; var texPoint: TTexPoint);
107
procedure CreateHeightFields(const n: integer);
108
procedure PlotFunctions;
109
procedure CreateAddedField;
110
procedure PlotDerivativeField;
111
procedure PlotIntegralField;
113
{ Public declarations }
115
procedure ShowDisplacement;
116
procedure UpdatePlot;
117
procedure UpdateAdded;
118
procedure ClearAddedField;
119
procedure ClearAddedLines;
145
uParser, GLState, GLMaterial, Math, GLVectorTypes,
146
GridOptions, Functions, Evaluate, CoordOptions,
147
DerivativeOptions, GridColors, PlotColors, AddPlotColors;
150
function LoadCursorFromRes(CursorName:String):THandle;
154
Cur := TCursorImage.Create;
155
Cur.LoadFromResourceName(HInstance,CursorName);
156
result := Cur.ReleaseHandle;
160
procedure TViewForm.FormCreate(Sender: TObject);
165
MainPath := ExtractFilePath(Application.ExeName);
166
MainPath := IncludeTrailingPathDelimiter(MainPath);
168
aFolder := Copy(MainPath, 1, 3)+'Plot 3D\';
170
DataPath := aFolder + 'Examples\';
171
if not DirectoryExists(DataPath) then ForceDirectories(DataPath);
172
ImagePath := aFolder + 'Images\';
173
if not DirectoryExists(ImagePath) then ForceDirectories(ImagePath);
174
LayoutFName := aFolder + 'Layout.lay';
175
RecentFName := aFolder + 'Recent.ini';
178
if not DirectoryExists(ImagePath) then ForceDirectories(ImagePath);
179
if not DirectoryExists(DataPath) then ForceDirectories(DataPath);
181
Screen.Cursors[crLightxy] := LoadCursorFromRes('LIGHTXY');
182
Screen.Cursors[crLightyz] := LoadCursorFromRes('LIGHTYZ');
183
Screen.Cursors[crLightxz] := LoadCursorFromRes('LIGHTXZ');
184
Screen.Cursors[crSlidexy] := LoadCursorFromRes('SLIDEXY');
185
Screen.Cursors[crSlidexz] := LoadCursorFromRes('SLIDEXZ');
186
Screen.Cursors[crSlideyz] := LoadCursorFromRes('SLIDEYZ');
187
Screen.Cursors[crRotate] := LoadCursorFromRes('ROTATE');
188
Screen.Cursors[crZoom] := LoadCursorFromRes('ZOOM');
189
Screen.Cursors[crSlidezy] := LoadCursorFromRes('SLIDEZY');
193
procedure TViewForm.FormDestroy(Sender: TObject);
195
while Fields.Count > 0 do TGLHeightField(Fields.Children[0]).Free;
200
procedure TViewForm.FormShow(Sender: TObject);
202
LayFile: File of TLayout;
208
if FileExists(LayoutFName) then
211
AssignFile(LayFile, LayoutFName);
214
Read(LayFile, Layout);
221
if IsMaximize then WindowState := wsMaximized
224
WindowState := wsNormal;
228
Height := MainHeight;
230
GraphFName := CurrentGraphFName;
231
DataPath := CurrentDataPath;
232
ImagePath := CurrentImagePath;
234
with FunctionsForm do
239
Height := FuncHeight;
242
if GridsVisible then GridOptionsForm.Show;
243
with GridOptionsForm do
249
with GridColorsForm do
251
Left := GridColorsLeft;
252
Top := GridColorsTop;
255
with PlotColorsForm do
257
Left := PlotColorsLeft;
258
Top := PlotColorsTop;
261
if EvaluateVisible then EvaluateForm.Show;
264
Left := EvaluateLeft;
268
if CoordVisible then CoordsForm.Show;
275
with DerivativesForm do
281
with AddPlotColorsForm do
283
Left := AddColorsLeft;
287
FunctionsForm.EditMinX.SetFocus;
289
MessageDlg('File Error! An Error has occurred when attempting to read'+
290
#13#10'"'+LayoutFName+'".'+
291
#13#10'The default layout will be used.',
298
if DataPath = '' then DataPath := MainPath + 'Examples\';
299
if ImagePath = '' then ImagePath := MainPath + 'Images\';
300
if not DirectoryExists(DataPath) then ForceDirectories(DataPath);
301
if not DirectoryExists(ImagePath) then ForceDirectories(ImagePath);
304
{ focallength: right mouse drag up/down }
306
{ displace origin: x axis: ctrl/left mouse drag left/right
307
y axis: alt/left mouse drag up/down
308
z axis: ctrl/left mouse drag up/down }
310
{ move light: x axis: ctrl right mouse drag left/right
311
y axis: alt right mouse drag up/down
312
z axis: ctrl right mouse drag up/down }
315
FunctionsForm.ReadAndShowInitialData;
316
Caption := GraphFName;
318
CreateHeightFields(FunctionsForm.CheckListBox.Count);
320
ini := TIniFile.Create(RecentFName);
323
c := ReadInteger(Name, 'RecentCount', 0);
326
Recent1.Add(TMenuItem.Create(Self));
327
Recent1.Items[i].Caption := ReadString(Name, IntToStr(i), '');
328
Recent1.Items[i].OnClick := RecentFilesClick;
335
procedure TViewForm.FormActivate(Sender: TObject);
340
if GridColorsForm.Visible then GridColorsForm.ShowGridColorData;
341
if PlotColorsForm.Visible then PlotColorsForm.ShowPlotColorData;
346
procedure TViewForm.FormClose(Sender: TObject; var Action: TCloseAction);
352
ini := TIniFile.Create(RecentFName);
355
WriteInteger(Name, 'RecentCount', Recent1.Count);
356
for i := 0 to Recent1.Count-1 do
357
WriteString(Name, IntToStr(i), Recent1.Items[i].Caption);
363
procedure TViewForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
370
IsMaximize := (Width >= Screen.Width) and (Height >= Screen.Height);
374
MainHeight := Height;
375
if GraphFName = '' then GraphFName := NewFName;
376
CurrentGraphFName := GraphFName;
377
CurrentDataPath := DataPath;
378
CurrentImagePath := ImagePath;
379
with FunctionsForm do
384
FuncHeight := Height;
387
GridsVisible := GridOptionsForm.Visible;
388
with GridOptionsForm do
394
with GridColorsForm do
396
GridColorsLeft := Left;
397
GridColorsTop := Top;
400
with PlotColorsForm do
402
PlotColorsLeft := Left;
403
PlotColorsTop := Top;
406
EvaluateVisible := EvaluateForm.Visible;
409
EvaluateLeft := Left;
413
CoordVisible := CoordsForm.Visible;
420
with DerivativesForm do
424
if Visible then Close;
427
with AddPlotColorsForm do
429
AddColorsLeft := Left;
431
if Visible then Close;
436
AssignFile(f, LayoutFName);
444
MessageDlg('File Error! An Error has occurred'+
445
#13#10'when attempting to write to "'+LayoutFName+'".',
449
if Altered or GridColorsAltered or DerivativeAltered then
451
case MessageDlg('The current graph''s data has been altered.'+
452
#13#10'Do you wish to save the alterations ?', mtConfirmation,
453
[mbYes, mbNo, mbCancel], 0) of
454
mrYes: FunctionsForm.SaveClick(Sender);
463
procedure TViewForm.FormKeyDown(Sender: TObject; var Key: Word;
471
VK_ADD: d := -1; { zoom in }
472
VK_SUBTRACT: d := 1; { zoom out }
474
if Key in [VK_ADD, VK_SUBTRACT] then
476
Screen.Cursor := crZoom;
478
{ each step adjusts target distance by 2.5% another method to zoom in or out }
479
Camera.AdjustDistanceToTarget(Power(1.025, d));
484
VK_HOME, VK_NUMPAD7, 72: DefaultView; {'H'/'h' key}
495
procedure TViewForm.FormKeyUp(Sender: TObject; var Key: Word;
498
Screen.Cursor := crDefault;
501
procedure TViewForm.FormMouseWheel(Sender: TObject; Shift: TShiftState;
502
WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
504
if (MousePoint.X >= GLSViewer.Left) and
505
(MousePoint.X <= GLSViewer.Left + GLSViewer.Width) and
506
(MousePoint.Y >= GLSViewer.Top) and
507
(MousePoint.y <= GLSViewer.Top + GLSViewer.Height) then
509
{ a wheel step = WheelDelta/300; each step adjusts target distance by 2.5%
510
another method to zoom in or out }
512
Camera.AdjustDistanceToTarget(Power(1.025, WheelDelta/300));
517
procedure TViewForm.GLSViewerMouseDown(Sender: TObject; Button: TMouseButton;
518
Shift: TShiftState; X, Y: Integer);
522
if ssShift in Shift then { Shift key down }
524
if ssLeft in Shift then Screen.Cursor := crZoom;
526
else if ssCtrl in Shift then { Ctrl key down }
528
if ssLeft in Shift then Screen.Cursor := crSlidexz
530
if ssRight in Shift then Screen.Cursor := crLightxz;
532
else if ssAlt in Shift then { Alt key down }
534
if ssLeft in Shift then Screen.Cursor := crSlidezy
536
if ssRight in Shift then Screen.Cursor := crLightxy;
538
else { no shift, ctrl or alt key }
540
if Shift = [ssLeft] then Screen.Cursor := crRotate
542
if Shift = [ssRight] then Screen.Cursor := crZoom;
546
procedure TViewForm.GLSViewerMouseMove(Sender: TObject;
547
Shift: TShiftState; X, Y: Integer);
551
begin { refer GLScene\Demos\interface\camera\Camera.dpr }
552
if MousePoint.X = MaxInt then { FileOpenDialog is visible }
558
dx := MousePoint.X - X;
559
dy := MousePoint.Y - Y;
561
if ssShift in Shift then { shift key down }
563
if ssLeft in Shift then { shift - left mouse button }
565
{ dy = a step which adjusts target distance by 1.25%; zoom in or out }
566
with Camera do AdjustDistanceToTarget(Power(1.0125, dy));
571
if ssCtrl in Shift then { Ctrl key down }
573
if ssLeft in Shift then { Ctrl - left mouse button }
575
TargetCube.Position.X :=
576
TargetCube.Position.X - dx*GLxzGrid.XSamplingScale.Step/10;
577
TargetCube.Position.Z :=
578
TargetCube.Position.Z - dy*GLxzGrid.ZSamplingScale.Step*ViewData.xyGrid.zScale/10;
581
if ssRight in Shift then { Ctrl - right mouse button }
583
GLLight.Position.Z := GLLight.Position.Z + dy/10;
584
GLLight.Position.X := GLLight.Position.X + dx/10;
589
if ssAlt in Shift then { Alt key down }
591
if ssRight in Shift then { Alt - right mouse button }
593
GLLight.Position.X := GLLight.Position.X + dx/10;
594
GLLight.Position.Y := GLLight.Position.Y + dy/10;
598
if ssLeft in Shift then { Alt - left mouse button }
600
TargetCube.Position.Y :=
601
TargetCube.Position.Y + dx*GLyzGrid.YSamplingScale.Step/10;
602
TargetCube.Position.Z :=
603
TargetCube.Position.Z - dy*GLyzGrid.ZSamplingScale.Step*ViewData.xyGrid.zScale/10;
607
else { no shift key }
609
if Shift = [ssLeft] then
610
{ Left mouse button changes camera angle by moving around target }
612
Camera.MoveAroundTarget(dy, dx);
615
if Shift = [ssRight] then
617
{ Right mouse button alters the camera's focal length;
618
zoom out or in by moving cursor up or down }
621
FocalLength := FocalLength - dy;
622
if FocalLength > 3000 then FocalLength := 3000; { max focal length }
623
if FocalLength < 10 then FocalLength := 10; { min focal length }
625
ShowFocalLength; { display in statusbar palel }
628
MousePoint.X := X; { update mouse position }
632
procedure TViewForm.GLSViewerMouseUp(Sender: TObject; Button: TMouseButton;
633
Shift: TShiftState; X, Y: Integer);
635
Screen.Cursor := crDefault;
638
procedure TViewForm.New1Click(Sender: TObject);
640
FunctionsForm.New1Click(Sender);
643
procedure TViewForm.Open1Click(Sender: TObject);
645
FunctionsForm.Open1Click(Sender);
648
procedure TViewForm.Save1Click(Sender: TObject);
650
FunctionsForm.SaveClick(Sender);
653
procedure TViewForm.Saveas1Click(Sender: TObject);
655
FunctionsForm.SaveAsClick(Sender);
658
procedure TViewForm.ShowCameraLocation;
660
with Camera.Position do
661
StatusBar.Panels[0].Text := 'Camera: '+FloatToStrF(X, ffNumber, 5, 2)+', '+
662
FloatToStrF(Y, ffNumber, 5, 2)+', '+FloatToStrF(Z, ffNumber, 5, 2);
665
procedure TViewForm.GridColours1Click(Sender: TObject);
670
procedure TViewForm.CoordText1Click(Sender: TObject);
675
procedure TViewForm.ShowFocalLength;
678
StatusBar.Panels[1].Text := 'f = '+FloatToStrF(FocalLength, ffnumber, 5, 2);
681
procedure TViewForm.ShowDisplacement;
683
with TargetCube.Position do
684
StatusBar.Panels[2].Text := 'Displaced: '+
685
FloatToStrF(-X, ffNumber, 5, 2)+', '+FloatToStrF(-Y, ffNumber, 5, 2)+', '+
686
FloatToStrF(-Z, ffNumber, 5, 2);
689
procedure TViewForm.Evaluate1Click(Sender: TObject);
694
procedure TViewForm.ShowLightLocation;
696
with GLLight.Position do
697
StatusBar.Panels[3].Text := 'Light: '+
698
FloatToStrF(X, ffNumber, 5, 2)+', '+FloatToStrF(Y, ffNumber, 5, 2)+', '+
699
FloatToStrF(Z, ffNumber, 5, 2);
702
procedure TViewForm.Grid1Click(Sender: TObject);
704
GridOptionsForm.Show;
707
procedure TViewForm.DefaultLayout1Click(Sender: TObject);
712
procedure TViewForm.DefaultView;
714
CameraCube.Position.SetPoint(0, 0, 0);
716
Camera.FocalLength := 200;
718
Camera.Position.SetPoint(50, 50, 30);
719
Camera.DepthOfView := 1000;
721
GLLight.Position.SetPoint(50, 50, 50);
723
TargetCube.Position.SetPoint(0, 0, 0);
726
procedure TViewForm.RecentFilesClick(Sender: TObject);
728
FunctionsForm.OpenRecentFile(TMenuItem(Sender).Caption);
731
procedure TViewForm.Exit1Click(Sender: TObject);
736
procedure TViewForm.DefaultLayout;
738
WindowState := wsNormal;
741
FunctionsForm.Width := 335;
742
FunctionsForm.Height := 387;
743
ViewForm.Width := Screen.Width - FunctionsForm.Width + 18;
744
ViewForm.Height := Screen.Height - 40;
745
FunctionsForm.Left := ViewForm.Left + ViewForm.Width - 14;
746
FunctionsForm.Top := ViewForm.Top;
747
GridOptionsForm.Left := FunctionsForm.Left +5;
748
GridOptionsForm.Top := FunctionsForm.Top + FunctionsForm.Height - 6;
749
EvaluateForm.Left := GridOptionsForm.Left;
750
EvaluateForm.Top := GridOptionsForm.Top + GridOptionsForm.Height - 3;
752
GridOptionsForm.Show;
753
GridColorsForm.Left := 20;
754
GridColorsForm.Top := 80;
755
PlotColorsForm.Left := 30;
756
PlotColorsForm.Top := 100;
757
AddPlotColorsForm.Left := 40;
758
AddPlotColorsForm.Top := 120;
759
FunctionsForm.EditMinX.SetFocus;
762
procedure TViewForm.DerivativeOpsClick(Sender: TObject);
764
if PlotColorsForm.Visible then PlotColorsForm.Close;
765
PlotColours1.Enabled := False;
766
DerivativePlotColours1.Enabled := True;
767
DerivativesForm.Show;
770
procedure TViewForm.DerivativePlotColours1Click(Sender: TObject);
772
if PlotColorsForm.Visible then PlotColorsForm.Close;
773
PlotColours1.Enabled := False;
774
AddPlotColorsForm.Show;
777
procedure TViewForm.PlotFunctions;
778
procedure PlotFunction(i: Integer);
782
with TGLHeightField(Fields.Children[i]) do
784
with XSamplingScale do
791
with YSamplingScale do
799
vmAmbient:ColorMode := hfcmAmbient;
800
vmAmbientandDiffuse:ColorMode := hfcmAmbientAndDiffuse;
801
vmDiffuse:ColorMode := hfcmDiffuse;
802
vmEmmision:ColorMode := hfcmEmission;
803
vmNone:ColorMode := hfcmNone;
807
fxyFill:Material.PolygonMode := pmFill;
808
fxyLines:Material.PolygonMode := pmLines;
809
fxyPoints:Material.PolygonMode := pmPoints;
811
OnGetHeight := Formulate;
813
GLSViewer.Refresh; { needed to display each zField data in list }
819
fxyParser: TfxyParser;
820
PD: TPlotData; { save the current PlotData of selected function }
822
begin { PlotFunctions }
823
Screen.Cursor := crHourGlass;
825
fxyParser := TfxyParser.Create(0, 0);
827
with FunctionsForm.CheckListBox do
828
for i := 0 to Items.Count -1 do if Checked[i] then
830
{ an item is checked; get the plot data }
831
PlotData := TPlotDataObject(Items.Objects[i]).Data;
835
Screen.Cursor := crDefault;
837
PlotData := PD; { restor the current PlotData }
841
procedure TViewForm.Formulate(const x, y: Single; var z: Single;
842
var color: TColorVector; var texPoint: TTexPoint);
845
MaxZ, MinZ: TGLFloat;
846
x1, x2, y1, y2, z1, z2: extended;
849
case AddedData.AddedAs of
850
AddNone: { no AddedData to plot; just plot the PlotData }
852
z := ParseEvaluateFxy(x, y, PlotData.fxyStr, e);
853
z := z*ViewData.xyGrid.zScale;
856
MaxZ := zMax*ViewData.xyGrid.zScale;
857
MinZ := zMin*ViewData.xyGrid.zScale;
860
if zLim and (z > MaxZ) then z := MaxZ;
861
if zLim and (z < MinZ) then z := MinZ;
864
if zLim and ((z < MinZ) or (z > MaxZ)) then z := NaN;
865
VectorLerp(LowerColor, UpperColor, z*ColorBlend - ColorMove, color);
869
AddDerivX: { this is for partial derivative wrt x }
871
x1 := x - AddedData.xInc;
872
x2 := x + AddedData.xInc;
873
z1 := ParseEvaluateFxy(x1, y, SelectedData.fxyStr, e);{ evaluate z1,x1,y }
874
z2 := ParseEvaluateFxy(x2, y, SelectedData.fxyStr, e);{ evaluate z2,x2,y }
875
z := (z2 - z1)/(x2 - x1); { z = slope wrt x axis }
876
z := z*ViewData.xyGrid.zScale;
879
MaxZ := zMax*ViewData.xyGrid.zScale;
880
MinZ := zMin*ViewData.xyGrid.zScale;
883
if zLim and (z > MaxZ) then z := MaxZ;
884
if zLim and (z < MinZ) then z := MinZ;
887
if zLim and ((z < MinZ) or (z > MaxZ)) then z := NaN;
888
VectorLerp(LowerColor, UpperColor, z*ColorBlend - ColorMove, color);
892
AddDerivY: { this is for partial derivative wrt y }
894
y1 := y - AddedData.yInc;
895
y2 := y + AddedData.yInc;
896
z1 := ParseEvaluateFxy(x, y1, SelectedData.fxyStr, e);{ evaluate z1,x,y1 }
897
z2 := ParseEvaluateFxy(x, y2, SelectedData.fxyStr, e);{ evaluate z2,x,y2 }
898
z := (z2 - z1)/(y2 - y1); { z = slope wrt y axis }
899
z := z*ViewData.xyGrid.zScale;
902
MaxZ := zMax*ViewData.xyGrid.zScale;
903
MinZ := zMin*ViewData.xyGrid.zScale;
906
if zLim and (z > MaxZ) then z := MaxZ;
907
if zLim and (z < MinZ) then z := MinZ;
910
if zLim and ((z < MinZ) or (z > MaxZ)) then z := NaN;
911
VectorLerp(LowerColor, UpperColor, z*ColorBlend - ColorMove, color);
915
AddVolume: { this is for double integral }
917
z := ParseEvaluateFxy(x, y, PlotData.fxyStr, e);
920
z := z*ViewData.xyGrid.zScale;
921
MaxZ := zMax*ViewData.xyGrid.zScale;
922
MinZ := zMin*ViewData.xyGrid.zScale;
925
if zLim and (z > MaxZ) then z := MaxZ;
926
if zLim and (z < MinZ) then z := MinZ;
929
if zLim and ((z < MinZ) or (z > MaxZ)) then z := NaN;
930
VectorLerp(LowerColor, UpperColor, z*ColorBlend - ColorMove, color);
932
TGLLines.CreateAsChild(VolumeLines);
935
with TGLLines(Children[Count -1]) do
937
LineColor.AsWinColor := AddLineColor;
938
LineWidth := AddLineWidth;
939
NodesAspect := LnaInvisible;
942
Nodes[0].X := x; { start point }
944
if zLim then Nodes[0].Z := MinZ else Nodes[0].Z := 0;
947
Nodes[1].X := x; { end point }
954
end; { case AddedData.AddedAs of... }
957
procedure TViewForm.PlotDerivativeField;
960
FoundSelected: Boolean;
963
Screen.Cursor := crHourGlass;
966
if FunctionsForm.CheckListBox.Count > 1 then { find Selected item }
968
FoundSelected := False;
969
while not FoundSelected and (i < FunctionsForm.CheckListBox.Count) do
971
FoundSelected := FunctionsForm.CheckListBox.Selected[i];
972
if not FoundSelected then Inc(i);
976
with FunctionsForm.CheckListBox do
977
SelectedData := TPlotDataObject(Items.Objects[i]).Data;
981
with TGLHeightField(AddedField.Children[0]) do
983
with XSamplingScale do
990
with YSamplingScale do
998
vmAmbient:ColorMode := hfcmAmbient;
999
vmAmbientandDiffuse:ColorMode := hfcmAmbientAndDiffuse;
1000
vmDiffuse:ColorMode := hfcmDiffuse;
1001
vmEmmision:ColorMode := hfcmEmission;
1002
vmNone:ColorMode := hfcmNone;
1006
fxyFill:Material.PolygonMode := pmFill;
1007
fxyLines:Material.PolygonMode := pmLines;
1008
fxyPoints:Material.PolygonMode := pmPoints;
1010
OnGetHeight := Formulate;
1012
GLSViewer.Refresh; { needed to display each zField data in list }
1015
Screen.Cursor := crDefault;
1019
procedure TViewForm.PlotIntegralField;
1020
procedure PlotVolume;
1021
begin { PlotVolume }
1024
with TGLHeightField(AddedField.Children[0]) do
1026
with XSamplingScale do
1033
with YSamplingScale do
1041
vmAmbient:ColorMode := hfcmAmbient;
1042
vmAmbientandDiffuse:ColorMode := hfcmAmbientAndDiffuse;
1043
vmDiffuse:ColorMode := hfcmDiffuse;
1044
vmEmmision:ColorMode := hfcmEmission;
1045
vmNone:ColorMode := hfcmNone;
1049
fxyFill:Material.PolygonMode := pmFill;
1050
fxyLines:Material.PolygonMode := pmLines;
1051
fxyPoints:Material.PolygonMode := pmPoints;
1053
OnGetHeight := Formulate;
1055
GLSViewer.Refresh; { needed to display each zField data in list }
1059
procedure CalculateVolume;
1062
i, j, iCount, jCount: integer;
1063
x, y, z, x0, y0, a, VolPos, VolNeg: TGLFloat;
1065
begin { CalculateVolume }
1068
a := xInc*yInc; { base area }
1069
iCount := round((xMax - xMin)/xInc) -1; { number of x points }
1070
jCount := round((yMax - yMin)/yInc) -1; { number of y points }
1073
x0 := xMin + xInc/2; { base centre x0 }
1074
y0 := yMin + yInc/2; { base centre y0 }
1075
for j := 0 to jCount do
1077
y := y0 + j*yInc; { next column wrt y }
1078
for i := 0 to iCount do
1080
x := x0 + i*xInc; { next column wrt x }
1081
z := ParseEvaluateFxy(x, y, PlotData.fxyStr, e);
1083
if zLim then { zLimit applied }
1085
if (zMax >= 0) and (zMin <= 0) then { above and below zero }
1089
if z > zMax then VolPos := VolPos + a*zMax
1090
else VolPos := VolPos + a*z;
1094
if z < zMin then VolNeg := VolNeg + a*zMin
1095
else VolNeg := VolNeg + a*z;
1099
if zMin > 0 then { both above zero }
1103
if z > zMax then VolPos := VolPos + a*(zMax - zMin)
1104
else VolPos := VolPos + a*(z - zMin);
1108
if zMax < 0 then { both below zero }
1112
if z < zMin then VolNeg := VolNeg + a*(zMax - zMin)
1113
else VolNeg := VolNeg + a*(z - zMax);
1117
else { no zLimit applied }
1119
if z > 0 then VolPos := VolPos + a*z
1120
else VolNeg := VolNeg + a*z;
1126
with DerivativesForm do
1128
PosVolLabel.Caption := 'Positive Volume: '+FloatToStr(VolPos);
1129
NegVolLabel.Caption := 'Negative Volume: '+FloatToStr(VolNeg);
1130
TotalLabel.Caption := 'Absolute Volume: '+FloatToStr(VolPos - VolNeg);
1131
VolumeLabel.Caption := 'Total Volume: '+FloatToStr(VolPos + VolNeg);
1133
end; { CalculateVolume }
1135
begin { TViewForm.PlotIntegralField }
1136
Screen.Cursor := crHourGlass;
1142
DerivativesForm.VolumeRB.Checked := False; //
1143
Screen.Cursor := crDefault;
1144
end; { TViewForm.PlotIntegralField }
1146
procedure TViewForm.PlotColours1Click(Sender: TObject);
1148
PlotColorsForm.Show;
1151
procedure TViewForm.CreateHeightFields(const n: integer);
1156
while Fields.Count > 0 do TGLHeightField(Fields.Children[0]).Free;
1157
for i := 0 to n -1 do
1159
TGLHeightField.CreateAsChild(Fields);
1161
Fields.Children[Fields.Count -1]).Material.BlendingMode := bmTransparency;
1165
procedure TViewForm.CreateAddedField;
1168
TGLHeightField.CreateAsChild(AddedField);
1169
TGLHeightField(AddedField.Children[0]).Material.BlendingMode := bmTransparency;
1172
procedure TViewForm.UpdatePlot;
1174
CreateHeightFields(FunctionsForm.CheckListBox.Count);
1178
procedure TViewForm.UpdateAdded;
1181
AddXLine.LineColor.AsWinColor := AddedData.AddLineColor;
1182
AddYLine.LineColor.AsWinColor := AddedData.AddLineColor;
1183
AddZLine.LineColor.AsWinColor := AddedData.AddLineColor;
1184
AddXLine.LineWidth := AddedData.AddLineWidth;
1185
AddYLine.LineWidth := AddedData.AddLineWidth;
1186
AddZLine.LineWidth := AddedData.AddLineWidth;
1187
if AddedData.AddedAs = AddVolume then PlotIntegralField
1188
else PlotDerivativeField;
1191
procedure TViewForm.ClearAddedField;
1193
with TGLHeightField(AddedField) do if Count > 0 then Children[0].Free;
1196
procedure TViewForm.ClearAddedLines;
1198
Screen.Cursor := crHourGlass;
1199
with TGLLines(VolumeLines) do
1200
while Count > 0 do Children[Count -1].Free;
1201
Screen.Cursor := crDefault;