Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.04.2011, 18:56   #1
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию График функции

В общем-то, нужно построить график функции(функция задана, y = a/(x*x-b*x)), в Image, заданы XMin,XMax,A,B. У меня почему-то не получается, не могу понять что именно. Возможно, кто-нибудь поможет мне.
Код:
unit Unit1;

interface

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

type
  TForm1 = class(TForm)
    GroupBox1: TGroupBox;
    Edit1: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Edit2: TEdit;
    Label3: TLabel;
    Edit3: TEdit;
    Edit4: TEdit;
    Label4: TLabel;
    Button1: TButton;
    XPManifest1: TXPManifest;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure DrawNumber(Y:Integer;T:Double); // OK
    procedure FindMin;   // OK
    procedure FindMax;   // OK
    procedure CalcFunc;  // OK
    procedure DrawAxes;  // OK
   // procedure DrawGraph;
  end;

var
  Form1: TForm1;
  BreakP : array[1..20] of Boolean;
  Points : array[1..20] of Double;
  XMin , XMax,
  YMin , YMax,
     A ,    B : Double;

implementation

{$R *.dfm}

procedure TForm1.DrawNumber(Y:Integer;T:Double);
begin
      With Image1 Do
      Begin
            Canvas.TextOut(Width div 2+10,Y,FloatToStrF(T,ffFixed,3,2));
      End;
end;

procedure TForm1.FindMin;
var
    i : Integer;
begin
      YMin:=Points[1];
      For i:=2 To 20 Do
      Begin
            If Points[i]<YMin Then
            YMin:=Points[i];
      End;
end;

procedure TForm1.FindMax;
var
    i : Integer;
begin
      YMax:=Points[1];
      For i:=2 To 20 Do
      Begin
            If Points[i]>YMax Then
            YMax:=Points[i];
      End;
end;

procedure TForm1.CalcFunc;
var
    i : Integer;
    x , sh : Double;
begin
      x:=XMin;
      sh:=(XMax-XMin)/20;
      for i:=1 to 20 do
      begin
            try
                Points[i]:=A/(Sqr(X)-B*X);
            except
                BreakP[i]:=True;
            end;
            x:=x+sh;
      end;
end;

procedure TForm1.DrawAxes;
var i : Integer;x,y,sh:Double;
    a,b:Integer;
begin
      With Image1 Do
      Begin
            Canvas.MoveTo(Width div 2,20);
            Canvas.LineTo(Width div 2,Height-20);
            Canvas.MoveTo(20,Height div 2);
            Canvas.LineTo(Width-20,Height div 2);
      End;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
      try
          XMin:=StrToFloat(Edit1.Text);
          XMax:=StrToFloat(Edit2.Text);
          A:=StrToFloat(Edit3.Text);
          B:=StrToFloat(Edit4.Text);
          CalcFunc;
          FindMin;
          FindMax;
          ShowMessage('YMin = '+FloatToStr(YMin));
          ShowMessage('YMax = '+FloatToStr(YMax));
      except
          ShowMessage('Введите все параметры!');
      end;
      DrawAxes;
end;

end.
Вернее сказать, я не знаю, как нарисовать график. Т.е. я вычислил значения функции на интервале [XMin,XMax]. Но ведь они не всегда будут совпадать с системой координат Image1.Canvas, т.к. они будут слишком большими или слишком маленькими.
_-Re@l-_ вне форума Ответить с цитированием
Старый 12.04.2011, 20:47   #2
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

т.к. функция монотонно убывающая, можно обойтись малой кровью:

Код:
procedure TForm1.PaintBox1Paint(Sender: TObject);
var
  x, y, dx, xmin, xmax, ymax, ymin, a, b: double;
  h, w: Integer;
  r: TRect;
begin
  a := 1;
  b := 2;
  xmin := 3;
  xmax := 20;
  //
  ymax :=  a / (xmin * xmin - b * xmin);
  ymin :=  a / (xmax * xmax - b * xmax);
  //
  h := PaintBox1.Height;
  w := PaintBox1.Width;
  //
  dx := (xmax - xmin) / w;
  //
  r := PaintBox1.BoundsRect;
  //
  with PaintBox1.Canvas do try
    //
    Lock();
    Brush.Color := clBlack;
    FillRect(R);
    //
    x := xmin;
    while (x <= xmax) do begin
      //
      y := a / (x * x - b * x);
      //
      Pixels[trunc((x - xmin) / xmax * w), h - trunc((y - ymin) / ymax * h)] := clRed;
      //
      x := x + dx;
    end;
    //
  finally
    Unlock();
  end;
end;
В общем случае можно прикинуть в вольфрамальфе отображаемый мин и макс по осям, и от них исходить.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."

Последний раз редактировалось veniside; 12.04.2011 в 20:50.
veniside вне форума Ответить с цитированием
Старый 12.04.2011, 20:48   #3
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Можно зная MAX и MIN функции на заданном отрезке вычислить масштабирующий множитель исходя из размеров канвы по вертикали и растягивать (или сжимать) график функции в этом направлении. Т.е. по оси X приращение аргумента соответствует одному или нескольким пикселям, а по оси Y значение функции отображать с масштабированием. Собственно и ось X по вертикали тоже можно размещать с неким смещением исходя из MAX и MIN функции
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 12.04.2011 в 20:50.
Аватар вне форума Ответить с цитированием
Старый 16.04.2011, 12:40   #4
_-Re@l-_
C++, Java
Старожил
 
Аватар для _-Re@l-_
 
Регистрация: 10.04.2010
Сообщений: 2,665
По умолчанию

Ага, ясно, принял к сведению.
Всё-таки решил делать через Image, в общем-то, что уже вырисовывается, вот код(существенная часть)...
Код:
 procedure FindMinAndMax;
  end;

var
  Form1: TForm1;
  Min , Max : Double;

implementation

{$R *.dfm}


procedure TForm1.FindMinAndMax;
var
    i : Integer;
    t : Double;
begin
      Min:=High(Integer);
      Max:=Low(Integer);
      for i:=-100 to 100 do
      begin
            if i*i-2*i = 0 then continue;
            t:=10/(i*i-2*i);
            if t > Max then max:=t;
            if t < Min then min:=t;
      end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var i , y , x: Integer;
begin
      FindMinAndMax;
      Image1.Canvas.Brush.Color:=clBlue;
      for i:=-100 to 100 do
      begin
            if i*i-2*i = 0 then continue;
            y:=Round(10/(i*i-2*i));
            y:=Round(537*(y-Min)/(Max-Min));
            x:=Round(2.725*(i+100));
            Image1.Canvas.Pixels[x,y]:=clBlue;
      end;
end;
В чём мои ошибки?
_-Re@l-_ вне форума Ответить с цитированием
Старый 16.04.2011, 14:30   #5
Аватар
Старожил
 
Аватар для Аватар
 
Регистрация: 17.11.2010
Сообщений: 18,922
По умолчанию

Код:
procedure TForm1.Button1Click(Sender: TObject);
var i,j: Integer;
    y,yMax,yMin,m: Real;
    XMin,XMax,A,B: Real;
function Calculate(X: Real): Real;
begin
  Result:=A/(X*X-B*X);
end;
begin
  XMin:=10.5;
  XMax:=33.45;
  A:=16.2;
  B:=4;
//на интервале [XMin,XMax] не должно быть нулей знаменателя, иначе шах и мат
//оси не отображены, могут и не попасть, если отображать додумай сам
//по хорошому их возможно отобразить если значения аргумента и функции не очень далеки от 0
//вычисл max min
  yMin:=Calculate(XMin);
  yMax:=yMin;
  for i:=1 to Image.Width-1 do begin
    y:=Calculate(XMin+(XMax-XMin)/Image.Width*i);
    if y<yMin then yMin:=y;
    if y>yMax then yMax:=y;
  end;
  m:=(yMax-yMin)/Image.Height; //масштаб множитель
//график
  for i:=0 to Image.Width-1 do begin
    y:=Calculate(XMin+(XMax-XMin)/Image.Width*i);
    j:=Round((y-yMin)/m);
    if j>Image.Height-1 then j:=Image.Height-1;
    if j<0 then j:=0;
    Image.Canvas.Pixels[i,Image.Height-1-j]:=clBlue;
  end;
end;
Если бы архитекторы строили здания так, как программисты пишут программы, то первый залетевший дятел разрушил бы цивилизацию

Последний раз редактировалось Аватар; 16.04.2011 в 14:55.
Аватар вне форума Ответить с цитированием
Старый 16.04.2011, 17:10   #6
phomm
personality
Старожил
 
Аватар для phomm
 
Регистрация: 28.04.2009
Сообщений: 2,882
По умолчанию

http://www.cyberforum.ru/delphi-begi...ead122904.html очень доступный материал по автопостроению графика (с подгонкой масштаба и т.п.)
phomm вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
график функции Анюта01 Помощь студентам 6 01.04.2010 08:50
График функции dsf Общие вопросы C/C++ 4 17.12.2009 23:20
График функции. Bilargo Помощь студентам 0 09.11.2009 18:57
График функции russian-stalker Общие вопросы Delphi 2 30.09.2009 14:58
График функции Леха Общие вопросы Delphi 18 16.04.2007 20:50