Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Построение графиков фукций


Автор: vudu91 10.5.2009, 13:32
Пожалуйста  помогите ... очень нужно реализовать пограму построения графикик некоторых функций  за выбором пользователя.
для одной функции я нашел,переделал,  но как сделать так, чтобы функцию можно было менять пользователем незнаю.. уже кучу времени потратил.. все перерыл, ну незнаю... smile  smile 
Код


#include <vcl.h>
#pragma hdrstop

#include "GraphMain.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
    : TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Grafik(void)
{
    float x1, x2;
    float y1, y2;
    float x;
    float y;
    float dx;
    int l,b;
    int w, h;
    float mx, my;
    int x0, y0;

    l = 10;
    b = Form1->ClientHeight-20;
    h = Form1->ClientHeight-40;
    w = Form1->Width - 20;

    x1 = 0;
    x2 = 25;
    dx = 0.01;

    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);
    mx = w/abs(x2-x1);

    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);
}
//---------------------------------------------------------------------------
float __fastcall TForm1::f( float x)
{
   return 2*sin(x)*exp(x/5);
}
void __fastcall TForm1::FormResize(TObject *Sender)
{
    TRect rct = Rect(0,0,ClientWidth,ClientHeight);

    Canvas->FillRect(rct);
    Grafik();
}
//---------------------------------------------------------------------------
void __fastcall TForm1::FormPaint(TObject *Sender)
{
    Grafik();
}




#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <math.h>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
    void __fastcall FormResize(TObject *Sender);
    void __fastcall FormPaint(TObject *Sender);
        void __fastcall FormCreate(TObject *Sender);
private:    // User declarations
public:        // User declarations
    __fastcall TForm1(TComponent* Owner);
    void __fastcall Grafik(void);
    float __fastcall f(float x);
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif



очень нужно...помогите пожалуйста.

Автор: vudu91 10.5.2009, 17:44
 smile  smile  smile 

Автор: Dmi3ev 10.5.2009, 18:41
Цитата

чтобы функцию можно было менять пользователем незнаю.. уже кучу времени потратил.. все перерыл, ну незнаю... 

произвольно менять? какую пользователь придумает, такая и будет? или менять из нескольких уже существующих?  smile 

Автор: vudu91 10.5.2009, 19:05
ну зараз можно просто чтобы пользователь выбирал из списка, и просто ставил коэфициенты... например а*х^2 где а зпдает пользователь smile 

Автор: Dmi3ev 10.5.2009, 20:52
Цитата

например а*х^2 где а зпдает пользователь

Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
double f1(int x, double a)//вычисления
{
        return (x*x*a);
}
void TForm1::DrawMyF1()//рисуем саму функцию
{
        int a=StrToInt(Edit1->Text);
        int x=0;
        int y=0;
        this->Canvas->MoveTo(this->Width/2, this->Height/2);
        this->Canvas->Pen->Color=clRed;

        while (x>-(this->Width/2) && y<this->Height/2)
        {
                x--;
                y=f1(x, a);
                this->Canvas->LineTo(x+(this->Width/2), (this->Height/2)-y);
        }
        this->Canvas->MoveTo(this->Width/2, this->Height/2);
        x=0;
        y=0;
        while (x<(this->Width/2) && y<this->Height/2)
        {
                x++;
                y=f1(x, a);
                this->Canvas->LineTo(x+(this->Width/2), (this->Height/2)-y);
        }


}
void TForm1::Draw1()//оси рисуем
{
        this->Canvas->MoveTo(0, this->Height/2);
        this->Canvas->Pen->Color=clBlack;
        this->Canvas->LineTo(this->Width, this->Height/2);
        this->Canvas->MoveTo(this->Width/2, 0);
        this->Canvas->LineTo(this->Width/2, this->Height);

}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        Draw1();
        DrawMyF1();
}

Н-файл
Код

//---------------------------------------------------------------------------

#ifndef Unit1H
#define Unit1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
//---------------------------------------------------------------------------
class TForm1 : public TForm
{
__published:    // IDE-managed Components
        TEdit *Edit1;
        TButton *Button1;
        void __fastcall Button1Click(TObject *Sender);
private:    // User declarations
public:        // User declarations
        __fastcall TForm1(TComponent* Owner);
        void DrawMyF1();
        void Draw1();
};
//---------------------------------------------------------------------------
extern PACKAGE TForm1 *Form1;
//---------------------------------------------------------------------------
#endif

что-то вроде, если функций несколько, то можно организовать выбор через радио баттоны, или чекбокс, и в зависимости от выбора рисовать ту или иную...

Автор: vudu91 10.5.2009, 21:41
Dmi3ev,  большое спасибо smile 
а не подскажэш  как увеличить маштаб выводимого графика и отобразить его не на весь экран а у левый половине...???

Автор: Dmi3ev 10.5.2009, 22:11
Цитата

а у левый половине...??? 

не понял )))

Автор: vudu91 10.5.2009, 22:17
Dmi3ev, ну чтоб выводило не на весь экран а на половину.

Добавлено через 5 минут и 31 секунду
чтобы график занял не весь экран а левую половину ну а справа било свободное место

Автор: Dmi3ev 10.5.2009, 22:28
Цитата

а не подскажэш  как увеличить маштаб

не подскажу, буду развивать в тебе умение мыслить... это очень легко...
что такое масштаб?
допустим реально у нас круг радиусом 1мм, а мы его изобразили радиусом 1см, чтобы видно было, те увеличили в 10 раз, а что мы для это сделали? правильно умножили... вот и подумай, как это провернуть программно...
ЗЫ
просто пока кроме клавиш ctrl+c, ctrl+v ты ничего не использовал для написания программы (даже в Н-файле строку не мог добавить)  smile 
либо начинай разбираться с этим несложным кодом, либо нех билдер ваще открывать... тут не все так просто как в CS и WarCraft, надо думать, а не только кнопки жать  smile И побольше читай, такие штучки в самых простецких книжках можно найти...

Добавлено через 58 секунд
Цитата

чтобы график занял не весь экран а левую половину ну а справа било свободное место 

думать, думать, и еще раз думать, надо поменять всего лишь несколько цифр!

Добавлено через 2 минуты и 55 секунд
самый простой способ, если ваще не варит котел, взять TImage, сделать его нужного размера и рисовать в нем! Соответственно, заменить this на Image1

Добавлено через 9 минут и 28 секунд
Код

//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{
}
//---------------------------------------------------------------------------
double f1(int x, double a)
{
        return (x*x*a);
}
void TForm1::DrawMyF1()
{
        int a=StrToInt(Edit1->Text);
        int x=0;
        int y=0;
        Image1->Canvas->MoveTo(Image1->Width/2, Image1->Height/2);
        Image1->Canvas->Pen->Color=clRed;

        while (x>-(Image1->Width/2) && y<Image1->Height/2)
        {
                x--;
                y=f1(x, a);
                Image1->Canvas->LineTo(x+(Image1->Width/2), (Image1->Height/2)-y);
        }
        Image1->Canvas->MoveTo(Image1->Width/2, Image1->Height/2);
        x=0;
        y=0;
        while (x<(Image1->Width/2) && y<Image1->Height/2)
        {
                x++;
                y=f1(x, a);
                Image1->Canvas->LineTo(x+(Image1->Width/2), (Image1->Height/2)-y);
        }


}
void TForm1::Draw1()
{
        Image1->Canvas->MoveTo(0, Image1->Height/2);
        Image1->Canvas->Pen->Color=clBlack;
        Image1->Canvas->LineTo(Image1->Width, Image1->Height/2);
        Image1->Canvas->MoveTo(Image1->Width/2, 0);
        Image1->Canvas->LineTo(Image1->Width/2, Image1->Height);
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
        Draw1();
        DrawMyF1();
}
//---------------------------------------------------------------------------


Добавлено через 10 минут и 16 секунд
просто? да? а сам почему не хочешь думать?
  smile 

Автор: Dmi3ev 10.5.2009, 22:46
vudu91, ну чего? получилось? или компонент Image не можешь найти?

Автор: vudu91 10.5.2009, 22:50
спасибо большое 
буду исправляться... с этим графиком я уже неделю мучаюсь, а толку ноль... 

Автор: Dmi3ev 10.5.2009, 22:50
Я бы так сделал, это дает ряд плюсов, не зависит от формы, те можно его разместить где угодно, менять размер, и тд и тп, при этом код не изменится, а с формой придется править каждый раз... Короче, рисуй не на форме а на TImage
Цитата

если ваще не варит котел

это я не со зла, извини... Даже лучше взять TImage

Автор: vudu91 10.5.2009, 22:57
нашол..  я нуб но не на столько, книги немного читаю...
ещо раз спасибо

Автор: vudu91 11.5.2009, 16:29
а не посоветуешь что нужно сделать,  или что я не правильно делаю я в место всех х++ и х-- просто поставил
Код

 float dx=0.5;
          x=x-dx;
  ну оно почемуто не работает ... вместо dx ставил просто числа  неработает... сама прога запускается ну когда нажымаю "построить график" глюкает..  ни на что не реагирует большэ ... это в мене камп глюкае или гдето я прощитался 

Автор: Dmi3ev 11.5.2009, 17:14
Цитата

float dx=0.5;
          x=x-dx;

а зачем ты так делаешь?

Добавлено через 1 минуту и 6 секунд
Цитата

это в мене камп глюкае или гдето я прощитался  

я тебя расстрою, но не в кампе дело  smile

Добавлено через 1 минуту и 41 секунду
а вот прокладку между стулом и компом можно поменять  smile

Добавлено через 6 минут и 6 секунд
Цитата

x=x-dx;

+ еще подумай, в чем измеряется Width, Height может ли это быть дробным?  smile Прежде чем садиться и писать код, нужно немного почитать... ты даже в готовой программе не можешь ничего изменить, хотя она удобочитабельна и не требует великих знаний, все по полочкам разложено... но не айс... Советую начать читать, так ничего не выйдет... Все зря... Только если будешь брать готовое, тогда будет работать, в остальных случаях нет...

Автор: vudu91 11.5.2009, 17:54
ну и на этом спасибо 

Автор: vudu91 12.5.2009, 18:35

Dmi3ev, а при чом тут
Цитата

 еще подумай, в чем измеряется Width, Height может ли это быть дробным?

мы ж вроде их не меняем 
как не странно но
Код

float dx;
 dx=StrToFloat(Edit2->Text);

Код

x=x-dx;
                y=f1(x);

и все просто супер.. и график строится хоть при 1 хоть при 0.01 


Автор: Dmi3ev 12.5.2009, 19:21
Цитата

мы ж вроде их не меняем 
как не странно но

vudu91, их мы не меняем, но LineTo принимает два целых параметра (что неудивительно, почему подумай сам)...
Цитата

и все просто супер.. и график строится хоть при 1 хоть при 0.01 

я рад за тебя )))
а знаешь почему? потому что берется целая часть те если х=0,99 то в функции LineTo х уже будет 0, тк его целая часть равно 0 (неявное преобразование типов, если ты об этом слышал), но потом х=1,99, и в функции LineTo х будет 1
поэтому визуально ты график видишь (даже похоже не видишь, что он неправильный), только он построен не совсем правильно, а точнее сказать совсем неправильно...
но если ты будешь строить график sin(x) (который не будет больше 1, и меньше -1), то таким макаром ничего ваще не выйдет...
потому как при х (-8; +8) (кроме тех случаес, когда х=П/2+Пn) у после попадания в функцию LineTo будет преобразован к 0 поэтому ты будешь получать прямую, лежащую на оси х, и только когда х будет делать у=1 или -1 будут точки в соответствующих местах...
но это устраняется с помщью простого умножения, те если функция sin(x), то ее можно записать вот так
Код

int myf1(int x)
{
return (100*sin(x));
}

и уже можно строить, только надо понимать, что по оси у идет увеличение масштаба (визуально график будет выглядеть правильно)...
догнал? или нет? объяснить просто не знаю как... но все просто...
хотя если тебя устраивает все, то я ни в коем случае не против, 
только по-моему мнению не очень, по крайней мере неразумно отнимать или прибавлять какие-то дельты дробные, если один х.. в функции LineTo используются целые числа (это искажает график, может ты этого не замечаешь, но это так)

Автор: vudu91 12.5.2009, 19:42

Dmi3ev, ну ладно может ты и прав но  до тех примеров что у меня вполне подходит и  так 


smile  smile  smile 

Автор: Dmi3ev 12.5.2009, 19:49
 smile 
Цитата

Dmi3ev, ну ладно может ты и прав но  до тех примеров что у меня вполне подходит и  так 

спасибо большое, недопрограммер, за то, что Вы оценили мои слова  smile 
Да делай, как хочешь, мне-то ваще пох... Только это глупо...
Цитата

хоть при 0.01 

при 0,01, при 0,02, при 0,03, при 0,..... ничего он не строит, а ставит точку в (0, ...), те всегда в одном и том же месте...  smile 
Дело твое, еще раз говорю, мне пох...  smile 

Автор: xvr 12.5.2009, 19:57
Для рисования советую использовать компонент TChart - он замечательно умеет смещать и влево и вправо и масштабировать и много чего еще

Автор: Dmi3ev 12.5.2009, 19:59
Цитата

Для рисования советую использовать компонент TChart - он замечательно умеет смещать и влево и вправо и масштабировать и много чего еще

это да, но человек похоже хочет сам рисовать с помщью Canvas...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)