Урок 58 График функции No title

January 25, 2007

в колонках играет Lara Fabian – Meu Grande Amor


Приветствую! После долгого отсутствия я вновь выхожу на сцену! Мы решили не ждать того момента, когда разъярённые читатели вычислят нас и дадут по е#@лу, и решили приободрить их новыми статьями…

Итак, в этот раз мы научимся делать программу, которая строит график функции y = 2sin(x)e^(x/5), но вы можете, конечно, использовать и любую другую функцию. Границы диапазона изменения аргумента функции являются исходными данными. Диапазон изменения значения функции вычисляется во время работы программы. На основании этих данных программа вычисляет масштаб, который позволяет построить график таким образом, чтобы он занимал всю область формы, предназначенную для его вывода. Если пользователь во время работы программы изменит размер окна, то график будет выведен заново с учётом новых размеров.



С приведённым ниже листингом недолжно возникнуть затруднений, так что действуй…
/*
График функции.
Демонстрирует:
- использование методов Line, MoveTo, TextOutA;
- обработку события OnFormResize
*/

#include
#include "math.h" // для доступа к sin и exp

#pragma hdrstop

#include "grf_.h"


#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;

__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}

void __fastcall TForm1::FormPaint(TObject *Sender)
{
Grafik();
}

// пользователь изменил размер окна
void __fastcall TForm1::FormResize(TObject *Sender)
{
TRect rct = Rect(0,0,ClientWidth,ClientHeight);

Canvas->FillRect(rct);
Grafik();
}

// функция, график которой надо построить
float f( float x)
{
return 2*sin(x)*exp(x/5);
}

void TForm1::Grafik()
{
float x1, x2; // границы изменения аргумента функции
float y1, y2; // границы изменения значения функции
float x; // аргумент функции
float y; // значение функции в точке x
float dx; // приращение аргумента
int l,b; // левый нижний угол области вывода графика
int w, h; // ширина и высота области вывода графика
float mx, my; // масштаб по осям X и Y
int x0, y0; // начало координат

// область вывода графика
l = 10; // X - координата левого верхнего угла
b = Form1->ClientHeight-20; // Y - координата левого нижнего угла
h = Form1->ClientHeight-40; // высота
w = Form1->Width - 20; // ширина


x1 = 0; // нижняя граница диапазона аргумента
x2 = 25; // верхняя граница диапазона аргумента
dx = 0.01; // шаг аргумента

// найдем максимальное и минимальное значение
// функции на отрезке [x1,x2]

x = x1;
y1 = f(x); // минимум
y2 = f(x); // максимум
do {
y = f(x);
if ( y < y1 ) y1 = y;
if ( y > y2 ) y2 = y;
x += dx;
} while (x <= x2);


// вычислим масштаб
my = (float)h/abs(y2-y1); // масштаб по оси Y
mx = w/abs(x2-x1); // масштаб по оси X


// оси
x0 = l+abs(x1*mx);
y0 = b-abs(y1*my);
Canvas->MoveTo(x0,b);Canvas->LineTo(x0,b-h);
Canvas->MoveTo(l,y0);Canvas->LineTo(l+w,y0);
Canvas->TextOutA(x0+5,b-h,FloatToStrF(y2,ffGeneral,6,3));
Canvas->TextOutA(x0+5,b,FloatToStrF(y1,ffGeneral,6,3));


// построение графика
x = x1;
do {
y = f(x);
Canvas->Pixels[x0+x*mx][y0-y*my] = clRed;
x += dx;
} while (x <= x2);
}

Не забудь добавить в модуль (*.h) прототип функции Grafik() в секцию private:
void Grafik();



Эта программа универсальна. Заменив инструкции в теле функции f(x) , можно поучить график другой функции. Причём независимо от её вида, график будет занимать всю область, предназначенную для вывода. Только не следует забывать, что если функция во всём диапазоне только положительная или только отрицательная, то в программу необходимо внести изменения. Какие – пусть это будет для тебя упражнением. Если что-то непонятно, обращайтесь по адресу 666klaus@rambler.ru.



Материал подготовил - Klaus, 2007
www.builderhelper.org
builder.helper@rambler.ru