Консультация № 177908
17.04.2010, 21:46
0.00 руб.
0 3 1
Здравствуйте!!!
Помогите,пожалуйста,построить график функции по точкам
(в проекте должна отрисовываться координатная сетка, и на ней график строго определенными координатами сетки). При изменении размеров окна график тоже должен перерисовываться вместе с сеткой
Координат построения графика может быть сколько угодно до 25 (т.е. должна быть возможность задать кол-во точек)

Спасибо!

Обсуждение

Неизвестный
18.04.2010, 13:30
общий
Миронычев Виталий:
Вам нужно рисовать график и сетку в ручную?
Если нет, то на панели Additional есть готовый компонент Chart.
Неизвестный
18.04.2010, 15:09
общий
Patriotix-N:
Необходима ручная прорисовка
Неизвестный
19.04.2010, 04:09
общий
это ответ
Здравствуйте, Миронычев Виталий.

Решение (pas и dfm) в приложении.

Приложение:
//pas
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Grids, ExtCtrls;

type
TForm1 = class(TForm)
Panel1: TPanel;
Image1: TImage;
Panel2: TPanel;
StringGrid1: TStringGrid;
Panel3: TPanel;
Button1: TButton;
Edit1: TEdit;
Label1: TLabel;
Button2: TButton;
procedure axes;
procedure graph;
procedure Panel3Resize(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Panel1Resize(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure StringGrid1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

const
field = 36;
step = 50;
pointRad = 5;
var
Form1: TForm1;
scaleX, scaleY: single;

implementation

{$R *.dfm}

procedure TForm1.axes;
var
rowsCount, colsCount: Byte;
startX, startY: Word;
i: Byte;
begin
rowsCount := Trunc((Panel1.Height - 2 * field) / step);
colsCount := Trunc((Panel1.Width - 2 * field) / step);
if rowsCount mod 2 = 1 then Dec(rowsCount);
if colsCount mod 2 = 1 then Dec(colsCount);
startX := Round((Image1.Width - colsCount * step) / 2);
startY := Round((Image1.Height - rowsCount * step) / 2);

Image1.Canvas.Pen.Width := 1;
Image1.Canvas.Pen.Color := clBlack;
Image1.Canvas.Brush.Color := clWhite;
for i := 0 to rowsCount do begin
Image1.Canvas.MoveTo(field, startY + i * step);
Image1.Canvas.LineTo(Image1.Width - field, startY + i * step);
Image1.Canvas.TextOut(Round(Image1.Width / 2) + 5,
startY + i * step + 5,
IntToStr(Round((startY + i * step - Image1.Height / 2) * -scaleY)));
end;
for i := 0 to colsCount do begin
Image1.Canvas.MoveTo(startX + i * step, field);
Image1.Canvas.LineTo(startX + i * step, Image1.Height - field);
Image1.Canvas.TextOut(startX + i * step + 5,
Round(Image1.Height / 2) + 5,
IntToStr(Round((startX + i * step - Image1.Width / 2) * scaleX)));
end;

Image1.Canvas.Pen.Width := 5;
Image1.Canvas.MoveTo(field, Round(Image1.Height / 2));
Image1.Canvas.LineTo(Image1.Width - field, Round(Image1.Height / 2));
Image1.Canvas.MoveTo(Round(Image1.Width / 2), field);
Image1.Canvas.LineTo(Round(Image1.Width / 2), Image1.Height - field);
end;

procedure TForm1.graph;
var
i: Byte;
minX, minY, maxX, maxY: Integer;
ofsX, ofsY: Integer;
begin
if (Image1.Height / 2 - field = 0) or (Image1.Width / 2 - field = 0) then
Exit;

for i := 0 to StringGrid1.RowCount - 1 do begin
if StringGrid1.Cells[0, i] = '' then StringGrid1.Cells[0, i] := '0';
if StringGrid1.Cells[1, i] = '' then StringGrid1.Cells[1, i] := '0';
if (StringGrid1.Cells[0, i] = '-') or
(StringGrid1.Cells[1, i] = '-') then Exit;
end;;

minX := StrToInt(StringGrid1.Cells[0, 0]);
maxX := StrToInt(StringGrid1.Cells[0, 0]);
minY := StrToInt(StringGrid1.Cells[1, 0]);
maxY := StrToInt(StringGrid1.Cells[1, 0]);
for i := 1 to StringGrid1.RowCount - 1 do begin
if minX > StrToInt(StringGrid1.Cells[0, i]) then
minX := StrToInt(StringGrid1.Cells[0, i]);
if maxX < StrToInt(StringGrid1.Cells[0, i]) then
maxX := StrToInt(StringGrid1.Cells[0, i]);
if minY > -StrToInt(StringGrid1.Cells[1, i]) then
minY := -StrToInt(StringGrid1.Cells[1, i]);
if maxY < -StrToInt(StringGrid1.Cells[1, i]) then
maxY := -StrToInt(StringGrid1.Cells[1, i]);
end;

Image1.Picture.Bitmap.FreeImage();
Image1.Picture.Bitmap := nil;

if (maxX - minX = 0) or (maxY - minY = 0) then Exit;

if Abs(minX) > Abs(maxX) then begin
scaleX := Abs(minX) / (Image1.Width / 2 - field);
ofsX := field - Round(minX / scaleX);
end
else begin
scaleX := Abs(maxX) / (Image1.Width / 2 - field);
ofsX := Image1.Width - field - Round((maxX) / scaleX);
end;
if Abs(minY) > Abs(maxY) then begin
scaleY := Abs(minY) / (Image1.Height / 2 - field);
ofsY := field - Round(minY / scaleY);
end
else begin
scaleY := Abs(maxY) / (Image1.Height / 2 - field);
ofsY := Image1.Height - field - Round((maxY) / scaleY);
end;

Image1.Canvas.Pen.Width := 2;
Image1.Canvas.Pen.Color := clGreen;
Image1.Canvas.MoveTo(Round((StrToInt(StringGrid1.Cells[0,0])) / scaleX) +
ofsX, Round((StrToInt(StringGrid1.Cells[1,0])) / -scaleY) + ofsY);
Image1.Canvas.Brush.Color := clGreen;
Image1.Canvas.Ellipse(Round((StrToInt(StringGrid1.Cells[0,0])) /
scaleX) + ofsX - pointRad,
Round((StrToInt(StringGrid1.Cells[1,0])) / -scaleY) + ofsY -
pointRad, Round((StrToInt(StringGrid1.Cells[0,0])) / scaleX) +
ofsX + pointRad, Round((StrToInt(StringGrid1.Cells[1,0])) /
-scaleY) + ofsY + pointRad);
for i := 1 to StringGrid1.RowCount - 1 do begin
Image1.Canvas.LineTo(Round((StrToInt(StringGrid1.Cells[0,i])) /
scaleX) + ofsX, Round((StrToInt(StringGrid1.Cells[1,i])) /
-scaleY) + ofsY);
Image1.Canvas.Ellipse(Round((StrToInt(StringGrid1.Cells[0,i])) /
scaleX) + ofsX - pointRad,
Round((StrToInt(StringGrid1.Cells[1,i])) / -scaleY) + ofsY -
pointRad, Round((StrToInt(StringGrid1.Cells[0,i])) / scaleX) +
ofsX + pointRad, Round((StrToInt(StringGrid1.Cells[1,i])) /
-scaleY) + ofsY + pointRad);
end;
end;

procedure TForm1.Panel3Resize(Sender: TObject);
begin
Button1.Left := Round((Panel3.Width - Button1.Width) / 2);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
i: Byte;
begin
for i := 0 to StringGrid1.RowCount - 1 do begin
StringGrid1.Cells[0, i] := IntToStr(Random(60000) - 30000);
StringGrid1.Cells[1, i] := IntToStr(Random(60000) - 30000);
end;

graph;
axes;
end;

procedure TForm1.Panel1Resize(Sender: TObject);
begin
graph;
axes;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
StringGrid1.RowCount := StrToInt(Edit1.Text);
end;

procedure TForm1.StringGrid1KeyUp(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
graph;
axes;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
Randomize;
end;

end.

//dfm
object Form1: TForm1
Left = 264
Top = 202
Width = 811
Height = 558
Caption = 'Form1'
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
PixelsPerInch = 96
TextHeight = 13
object Panel1: TPanel
Left = 0
Top = 0
Width = 671
Height = 520
Align = alClient
TabOrder = 0
OnResize = Panel1Resize
object Image1: TImage
Left = 1
Top = 1
Width = 669
Height = 518
Align = alClient
end
end
object Panel2: TPanel
Left = 671
Top = 0
Width = 124
Height = 520
Align = alRight
TabOrder = 1
object StringGrid1: TStringGrid
Left = 1
Top = 1
Width = 122
Height = 401
Align = alClient
ColCount = 2
DefaultColWidth = 50
FixedCols = 0
FixedRows = 0
Options = [goFixedVertLine, goFixedHorzLine, goVertLine, goHorzLine, goRangeSelect, goEditing]
TabOrder = 0
OnKeyUp = StringGrid1KeyUp
end
object Panel3: TPanel
Left = 1
Top = 402
Width = 122
Height = 117
Align = alBottom
TabOrder = 1
object Label1: TLabel
Left = 16
Top = 8
Width = 90
Height = 13
Caption = #1050#1086#1083#1080#1095#1077#1089#1090#1074#1086' '#1090#1086#1095#1077#1082
end
object Button1: TButton
Left = 8
Top = 48
Width = 105
Height = 25
Caption = #1055#1088#1080#1085#1103#1090#1100
TabOrder = 0
OnClick = Button1Click
end
object Edit1: TEdit
Left = 8
Top = 24
Width = 105
Height = 21
TabOrder = 1
Text = '5'
end
object Button2: TButton
Left = 8
Top = 80
Width = 105
Height = 25
Caption = #1057#1083#1091#1095#1072#1081#1085#1099#1077' '#1090#1086#1095#1082#1080
TabOrder = 2
OnClick = Button2Click
end
end
end
end
5
Спасибо вам огромное за труд!!!
Форма ответа