[c++]Program rysujacy wykres funkcji(konsolowy z winbgim)

czacha

[c++]Program rysujacy wykres funkcji(konsolowy z winbgim)

Post autor: czacha »

Mam problem z ponizszym programem.

main.cpp

Kod: Zaznacz cały

#include <cstdlib>
#include <iostream>
#include <winbgim.h>
#include "deklaracje.h"
#include "definicje.h"

int main(int argc, char *argv[])
{
    //obiekt grafika do operacji na wykresach
    Grafika Zrob;
    
    //zmienne przechowujace wielkosc okna
    int szer, wys;
    
    //pobieramy wymiary okna
    cout << "Podaj wielkosc okna.\n";
    cin >> szer >> wys;
    
    //RYSUJEMY OKNO I UKLAD WSPOLRZEDNYCH
    Zrob.RysOkno(&szer,&wys);
    Zrob.RysUklad(&szer,&wys);
    
    //PETLA GLOWNA
    while(1)
    {
            cout << "Jaki wykres chcesz narysowac?\n";
            cout << "1 - Funkcja liniowa\t(y = ax + b)\n";
            cout << "2 - Parabola\t\t(y = ax^2 + b)\n";
            cout << "3 - Hiperbola\t\t(y = a/x)\n";
            cout << "0 - Wyjscie\n";
            
            unsigned short int decyzja;
            float wspProp, wWolny;
            
            //zmienna decyzja sluzy do wyboru zadania
            // wspProp to wspolczynnik proporcjonalnosci
            // wWolny to wyraz wolny, okresla o ile wykres ma
            //    zostac podniesiony lub opuszczony
            
            cin >> decyzja;
            
            switch(decyzja)
            {
                 case 1:
                      cout << "Podaj wspolczynnik proporcjonalnosci(a): ";
                      cin >> wspProp;
                      cout << "\nPodaj wyraz wolny(b): ";
                      cin >> wWolny;
                      
                      Zrob.RysFunkcjaLiniowa(&szer, &wys, &wspProp, &wWolny);
                      while(!getch());
                      break;
                 case 2:
                      cout << "Podaj wspolczynnik proporcjonalnosci(a): ";
                      cin >> wspProp;
                      cout << "\nPodaj wyraz wolny(b): ";
                      cin >> wWolny;

                      Zrob.RysParabola(&szer, &wys, &wspProp, &wWolny);
                      while(!getch());
                      break;
                 case 3:
                      cout << "Podaj wspolczynnik proporcjonalnosci(a): ";
                      cin >> wspProp;
                      
                      Zrob.RysHiperbola(&szer, &wys, &wspProp);
                      while(!getch());
                      break;
                 case 0:
                      return 0;
                 default: continue;
            }
            //czyscimy okno i uzupelniamy od nowa
            Zrob.Refresh(&szer, &wys);
            Zrob.RysUklad(&szer, &wys);
    }
    closegraph();
    return EXIT_SUCCESS;
}
deklaracje.h

Kod: Zaznacz cały

//###################################### KLASA Grafika #########################
class Grafika
{
      public:
         //konstruktory
             Grafika();
             Grafika(int *width, int *height);
             ~Grafika();
         //akcesory
             int GetWidth()const { return *itsWidth; }
             int GetHeight()const { return *itsHeight; }
             void SetWidth(int *width) { *width = *itsWidth; }
             void SetHeight(int *height) { *height = *itsHeight; }
         //metody rysujace
             //metoda rysujaca okno
                      void RysOkno(int *width, int *height);
             //metoda rysujaca uklad wspolrzednych
                      void RysUklad(int *width, int *height);
             //metoda odswierzajaca okno
                      void Refresh(int *width, int *height);
             //metody rysujace wykresy funkcji
                 //funkcja liniowa
                      void RysFunkcjaLiniowa(int *width, int *height,
                                             float *a, float *b);
                 //parabola
                      void RysParabola(int *width, int *height,
                                       float *a, float *b);
                 //hiperbola
                      void RysHiperbola(int *width, int *height, float *a);
      protected:
         //skladowe
             int *itsWidth;
             int *itsHeight;
};

//######################## POZOSTALE FUNKCJE ###################################

int PrzeliczX(int x, int w);
int PrzeliczY(int y, int h);

void PreFunkcjaLiniowa(int *w, int *h,
                       int *x, int *y, float *a, float *b);
void PreParabola(int *w, int *h,
                       int *x, int *y, float *a, float *b);
void PreHiperbola(int *w, int *h,
                       int *x, int *y, float *a);
definicje.h

Kod: Zaznacz cały

using namespace std;

//################################# KONSTRUKTORY ###############################

Grafika::Grafika()
{
     itsWidth = new int(0);
     itsHeight = new int(0);
}
Grafika::Grafika(int *width, int *height)
{
     itsWidth = new int(0);
     itsHeight = new int(0);
}

Grafika::~Grafika()
{
     delete itsWidth;
     delete itsHeight;
     itsWidth = 0;
     itsHeight = 0;
}

//######################### FUNKCJA RYSUJACA OKNO ##############################

void Grafika::RysOkno(int *width, int *height)
{
     initwindow(*width,*height);
     setfillstyle(SOLID_FILL, WHITE);
     bar(0,0,getmaxx(),getmaxy());
}

//######################## FUNKCJA RYSUJACA UKLAD ##############################

void Grafika::RysUklad(int *width, int *height)
{
     setcolor(BLACK);
    
     //osie x,y
     line( 0, *height/2, *width, *height/2 );
     line( *width/2, 0, *width/2, *height );
    
     //strzalki
          //od osi x
     line( (*width - 10), (*height / 2 + 4), *width, (*height / 2) );
     line( (*width - 10), (*height / 2 - 4), *width, (*height / 2) );
    
          //od osi y
     line( (*width / 2 + 4), 10, (*width / 2), 0 );
     line( (*width / 2 - 4), 10, (*width / 2), 0 );
    
     //skala
          //na osi x
              /* for(int x = 0; x < getmaxx(); x + 10)
                       line(x, *height/2-4, x, *height/2+4);
          //na osi y
               for(int y = 0; y < getmaxy(); y + 10)
                       line(*width/2-4, y, *width/2+4, y); */
}

//##################### FUNKCJA ODSWIERZAJACA OKNO #############################

void Grafika::Refresh(int *width, int *height)
{
     cleardevice(); 
     setfillstyle(SOLID_FILL, WHITE);
     bar(0,0,getmaxx(),getmaxy());
}

//########################### FUNKCJA LINIOWA ##################################

void Grafika::RysFunkcjaLiniowa(int *width, int *height, float *a, float *b)
{
     //wspolrzedne punktu w prostokatnym ukladzie wspolrzednych 
     int x = -*width / 2;
     int y;
    
     //wspolrzedne punktu w oknie komputera
     int bx = 0;
     int by = 0;
     
     //petla rysuje punkt o wspolrzednych(x,y) przy kazdym przebiegu w kolejnym
     //obliczonym miejscu
     for(bx = 0;;) 
     {  
            y = *a * x + *b;
         
            cout << "x: " << x << endl;
            cout << "y: " << y << endl;
         
            bx = PrzeliczX(x, *width);
            by = PrzeliczY(y, *height);
         
            PreFunkcjaLiniowa(width, height, &x, &y, a, b);
         
            delay(20);
         
            cout << "x': " << bx << endl;
            cout << "y': " << by << endl << endl;
         
            if( bx >= getmaxx() || by <= 0 )break;
     }
}

//############################## PARABOLA ######################################

void Grafika::RysParabola(int *width, int *height, float *a, float *b)
{
     //wspolrzedne punktu w prostokatnym ukladzie wspolrzednych 
     int x = -*width / 2;
     int y;
    
     //wspolrzedne punktu w oknie komputera
     int bx = 0;
     int by = 0;
     
     //petla rysuje punkt o wspolrzednych(x,y) przy kazdym przebiegu w kolejnym
     //obliczonym miejscu
     for(bx = 0;;) 
     {
            #define SQUARE(x) ( (x) * (x) )
            y = (*a) * SQUARE(x) + (*b);
            
            cout << "x: " << x << endl;
            cout << "y: " << y << endl;
         
            bx = PrzeliczX(x, *width);
            by = PrzeliczY(y, *height);
            
            PreParabola(width, height, &x, &y, a, b);
            
            delay(20);
         
            cout << "x': " << bx << endl;
            cout << "y': " << by << endl << endl;
         
            if((bx >= getmaxx()/2) && (by <= 0))break;        
     }
}

//############################### HIPERBOLA ####################################

void Grafika::RysHiperbola(int *width, int *height, float *a)
{
     //wspolrzedne punktu w prostokatnym ukladzie wspolrzednych 
     int x = -*width / 2;
     int y;
    
     //wspolrzedne punktu w oknie komputera
     int bx = 0;
     int by = 0;
     
     //petla rysuje punkt o wspolrzednych(x,y) przy kazdym przebiegu w kolejnym
     //obliczonym miejscu
     for(bx = 0;;) 
     {
            y = (*a) / x;
            
            cout << "x: " << x << endl;
            cout << "y: " << y << endl;
         
            bx = PrzeliczX(x, *width);
            by = PrzeliczY(y, *height);
            
            PreHiperbola(width, height, &x, &y, a);
            
            delay(20);
         
            cout << "x': " << bx << endl;
            cout << "y': " << by << endl << endl;
         
            //if((bx >= getmaxx()/2) || (by <= 0))break;  
     }
}

//###################### FUNKCJE PRZELICZAJACE WSPOLRZEDNE #####################

int PrzeliczX(int x, int w)
{
     return x + w / 2;
}

int PrzeliczY(int y, int h)
{
     return -(y - h / 2);
}

//############################# FUNKCJE LACZACE PUNKTY #########################

void PreFunkcjaLiniowa(int *w, int *h,
                       int *x, int *y, float *a, float *b)
{
     setcolor(RED);
     int ax = PrzeliczX(*x, *w);
     int ay = PrzeliczY(*y, *h);
     
     ++(*x);
     *y = (*a) * (*x) + (*b);
     
     int bx = PrzeliczX(*x, *w);
     int by = PrzeliczY(*y, *h);
     
     line( ax, ay, bx, by );
}

void PreParabola(int *w, int *h,
                       int *x, int *y, float *a, float *b)
{
     setcolor(RED);
     #define SQUARE(x) ( (x) * (x) )
     int ax = PrzeliczX(*x, *w);
     int ay = PrzeliczY(*y, *h);
     
     ++(*x);
     *y = (*a) * SQUARE(*x) + (*b);
     
     int bx = PrzeliczX(*x, *w);
     int by = PrzeliczY(*y, *h);
     
     line( ax, ay, bx, by );
}

void PreHiperbola(int *w, int *h,
                       int *x, int *y, float *a) 
{
     setcolor(RED);
     int ax = PrzeliczX(*x, *w);
     int ay = PrzeliczY(*y, *h);
     
     ++(*x);
     *y = (*a) / (*x);
     
     int bx = PrzeliczX(*x, *w);
     int by = PrzeliczY(*y, *h);
     
     line( ax, ay, bx, by );
}
Prosze wybaczyc jesli analiza programu sprawi komus trudnosci ale jestem poczatkujacy i nie bardzo potrafie zapanowac nad wiekszym projektem. W brzydki sposob rozwiazalem tutaj konwersje z typu float na int ale inaczej nie umiem. Jednak nie w tym problem. Chodzi o to, ze nie wiem jak narysowac normalny wykres hiperboli. Bo ten, ktory mi wychodzi nie wyglada tak jak powinien(chyba). Drugi problem to nie wiem jak zakonczyc dzialanie petli rysujacej w poszczegolnych funkcjach. Warunki ktore zastosowalem nie do konca odwzorowuja moje zamierzenia. Nie wiem tez jak w funkcji glownej w liniach 52, 61, 68 przerwac switch(). Z gory dziekuje, pozdrawiam.

Moze jeszcze dodam cos bo widze ze chyba nikt nie czai mojego mizernego kodu. Funkcje Pre... sa po to, zeby odgadnely jaki bedzie nastepny punkt i polaczyly go linia z poprzednim bo jak bede robil funkcja "putpixel(x,y,c)" to kropki czasem powychodza bardzo rzadkie.

Funkcje Przelicz... przeliczaja wspolrzedne z takich jak w prostokatnym ukladzie wspolrzednych na takie jakie wystepuja w stworzonym przez komputer oknie. Bo wiadomo ze klasyczny uklad wspolrzednych jest oznaczony na nieco innej zasadzie niz ten w okienku. Czyli w klasycznym '0' jest na srodku, w gore i w prawo rosnie, w lewo i na dol maleje. W okienku mamy (0,0) w gornym lewym rogu, a w dol i w prawo rosnie.
Dumel
Użytkownik
Użytkownik
Posty: 2000
Rejestracja: 19 lut 2008, o 17:35
Płeć: Mężczyzna
Lokalizacja: Stare Pole/Kraków
Podziękował: 60 razy
Pomógł: 202 razy

[c++]Program rysujacy wykres funkcji(konsolowy z winbgim)

Post autor: Dumel »

nie za bardzo wiem co to ma być:

Kod: Zaznacz cały

while(!getch()); 
jeśli program ma czekać na wciśnięcie jakiegoś klawisza, użyj poprostu

Kod: Zaznacz cały

getch()
czacha

[c++]Program rysujacy wykres funkcji(konsolowy z winbgim)

Post autor: czacha »

Faktycznie. Bo najpierw bylo:

Kod: Zaznacz cały

while(!kbhit());
ale nie przerywalo switcha i potem kombinowalem. Robilem m. in. getch(), ale tez nie chcial przerwac.
Spierdzielił mi sie kod. Okno nie działa i dzieją sie dziwne rzeczy, wiec nie sprawdzę czy jest ok, bo ostatnio jak probowalem getch(); to tez nie dzialalo.
Narazie tego nie zrobie bo teraz mam testy, ale moze sa jakies propozycje jeszcze odnosnie hiperboli? Pozdrawiam.[/code]

[ Dodano: 24 Kwietnia 2008, 15:00 ]
Sorry. Ta hiperbola dobrze dziala. Sorry za zamieszanie.

P.S. Zastosowalem getch(); i nie dziala. Dziala dopiero jak tam wstawie system("pause");
A jakie moge wymyslic warunki, zeby te funkcje mi nie padaly za wczesnie i zeby sie zatrzymaly
jak dojada do konca okna? A moze jest jakas funkcja do tego?
ODPOWIEDZ