MathgeomGLS

Форк
0
/
fPlot1D.pas 
1109 строк · 28.1 Кб
1
unit fPlot1D;
2
(* App crashes; stops responding; when vertical volume intergration calculated
3
  for x/arccsc(ln(x^4)); xonarccsc(ln(x_4)).yfx file
4
  also for large movements when logx and logy axes in use *)
5

6
interface
7

8
uses
9
  Winapi.Windows,
10
  Winapi.Messages,
11
  System.SysUtils,
12
  System.Variants,
13
  System.Classes,
14
  System.UITypes,
15
  System.Math,
16
  Vcl.Graphics,
17
  Vcl.Controls,
18
  Vcl.Forms,
19
  Vcl.Dialogs,
20
  Vcl.ComCtrls,
21
  Vcl.Menus,
22
  Vcl.ExtDlgs,
23
  Vcl.Printers,
24

25
  GLS.Scene,
26
  GLS.Coordinates,
27

28
  GLS.BaseClasses,
29
  GLS.SceneViewer,
30
  GLS.BitmapFont,
31
  GLS.WindowsFont,
32
  GLS.RenderContextInfo,
33

34
  uCanvas,
35
  uGlobal,
36
  fAbout,
37
  fFuncts;
38

39
type
40
  TMainForm = class(TForm)
41
    MainMenu: TMainMenu;
42
    File1: TMenuItem;
43
    New: TMenuItem;
44
    Open: TMenuItem;
45
    Save: TMenuItem;
46
    SaveAs: TMenuItem;
47
    SaveBMPfile1: TMenuItem;
48
    SaveJPGfile1: TMenuItem;
49
    N2: TMenuItem;
50
    Print1: TMenuItem;
51
    SetupPrinter1: TMenuItem;
52
    N1: TMenuItem;
53
    ExitApp: TMenuItem;
54
    View1: TMenuItem;
55
    GridOptions1: TMenuItem;
56
    NumGraphs: TMenuItem;
57
    Texts1: TMenuItem;
58
    Style1: TMenuItem;
59
    SelectStyle1: TMenuItem;
60
    SaveStyle1: TMenuItem;
61
    StatusBar: TStatusBar;
62
    GLViewer: TGLSceneViewer;
63
    GLScene: TGLScene;
64
    GLCamera: TGLCamera;
65
    GLDirectOpenGL: TGLDirectOpenGL;
66
    GLWinBitFont: TGLWindowsBitmapFont;
67
    GLMemoryViewer: TGLMemoryViewer;
68
    PrinterSetupDialog: TPrinterSetupDialog;
69
    DefaultLayout1: TMenuItem;
70
    Help1: TMenuItem;
71
    About1: TMenuItem;
72
    procedure FormCreate(Sender: TObject);
73
    procedure FormShow(Sender: TObject);
74
    procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
75
    procedure FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
76
    procedure FormKeyUp(Sender: TObject; var Key: Word; Shift: TShiftState);
77
    procedure FormMouseWheel(Sender: TObject; Shift: TShiftState;
78
              WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
79
    procedure GLViewerDragOver(Sender, Source: TObject; X, Y: Integer;
80
                               State: TDragState; var Accept: Boolean);
81
    procedure GLViewerEndDrag(Sender, Target: TObject; X, Y: Integer);
82
    procedure GLViewerMouseDown(Sender: TObject; Button: TMouseButton;
83
                                 Shift: TShiftState; X, Y: Integer);
84
    procedure GLViewerMouseMove(Sender: TObject; Shift: TShiftState;
85
                                  X, Y: Integer);
86
    procedure GLViewerMouseUp(Sender: TObject; Button: TMouseButton;
87
                               Shift: TShiftState; X, Y: Integer);
88
    procedure GLDirectOpenGLRender(Sender: TObject;
89
                                  var rci: TGLRenderContextInfo);
90
    procedure NewClick(Sender: TObject);
91
    procedure OpenClick(Sender: TObject);
92
    procedure SaveClick(Sender: TObject);
93
    procedure SaveAsClick(Sender: TObject);
94
    procedure ExitAppClick(Sender: TObject);
95
    procedure GridOptions1Click(Sender: TObject);
96
    procedure Texts1Click(Sender: TObject);
97
    procedure SaveBMPfile1Click(Sender: TObject);
98
    procedure SaveJPGfile1Click(Sender: TObject);
99
    procedure Print1Click(Sender: TObject);
100
    procedure SetupPrinter1Click(Sender: TObject);
101
    procedure SelectStyle1Click(Sender: TObject);
102
    procedure SaveStyle1Click(Sender: TObject);
103
    procedure GLViewerMouseLeave(Sender: TObject);
104
    procedure NumGraphsClick(Sender: TObject);
105
    procedure DefaultLayout1Click(Sender: TObject);
106
    procedure About1Click(Sender: TObject);
107
  private
108
    dMove: integer;
109
    procedure ShowXYvalues(const x, y: extended);
110
    procedure UpdateGridXRange;
111
    procedure UpdateGridYRange;
112
    procedure DefaultLayout;
113
    function ValueX(const x: integer): extended;
114
    function ValueY(const y: integer): extended;
115
    function ValueLogX(const x: integer): extended;
116
    function ValueLogY(const y: integer): extended;
117
  public
118
    oMousex, oMousey: integer;
119
  end;
120

121
const
122
  crHandMove = 1;
123
  crMoveRight = 2;
124
  crMoveLeft = 3;
125
  crMoveUp = 4;
126
  crMoveDown = 5;
127
  crZoom = 6;
128

129
var
130
  MainForm: TMainForm;
131
  NewFont: Boolean = True;
132
  PrinterExists: Boolean;
133

134
//=====================================================================
135
implementation
136
//=====================================================================
137

138
{$R *.dfm}
139
{$R CURSORS.RES}
140

141
uses
142
  fGridOpts,
143
  fIntegrateX,
144
  fIntegrateY,
145
  fBitmap,
146
  fStyle,
147
  fTextBlocks,
148
  fDerivative,
149
  fBetween,
150
  fVolumeX,
151
  fVolumeY,
152
  fxValue,
153
  fx1Value,
154
  fx2Value,
155
  fNumeric,
156
  fPrint;
157

158
procedure TMainForm.FormCreate(Sender: TObject);
159

160
begin
161
  BinPath :=  ExtractFilePath(ParamStr(0));
162
  BinPath := IncludeTrailingPathDelimiter(BinPath);
163
  DataPath := BinPath + 'Examples\';
164

165
  PrinterExists := Printer.Printers.Count > 0;
166
  StyleFName := BinPath + 'Styles.sty';
167
  LayoutFName := BinPath + 'Layout.lay';
168

169
  Screen.Cursors[crHandMove] := LoadCursor(HInstance, 'HANDMOVE');
170
  Screen.Cursors[crMoveRight] := LoadCursor(HInstance, 'MOVERIGHT');
171
  Screen.Cursors[crMoveLeft] := LoadCursor(HInstance, 'MOVELEFT');
172
  Screen.Cursors[crMoveUp] := LoadCursor(HInstance, 'MOVEUP');
173
  Screen.Cursors[crMoveDown] := LoadCursor(HInstance, 'MOVEDOWN');
174
  Screen.Cursors[crZoom] := LoadCursor(HInstance, 'ZOOM');
175
  dMove := $200;
176
end;
177

178
procedure TMainForm.FormShow(Sender: TObject);
179
var
180
  f: File of TLayout;
181

182
begin
183
  if FileExists(LayoutFName) then
184
  begin
185
    try
186
      AssignFile(f, LayoutFName);
187
      try
188
        Reset(f);
189
        Read(f, Layout);
190
      finally
191
        CloseFile(f);
192
      end;
193

194
      if Layout.IsMaximize then WindowState := wsMaximized
195
      else
196
      begin
197
        with Layout do
198
        begin
199
          Left := MainLeft;
200
          Top := MainTop;
201
          Width := MainWidth;
202
          Height := MainHeight;
203
          GraphFName := CurrentGraphFName;
204
          DataPath := CurrentDataPath;
205
          ImagePath := CurrentImagePath;
206
          PrinterInfo := CurrentPrinterInfo;
207

208
          if GridsVisible then GridOptionsForm.Show;
209
          with GridOptionsForm do
210
          begin
211
            MainForm.Left := GridsLeft;
212
            MainForm.Top := GridsTop;
213
          end;
214

215
          if NumericVisible then NumericForm.Show;
216
          with NumericForm do
217
          begin
218
            MainForm.Left := NumericLeft;
219
            MainForm.Top := NumericTop;
220
          end;
221

222
          if TextVisible then TextBlocksForm.Show;
223
          with TextBlocksForm do
224
          begin
225
            MainForm.Left := TextLeft;
226
            MainForm.Top := TextTop;
227
            MainForm.Width := TextWidth;
228
            MainForm.Height := TextHeight;
229
          end;
230
          with FunctionsForm do
231
          begin
232
            MainForm.Left := FuncLeft;
233
            MainForm.Top := FuncTop;
234
          end;
235
          with DerivativeForm do
236
          begin
237
            MainForm.Left := DerivLeft;
238
            MainForm.Top := DerivTop;
239
          end;
240
          with IntegrateXForm do
241
          begin
242
            MainForm.Left := IntegXLeft;
243
            MainForm.Top := IntegXTop;
244
          end;
245
          with IntegrateYForm do
246
          begin
247
            MainForm.Left := IntegYLeft;
248
            MainForm.Top := IntegYTop;
249
          end;
250
          with BetweenForm do
251
          begin
252
            MainForm.Left := BetweenLeft;
253
            MainForm.Top := BetweenTop;
254
          end;
255
          with VolumeXForm do
256
          begin
257
            MainForm.Left := VolumeXLeft;
258
            MainForm.Top := VolumeXTop;
259
          end;
260
          with VolumeYForm do
261
          begin
262
            MainForm.Left := VolumeYLeft;
263
            MainForm.Top := VolumeYTop;
264
          end;
265
          with fxValueForm do
266
          begin
267
            MainForm.Left := fxLeft;
268
            MainForm.Top := fxTop;
269
          end;
270
          with fx1ValueForm do
271
          begin
272
            MainForm.Left := fx1Left;
273
            MainForm.Top := fx1Top;
274
          end;
275
          with fx2ValueForm do
276
          begin
277
            MainForm.Left := fx2Left;
278
            MainForm.Top := fx2Top;
279
          end;
280
        end;
281
      end;
282
    except
283
      MessageDlg('File Error! An Error has occurred when attempting to read'+
284
           #13#10'"'+LayoutFName+'".'+
285
           #13#10'The default layout will be used.',
286
           mtError, [mbOK], 0);
287
      DefaultLayout;
288
    end;
289
  end
290
  else DefaultLayout;
291
  if DataPath = '' then DataPath := BinPath + 'Examples\';
292
  if ImagePath = '' then ImagePath := BinPath + 'Images\';
293
  if not DirectoryExists(DataPath) then ForceDirectories(DataPath);
294
  if not DirectoryExists(ImagePath) then ForceDirectories(ImagePath);
295

296
  if PrinterExists then
297
  begin
298
    SetPrinterInfo(PrinterInfo);
299
    GetPrinterInfo(PrinterInfo);
300
    if PrinterInfo.Orientation = poPortrait
301
    then StatusBar.Panels[1].Text :=
302
         '  '+Printer.Printers[PrinterInfo.Index]+'  '+GetPaperType +
303
         ', Portrait.'
304
    else StatusBar.Panels[1].Text :=
305
         '  '+Printer.Printers[PrinterInfo.Index]+'  '+GetPaperType +
306
         ', Landscape.';
307
  end
308
  else
309
  begin
310
    Print1.Enabled := false;   // disabled if no printer
311
    SetupPrinter1.Enabled := false;
312
    StatusBar.Panels[1].Text := 'No printer was found.';
313
  end;
314

315
  Caption := GraphFName;
316
  KeepRange := false;
317
  FunctionsForm.Show;
318
  Altered := false;
319
end;
320

321
procedure TMainForm.FormCloseQuery(Sender: TObject; var CanClose: Boolean);
322
var
323
  f: File of TLayout;
324

325
begin
326
  with Layout do
327
  begin
328
    IsMaximize := WindowState = wsMaximized;
329
    MainLeft := Left;
330
    MainTop := Top;
331
    MainWidth := Width;
332
    MainHeight := Height;
333
    CurrentGraphFName := GraphFName;
334
    CurrentDataPath := DataPath;
335
    CurrentImagePath := ImagePath;
336
    CurrentPrinterInfo := PrinterInfo;
337
    GridsVisible := GridOptionsForm.Visible;
338
    with GridOptionsForm do
339
    begin
340
      GridsLeft := Left;
341
      GridsTop := Top;
342
    end;
343

344
    NumericVisible := NumericForm.Visible;
345
    with NumericForm do
346
    begin
347
      NumericLeft := Left;
348
      NumericTop := Top;
349
    end;
350

351
    with NumericForm do if Visible then
352
    begin
353
      if (DataListBox.Count = 0) and (CheckListBox.Count > 0)
354
      then DeleteButtonClick(Sender);
355
      FunctionsForm.CoordPointButton.Visible := False;
356
    end;
357

358
    TextVisible := TextBlocksForm.Visible;
359
    with TextBlocksForm do
360
    begin
361
      TextLeft := Left;
362
      TextTop := Top;
363
      TextWidth := Width;
364
      TextHeight := Height;
365
    end;
366
    with FunctionsForm do
367
    begin
368
      FuncLeft := Left;
369
      FuncTop := Top;
370
    end;
371
    with DerivativeForm do
372
    begin
373
      DerivLeft := Left;
374
      DerivTop := Top;
375
    end;
376
    with IntegrateXForm do
377
    begin
378
      IntegXLeft := Left;
379
      IntegXTop := Top;
380
    end;
381
    with IntegrateYForm do
382
    begin
383
      IntegYLeft := Left;
384
      IntegYTop := Top;
385
    end;
386
    with BetweenForm do
387
    begin
388
      BetweenLeft := Left;
389
      BetweenTop := Top;
390
    end;
391
    with VolumeXForm do
392
    begin
393
      VolumeXLeft := Left;
394
      VolumeXTop := Top;
395
    end;
396
    with VolumeYForm do
397
    begin
398
      VolumeYLeft := Left;
399
      VolumeYTop := Top;
400
    end;
401
    with fxValueForm do
402
    begin
403
      fxLeft := Left;
404
      fxTop := Top;
405
    end;
406
    with fx1ValueForm do
407
    begin
408
      fx1Left := Left;
409
      fx1Top := Top;
410
    end;
411
    with fx2ValueForm do
412
    begin
413
      fx2Left := Left;
414
      fx2Top := Top;
415
    end;
416
  end;
417

418
  try
419
    AssignFile(f, LayoutFName);
420
    try
421
      Rewrite(f);
422
      write(f, Layout);
423
    finally
424
      CloseFile(f);
425
    end;
426
  except
427
    MessageDlg('File Error! An Error has occurred'+
428
         #13#10'when attempting to write to "'+LayoutFName+'".',
429
    mtError, [mbOK], 0);
430
  end;
431

432
  if Altered then
433
  begin
434
    case MessageDlg('The current graph data has been altered.'+
435
              #13#10'Do you wish to save the alterations ?', mtConfirmation,
436
                    [mbYes, mbNo, mbCancel], 0) of
437
    mrYes: FunctionsForm.SaveClick(Sender);
438
 mrCancel: begin
439
             CanClose := false;
440
             Exit;
441
           end;
442
    end;
443
  end;
444
end;
445

446
procedure TMainForm.FormKeyDown(Sender: TObject; var Key: Word;
447
                                 Shift: TShiftState);
448
var
449
  x, y, r: extended;
450

451
begin
452
  with GraphData.Grid do
453
  if (xAxisStyle = asLog) or (yAxisStyle = asLog) then exit;
454
  case Key of
455
//VK_F2:ShowAbout;
456
  VK_ESCAPE:
457
    if (MessageDlg('Do you wish to close the applicsation?',
458
                    mtConfirmation, [mbYes, mbNo], 0) = mrYes)
459
    then ExitAppClick(Sender);
460
  VK_LEFT, VK_NUMPAD4:
461
    begin
462
      Screen.Cursor := crMoveLeft;
463
      with GraphData do
464
      begin
465
        x := (xMax - xMin)/dMove;
466
        xMin := xMin + x;
467
        xMax := xMax + x;
468
      end;
469
      UpdateGridXRange;
470
      Altered := true;
471
      if dMove > 1 then dec(dMove, dMove div 16);
472
      GLViewer.Invalidate;
473
      Key := 0;
474
    end;
475
  VK_RIGHT, VK_NUMPAD6:
476
    begin
477
      Screen.Cursor := crMoveRight;
478
      with GraphData do
479
      begin
480
        x := (xMax - xMin)/dMove;
481
        xMin := xMin - x;
482
        xMax := xMax - x;
483
      end;
484
      UpdateGridXRange;
485
      Altered := true;
486
      if dMove > 1 then dec(dMove, dMove div 16);
487
      GLViewer.Invalidate;
488
      Key := 0;
489
    end;
490
  VK_UP, VK_NUMPAD8:
491
    begin
492
      Screen.Cursor := crMoveUp;
493
      with GraphData do
494
      begin
495
        y := (yMax - yMin)/dMove;
496
        yMin := yMin - y;
497
        yMax := yMax - y;
498
      end;
499
      UpdateGridYRange;
500
      Altered := true;
501
      if dMove > 1 then dec(dMove, dMove div 16);
502
      GLViewer.Invalidate;
503
      Key := 0;
504
    end;
505
  VK_DOWN, VK_NUMPAD2:
506
    begin
507
      Screen.Cursor := crMoveDown;
508
      with GraphData do
509
      begin
510
        y := (yMax - yMin)/dMove;
511
        yMin := yMin + y;
512
        yMax := yMax + y;
513
      end;
514
      UpdateGridYRange;
515
      Altered := true;
516
      if dMove > 1 then dec(dMove, dMove div 16);
517
      GLViewer.Invalidate;
518
      Key := 0;
519
    end;
520
  VK_ADD:  // zoom in
521
    begin
522
      Screen.Cursor := crZoom;
523
      with GraphData do
524
      begin
525
        x := (xMax - xMin)/dMove;
526
        xMin := xMin + x;
527
        xMax := xMax - x;
528

529
        y := (yMax - yMin)/dMove;
530
        yMin := yMin + y;
531
        yMax := yMax - y;
532
      end;
533
      UpdateGridXRange;
534
      UpdateGridYRange;
535
      Altered := true;
536
      if dMove > 1 then dec(dMove, dMove div 16);
537
      GLViewer.Invalidate;
538
      Key := 0;
539
    end;
540
  VK_SUBTRACT:  // zoom out
541
    begin
542
      Screen.Cursor := crZoom;
543
      x := (GraphData.xMax - GraphData.xMin)/dMove;
544
      GraphData.xMin := GraphData.xMin - x;
545
      GraphData.xMax := GraphData.xMax + x;
546

547
      y := (GraphData.yMax - GraphData.yMin)/dMove;
548
      GraphData.yMin := GraphData.yMin - y;
549
      GraphData.yMax := GraphData.yMax + y;
550
      UpdateGridXRange;
551
      UpdateGridYRange;
552
      Altered := true;
553
      if dMove > 1 then dec(dMove, dMove div 16);
554
      GLViewer.Invalidate;
555
      Key := 0;
556
    end;
557
  VK_HOME, VK_NUMPAD7:
558
    begin
559
      x := (GraphData.xMax - GraphData.xMin)/2;
560
      GraphData.xMin := -x;
561
      GraphData.xMax :=  x;
562
      y := (GraphData.yMax - GraphData.yMin)/2;
563
      GraphData.yMin := -y;
564
      GraphData.yMax :=  y;
565
      UpdateGridXRange;
566
      UpdateGridYRange;
567
      Altered := true;
568
      GLViewer.Invalidate;
569
      Key := 0;
570
    end;
571
  12, VK_NUMPAD5:  // eual grid
572
    begin
573
      with GraphData do
574
      begin
575
        x := xMax - xMin;
576
        y := yMax - yMin;
577
        r := (x*MainForm.GLViewer.Height)/(y*Mainform.GLViewer.Width);
578

579
        if x > y then
580
        begin
581
          if Shift = [ssCtrl] then
582
          begin
583
            xMax := yMax;
584
            xMin := yMin;
585
          end
586
          else
587
          begin
588
            yMax := yMax*r;
589
            yMin := yMin*r;
590
          end;
591
        end
592
        else
593
        begin
594
          if Shift = [ssCtrl] then
595
          begin
596
            yMax := xMax;
597
            yMin := xMin;
598
          end
599
          else
600
          begin
601
            xMax := xMax/r;
602
            xMin := xMin/r;
603
          end;
604
        end;
605
      end;
606
      UpdateGridXRange;
607
      UpdateGridYRange;
608
      Altered := true;
609
      GLViewer.Invalidate;
610
      Key := 0;
611
    end;
612
  end;
613
end;
614

615
procedure TMainForm.FormKeyUp(Sender: TObject; var Key: Word;
616
                              Shift: TShiftState);
617
begin
618
  Screen.Cursor := crDefault;
619
  dMove := $200;
620
end;
621

622
procedure TMainForm.FormMouseWheel(Sender: TObject; Shift: TShiftState;
623
          WheelDelta: Integer; MousePos: TPoint; var Handled: Boolean);
624
var
625
  d: integer;
626
  x, y: extended;
627

628
begin
629
  with GraphData.Grid do
630
  if (xAxisStyle = asLog) or (yAxisStyle = asLog) then exit;
631
// WheelDelta is negative when wheel is rotated toward user, i.e. Zoom in.
632
  d := -WheelDelta div 2;
633
  if Shift = [ssShift] then d := d div 4
634
  else if Shift = [ssCtrl] then d := d div 2;
635

636
  with GraphData do
637
  begin
638
    x := (xMax - xMin)/d;
639
    xMin := xMin + x;
640
    xMax := xMax - x;
641

642
    y := (yMax - yMin)/d;
643
    yMin := yMin + y;
644
    yMax := yMax - y;
645
  end;
646
  UpdateGridXRange;
647
  UpdateGridYRange;
648
  Altered := true;
649
  GLViewer.Invalidate;
650
end;
651

652
procedure TMainForm.GLViewerDragOver(Sender, Source: TObject; X, Y: Integer;
653
                                     State: TDragState; var Accept: Boolean);
654
begin
655
  Accept := Source = Sender;
656
  if Accept then with GraphData, PlotData do
657
  begin
658
    with Grid do
659
    begin
660
      if xAxisStyle = asLog
661
      then xLabel := ValueLogX(X)
662
      else xLabel := ValueX(X);
663

664
      if yAxisStyle = asLog
665
      then yLabel := ValueLogY(Y)
666
      else yLabel := ValueY(Y);
667
    end;
668

669
    FunctionsForm.EditLocX.Text := FloatToStrF(xLabel, ffNumber, 4, 3);
670
    FunctionsForm.EditLocY.Text := FloatToStrF(yLabel, ffNumber, 4, 3);
671
    ShowXYvalues(xLabel, yLabel);
672
  end;
673
end;
674

675
procedure TMainForm.GLViewerEndDrag(Sender, Target: TObject; X, Y: Integer);
676
begin
677
  if Target = Sender then  // end of drag
678
  with FunctionsForm.CheckListBox,
679
       TPlotDataObject(Items.Objects[ItemIndex]).Data do
680
  begin
681
    with GraphData.Grid do
682
    begin
683
      if xAxisStyle = asLog
684
      then xLabel := ValueLogX(X)
685
      else xLabel := ValueX(X);
686

687
      if yAxisStyle = asLog
688
      then yLabel := ValueLogY(Y)
689
      else yLabel := ValueY(Y);
690
    end;
691

692
    Altered := true;
693
    GLViewer.Invalidate;
694
  end;
695
end;
696

697
procedure TMainForm.GLViewerMouseDown(Sender: TObject; Button: TMouseButton;
698
                                       Shift: TShiftState; X, Y: Integer);
699
var
700
  dx, dy: extended;
701

702
begin
703
  if Shift = [ssLeft] then          // drag only if left button pressed
704
  with Sender as TGLSceneViewer do  // treat Sender as TGLSceneViewer
705
  begin
706
    if (X >= LabelRect.Left ) and (X <= LabelRect.Right) and
707
       (Y >= LabelRect.Top) and (Y <= LabelRect.Bottom)
708
    then BeginDrag(false) else Screen.Cursor := crHandMove;
709
  end
710
  else if (GraphData.Grid.xAxisStyle <> asLog) and
711
          (GraphData.Grid.yAxisStyle <> asLog) and
712
          (Shift = [ssLeft, ssAlt]) then
713
  begin         // reposition graph; set mouse location as graph center
714
    with GraphData do
715
    begin
716
      dx := (xMin + xMax)/2 - ValueX(X);
717
      dy := (yMin + yMax)/2 - ValueY(Y);
718
      xMin := xMin - dx;
719
      xMax := xMax - dx;
720
      yMin := yMin - dy;
721
      yMax := yMax - dy;
722
    end;
723
    UpdateGridXRange;
724
    UpdateGridYRange;
725
    Altered := true;
726
    GLViewer.Invalidate;
727
  end;
728
end;
729

730
procedure TMainForm.GLViewerMouseLeave(Sender: TObject);
731
begin
732
  oMousex := -1;
733
end;
734

735
procedure TMainForm.GLViewerMouseMove(Sender: TObject; Shift: TShiftState;
736
                                        X, Y: Integer);
737

738
  procedure IsAltered;
739
  begin
740
    UpdateGridXRange;
741
    UpdateGridYRange;
742
    Altered := true;
743
    GLViewer.Invalidate;
744
  end;
745

746
var
747
  xValue, yValue: extended;
748

749
begin
750
  xValue := 0;
751
  yValue := 0;
752

753
  if Active and (oMousex > -1) then
754
  begin
755
    if Shift = [ssLeft] then
756
    begin
757
      with GraphData do
758
      begin
759
        if Grid.xAxisStyle = asLog then
760
        begin // ratio of change to current value of x
761
          xValue := (ValueLogX(X) - ValueLogX(oMousex))/ValueLogX(X);
762
          xMin := xMin - xMin*xValue;
763
          xMax := xMax - xMax*xValue;
764
        end
765
        else
766
        begin
767
          xValue := ValueX(X) - ValueX(oMousex);
768
          xMax := xMax - xValue;
769
          xMin := xMin - xValue;
770
        end;
771

772
        if Grid.yAxisStyle = asLog then
773
        begin // ratio of change to current value of y
774
          yValue := (ValueLogY(Y) - ValueLogY(oMousey))/ValueLogY(Y);
775
          yMin := yMin - yMin*yValue;
776
          yMax := yMax - yMax*yValue;
777
        end
778
        else
779
        begin
780
          yValue := ValueY(Y) - ValueY(oMousey);
781
          yMax := yMax - yValue;
782
          yMin := yMin - yValue;
783
        end;
784
      end;
785
      IsAltered;
786
    end
787
    else
788
    if Shift = [ssLeft, ssCtrl] then
789
    begin
790
      Screen.Cursor := crSizeAll;
791

792
      if GraphData.Grid.xAxisStyle = asLog then
793
      begin
794
        xValue := (ValueLogX(X) - ValueLogX(oMousex))/ValueLogX(X);
795
        GraphData.xMin := GraphData.xMin + GraphData.xMin*xValue;
796
        GraphData.xMax := GraphData.xMax - GraphData.xMax*xValue;
797
      end
798
      else
799
      begin
800
        xValue := ValueX(X) - ValueX(oMousex);
801
        GraphData.xMin := GraphData.xMin + xValue;
802
        GraphData.xMax := GraphData.xMax - xValue;
803
      end;
804

805
      if GraphData.Grid.yAxisStyle = asLog then
806
      begin
807
        yValue := (ValueLogY(Y) - ValueLogY(oMousey))/ValueLogY(Y);
808
        GraphData.yMin := GraphData.yMin + GraphData.yMin*yValue;
809
        GraphData.yMax := GraphData.yMax - GraphData.yMax*yValue;
810
      end
811
      else
812
      begin
813
        yValue := ValueY(Y) - ValueY(oMousey);
814
        GraphData.yMin := GraphData.yMin + yValue;
815
        GraphData.yMax := GraphData.yMax - yValue;
816
      end;
817

818
      IsAltered;
819
    end;
820

821
    if GraphData.Grid.xAxisStyle = asLog then
822
      xValue := ValueLogX(X)
823
    else
824
      xValue := ValueX(X);
825

826
    if GraphData.Grid.yAxisStyle = asLog then
827
      yValue := ValueLogY(Y)
828
    else
829
      yValue := ValueY(Y);
830
  end;
831

832
  oMousex := X;
833
  oMousey := Y;
834

835
  ShowXYvalues(xValue, yValue);
836
end;
837

838
procedure TMainForm.GLViewerMouseUp(Sender: TObject; Button: TMouseButton;
839
                                     Shift: TShiftState; X, Y: Integer);
840
begin
841
  Screen.Cursor := crDefault;
842
end;
843

844
procedure TMainForm.NewClick(Sender: TObject);
845
begin
846
  FunctionsForm.NewClick(Sender);
847
end;
848

849
procedure TMainForm.OpenClick(Sender: TObject);
850
begin
851
  FunctionsForm.OpenClick(Sender);
852
end;
853

854
procedure TMainForm.SaveClick(Sender: TObject);
855
begin
856
  FunctionsForm.SaveClick(Sender);
857
end;
858

859
procedure TMainForm.SaveAsClick(Sender: TObject);
860
begin
861
  FunctionsForm.SaveAsClick(Sender);
862
end;
863

864
procedure TMainForm.SaveBMPfile1Click(Sender: TObject);
865
begin
866
  BitmapForm := TBitmapForm.Create(Application);
867
  if FunctionsForm.CheckListBox.Count > 1 then
868
    BitmapForm.Caption := '   Save graphs as ''' +
869
      ChangeFileExt(GraphFName, '.bmp''')
870
  else
871
    BitmapForm.Caption := '   Save graph as ''' +
872
      ChangeFileExt(GraphFName, '.bmp''');
873
  BitmapForm.ShowModal;
874
  BitmapForm.Free;
875
  BitmapForm := nil;
876
end;
877

878
procedure TMainForm.SaveJPGfile1Click(Sender: TObject);
879
begin
880
  BitmapForm := TBitmapForm.Create(Application);
881
  if FunctionsForm.CheckListBox.Count > 1 then
882
    BitmapForm.Caption := '   Save graphs as ''' +
883
      ChangeFileExt(GraphFName, '.jpg''')
884
  else
885
    BitmapForm.Caption := '   Save graph as ''' +
886
      ChangeFileExt(GraphFName, '.jpg''');
887
  BitmapForm.ShowModal;
888
  BitmapForm.Free;
889
  BitmapForm := nil;
890
end;
891

892
procedure TMainForm.Print1Click(Sender: TObject);
893
begin
894
  PrintForm := TPrintForm.Create(Application);
895
  PrintForm.Caption := '   Print '''+ GraphFName+'''.';
896
  PrintForm.ShowModal;
897
  PrintForm.Free;
898
  PrintForm := nil;
899
end;
900

901
procedure TMainForm.SetupPrinter1Click(Sender: TObject);
902
begin
903
  if PrinterSetupDialog.Execute then
904
  begin
905
    GetPrinterInfo(PrinterInfo);
906
    if PrinterInfo.Orientation = poPortrait
907
    then StatusBar.Panels[1].Text :=
908
         '  '+Printer.Printers[PrinterInfo.Index]+'  '+GetPaperType +
909
         ', Portrait.'
910
    else StatusBar.Panels[1].Text :=
911
         '  '+Printer.Printers[PrinterInfo.Index]+'  '+GetPaperType +
912
         ', Landscape.';
913
  end;
914
end;
915

916
procedure TMainForm.DefaultLayout1Click(Sender: TObject);
917
begin
918
  DefaultLayout;
919
end;
920

921
procedure TMainForm.ExitAppClick(Sender: TObject);
922
begin
923
  Close;
924
end;
925

926
procedure TMainForm.GridOptions1Click(Sender: TObject);
927
begin
928
  if not GridOptionsForm.Visible then
929
    GridOptionsForm.Show;
930
end;
931

932
procedure TMainForm.NumGraphsClick(Sender: TObject);
933
begin
934
  if not NumericForm.Visible then
935
  begin
936
    NumericForm.Show;
937
    NumericForm.CheckListBoxClick(Sender); // updates NumericForm.DataListBox
938
  end;
939
end;
940

941
procedure TMainForm.Texts1Click(Sender: TObject);
942
begin
943
  if not TextBlocksForm.Visible then
944
    TextBlocksForm.Show;
945
end;
946

947
procedure TMainForm.SelectStyle1Click(Sender: TObject);
948
begin
949
  StyleNameForm := TStyleNameForm.Create(Application);
950
  StyleNameForm.Selecting := true;
951
  StyleNameForm.ShowModal;
952
  StyleNameForm.Free;
953
  StyleNameForm := nil;
954
  Altered := true;
955
(*
956
NewFont needed to initialize GLWinFont.GetCharWidth
957
  if the font has been altered, which may or may not be the case,
958
  so do it anyway
959
*)
960
  NewFont := true;
961
  GLViewer.Invalidate;
962
end;
963

964
procedure TMainForm.SaveStyle1Click(Sender: TObject);
965
begin
966
  StyleNameForm := TStyleNameForm.Create(Application);
967
  StyleNameForm.Selecting := false;
968
  StyleNameForm.ShowModal;
969
  StyleNameForm.Free;
970
  StyleNameForm := nil;
971
end;
972

973
procedure TMainForm.GLDirectOpenGLRender(Sender: TObject;
974
                                        var rci: TGLRenderContextInfo);
975
var
976
  fxCanvas: TfxCanvas;
977

978
begin
979
  fxCanvas := TfxCanvas.Create(GLViewer.Width, GLViewer.Height);
980
  try
981
    if NewFont then
982
    begin
983
      fxCanvas.SetGLWinBitFont(rci, GLWinBitFont, GraphData.FontName,
984
        GraphData.FontSize, GraphData.FontStyle);
985
      fxCanvas.SetupFont(rci, GLWinBitFont);
986
      NewFont := false;
987
    end;
988

989
    with fxCanvas do
990
    begin
991
      xAxisGradsCalc(GLWinBitFont);            // calculates graduations
992
      yAxisGradsCalc(GLWinBitFont);
993

994
      if GraphData.Grid.GridStyle > gsNone
995
      then DrawAxes;
996

997
      AddFunctionLabelsText;               // add the labels to text list
998
      DrawTextList(rci, TextList, GLWinBitFont);  // axes and labels text
999
      DrawFunctions;
1000
      DrawNumericData;
1001
      DrawTextBlocks(rci, GLWinBitFont);
1002
    end;
1003
  finally
1004
    fxCanvas.Free;
1005
  end;
1006
end;
1007

1008
procedure TMainForm.ShowXYvalues(const x, y: extended);
1009
var
1010
  sx, sy: string;
1011

1012
begin
1013
  sx := FloatToStrF(x, ffnumber, 16, 8);
1014
  sy := FloatToStrF(y, ffnumber, 16, 8);
1015
  StatusBar.Panels[0].Text := ' x : '+sx+', y : '+sy;
1016
end;
1017

1018
procedure TMainForm.UpdateGridXRange;
1019
begin
1020
  with GridOptionsForm do
1021
    if Visible then
1022
      begin
1023
        EditMinX.Text := FloatToStrF(GraphData.xMin, ffGeneral, 13, 4);
1024
        EditMaxX.Text := FloatToStrF(GraphData.xMax, ffGeneral, 13, 4);
1025
      end;
1026
end;
1027

1028
procedure TMainForm.About1Click(Sender: TObject);
1029
begin
1030
  FormAbout.Show
1031
(*
1032
  with TAboutForm.Create();
1033
  try
1034
    ShowModal;
1035
  finally
1036
    Free;
1037
  end;
1038
*)
1039
end;
1040

1041
procedure TMainForm.DefaultLayout;
1042
begin
1043
  MainForm.Left := 1;
1044
  MainForm.Top := 1;
1045
  MainForm.Width := Screen.Width - GridOptionsForm.Width - 10;
1046
  MainForm.Height := Screen.Height - 30;
1047
  FunctionsForm.Left := MainForm.Left + MainForm.Width + 5;
1048
  FunctionsForm.Top := MainForm.Top + 5;
1049
  GridOptionsForm.Left := FunctionsForm.Left;
1050
  GridOptionsForm.Top := FunctionsForm.Top + FunctionsForm.Height + 10;
1051
  GridOptionsForm.Show;
1052
  NumericForm.Top := 25;
1053
  NumericForm.Left := 25;
1054
  TextBlocksForm.Top := 75;
1055
  TextBlocksForm.Left := 75;
1056
end;
1057

1058
procedure TMainForm.UpdateGridYRange;
1059
begin
1060
  with GridOptionsForm do
1061
    if Visible then
1062
    begin
1063
      EditMinY.Text := FloatToStrF(GraphData.yMin, ffGeneral, 13, 4);
1064
      EditMaxY.Text := FloatToStrF(GraphData.yMax, ffGeneral, 13, 4);
1065
    end;
1066
end;
1067

1068
function TMainForm.ValueX(const x: integer): extended;
1069
begin
1070
  Result := GraphData.xMin + X * (GraphData.xMax - GraphData.xMin) / GLViewer.Width;
1071
end;
1072

1073
function TMainForm.ValueY(const y: integer): extended;
1074
begin
1075
  Result := GraphData.yMax + Y * (GraphData.yMin - GraphData.yMax) / GLViewer.Height;
1076
end;
1077

1078
function TMainForm.ValueLogX(const x: integer): extended;
1079
var
1080
  LogMin, a: extended;
1081

1082
begin
1083
  LogMin := Log10(GraphData.xMin);
1084
  a := LogMin + x*(Log10(GraphData.xMax) - LogMin)/GLViewer.Width;
1085
  Result := Power(10, a);
1086
end;
1087

1088
function TMainForm.ValueLogY(const y: integer): extended;
1089
var
1090
  LogMax, a: extended;
1091

1092
begin
1093
  LogMax := Log10(GraphData.yMax);
1094
  a := LogMax + y*(Log10(GraphData.yMin) - LogMax)/GLViewer.Height;
1095
  Result := Power(10, a);
1096
end;
1097

1098
//------------------------------------------------------------------
1099
initialization
1100
//------------------------------------------------------------------
1101
  FormatSettings.DecimalSeparator := '.';
1102

1103
//------------------------------------------------------------------
1104
finalization
1105
//------------------------------------------------------------------
1106
//  return to FormatSettings.DecimalSeparator := ',';
1107

1108

1109
end.
1110

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.