MathgeomGLS
240 строк · 5.8 Кб
1unit Contour;
2{Demonstrates contour drawing features of MathImage, as well as the use
3of the TSurface/TLevelSurface object. The routines marked by *********** use
4MathImage methods.
5The filled level lines routine is very memory intensive. I found
6Robert Lee's memory manager replacement (available from Code Central)
7to
8a) speed up things a lot,
9b) allow me to use more grid points.}
10
11interface
12
13uses
14Winapi.Windows,
15Winapi.Messages,
16System.Classes,
17System.SysUtils,
18Vcl.Graphics,
19Vcl.Controls,
20Vcl.Forms,
21Vcl.Dialogs,
22Vcl.StdCtrls,
23Vcl.ExtCtrls,
24Vcl.Menus,
25Vcl.Clipbrd,
26//
27MathImage,
28OverlayImage;
29
30const
31gxmin = -3; gxmax = 6.5; gymin = -4; gymax = 4; {graph domain}
32xMesh = 100; yMesh = 100; {graph mesh}
33c = 4;
34colorarray: array[0..13] of TColor = ($00CB9F74, $00D8AD49, $00E6C986,
35$00F2E3C1, $00DAF0C4, $00A6E089, $0086D560, $0065CFB5, $008DC5FC, $0075D5FD,
36$0078E1ED, $00ACEDF4, $00D0F2F7, $00F2FBFD);
37levelsarray: array[0..13] of MathFloat = (-1, -0.7, -0.4, -0.2, 0, 0.2, 0.4,
380.6, 0.8, 1.1, 1.4, 1.6, 2.2, 4);
39
40type
41TContourform = class(TForm)
42Panel1: TPanel;
43ContourlinesButton: TButton;
44ColorDialog1: TColorDialog;
45Panel2: TPanel;
46FilledContoursButton: TButton;
47GraphImage: TMathImage;
48Label1: TLabel;
49procedure ContourlinesButtonClick(Sender: TObject);
50procedure GraphImageResize(Sender: TObject);
51procedure FormCreate(Sender: TObject);
52procedure FormDestroy(Sender: TObject);
53procedure FilledContoursButtonClick(Sender: TObject);
54procedure FormShow(Sender: TObject);
55private
56CurrentType: Integer;
57GraphSurface: TLevelSurface;
58LevelsMade: Boolean;
59procedure Graph(x, y: MathFloat; var z: MathFloat);
60procedure MakeGraphSurface;
61protected
62procedure CreateParams(var Params: TCreateParams); override;
63public
64values: array[0..13] of TLabel;
65Colors: array[0..13] of TLabel;
66end;
67
68var
69ContourForm: TContourform;
70
71implementation
72
73
74uses
75MDemo1;
76
77
78{$R *.DFM}
79
80procedure TContourform.CreateParams(var Params: TCreateParams);
81begin
82inherited CreateParams(Params);
83with Params do
84begin
85WndParent := Demoform.Handle;
86Parent := Demoform;
87Style := WS_CHILD or WS_CLIPSIBLINGS or WS_CLIPCHILDREN;
88Align := alClient;
89end;
90end;
91
92
93{*************************************}
94
95procedure TContourform.FormCreate(Sender: TObject);
96var
97i: Integer;
98begin
99makegraphsurface;
100ControlStyle := ControlStyle + [csOpaque];
101currenttype := 1;
102for i := 0 to 13 do
103begin
104values[i] := TLabel.Create(self);
105with values[i] do
106begin
107Top := Label1.Top + Label1.Height + 5 + i * Label1.Height;
108Left := Label1.Left;
109Parent := Panel1;
110Caption := FloatToStrf(levelsarray[i], ffgeneral, 4, 4);
111end;
112Colors[i] := TLabel.Create(self);
113with Colors[i] do
114begin
115autosize := False;
116Caption := '';
117Left := Label1.Left + Label1.Width;
118Top := values[i].Top;
119Width := values[i].Height;
120Height := Width;
121Color := colorarray[i];
122Parent := Panel1;
123end;
124end;
125end;
126
127procedure TContourform.Graph(x, y: MathFloat; var z: MathFloat);
128{graph formula}
129begin
130
131//this first one is a real test, it looks crummy unless you
132//give it a mesh of about 200x200, in which case the filled level
133//curve drawing runs out of mem under Win2K on my machine...
134//****Cure: Use Robert Lee's memory manager replacement,
135//available from CodeCentral, it's awesome.****************
136//There isn't anything I can do about level
137//curves near intersection points looking bad,
138//other than increasing the mesh.
139
140// z := 2 * (cos(1.5 * (x - y)) + sin(1.6 * (x + 0.6 * y))) + 0.8;
141
142if (x <> c) or (y <> 0) then
143z := sin(sqrt(sqr(x) + sqr(y))) + 1 / sqrt(sqr(x - c) + sqr(y))
144else
145z := 1.0E10
146end;
147
148{**************************}
149
150procedure TContourform.ContourlinesButtonClick(Sender: TObject);
151var SavePen: TPen; i: Integer;
152begin
153Screen.Cursor := CrHourGlass;
154currenttype := 1;
155with GraphImage do
156begin
157SetWorld(gxmin, gymin, gxmax, gymax);
158Clear;
159DrawAxes('x ', 'y', False, clSilver, clSilver, False);
160SavePen := TPen.Create;
161SavePen.assign(Pen);
162for i := 0 to High(levelsarray) do
163begin
164Pen.Color := colorarray[i];
165DrawLevelCurves(graphsurface, levelsarray[i]);
166end;
167Pen.assign(SavePen);
168SavePen.Free;
169end;
170Screen.Cursor := crDefault;
171end;
172
173{******************************}
174
175procedure TContourform.FilledContoursButtonClick(Sender: TObject);
176begin
177Screen.Cursor := CrHourGlass;
178currenttype := 2;
179with GraphImage do
180begin
181if not LevelsMade then
182begin //The following is what takes long
183graphsurface.SetLevels(levelsarray, colorarray);
184LevelsMade := True;
185end;
186SetWorld(gxmin, gymin, gxmax, gymax);
187Clear;
188DrawAxes('x ', 'y', False, clSilver, clSilver, False);
189DrawFilledLevelCurves(graphsurface);
190end;
191Screen.Cursor := crDefault;
192end;
193{*****************************************}
194
195procedure TContourform.MakeGraphSurface;
196var
197i, j: Integer; x, y, z: MathFloat;
198begin
199graphsurface := TLevelSurface.Create(xMesh, yMesh);
200for i := 0 to xMesh do
201begin
202x := gxmin + i * (gxmax - gxmin) / xMesh;
203for j := 0 to yMesh do
204begin
205y := gymin + j * (gymax - gymin) / yMesh;
206Graph(x, y, z);
207graphsurface.Make(i, j, x, y, z);
208end;
209end;
210LevelsMade := False;
211end;
212
213
214{****************************}
215
216procedure TContourform.GraphImageResize(Sender: TObject);
217begin
218if currenttype = 1 then
219ContourlinesButtonClick(self)
220else FilledContoursButtonClick(self);
221end;
222
223
224procedure TContourform.FormDestroy(Sender: TObject);
225begin
226graphsurface.Free;
227end;
228
229procedure TContourform.FormShow(Sender: TObject);
230begin
231/// SaveasMetafile1.enabled := False;
232ContourlinesButtonClick(self); //Already done in GraphimageResize
233end;
234
235
236initialization
237
238
239
240end.
241
242