Tworzenie wykresu funkcji sin(x) za pomocą gwiazdek

0

Witam. Mam problem z kodem, który po uruchomieniu ma drukować wykres funkcji sin x. Na początku zastrzegam, że są to moje początki z C, więc jeśli mój tok rozumowania wydaje się chaotyczny, a kod jest bezsensowny, to prosiłbym o zasygnalizowanie tego faktu. Na początku wolałem spróbować jednak doprowadzić mój pomysł do końca, wolałem uniknąć bazowania na czyichś kodach.

#include <stdio.h>
#include <math.h>
#define FUNC "sin(x)"
#define PI acos(-1)
#define X_MIN 0	//lewy koniec dziedziny
#define X_MAX 2*PI	//prawy koniec dziedziny
#define Y_MAX 1.0	//granica przedzialu zbioru wartosci
#define RZAD 9		//dlugosc osi OY
#define KOL 36		//dlugosc osi OX


main(){

	printf("Program rysuje wykres funkcji %s w przedziale [%d,%d].\n\n",FUNC,X_MIN,X_MAX);

	char tab[RZAD][KOL];

	//wypelnienie tablicy jednowymiarowej wartosciami funkcji sin(x) w przedziale [0;6.28]
	double sin_val[KOL+1];
	for (int i = 0; i < KOL + 1; i++) {
		sin_val[i] = sin(i*PI / 18);
	}

	//wypelnienie tablicy jednowymiarowej wartosciami y dla kazdego nastepnego rzedu 
	double y_val[RZAD];
	for (int i = 0; i < RZAD; i++) {
		y_val[i] = Y_MAX - (i / ((RZAD - 1)/2.0))*Y_MAX;;
	}

	//drukowanie ukladu wspolrzednych
	printf("^\n");
	for (int i = 0; i < RZAD; i++) {
		for (int j = 0; j < KOL; j++) {
			if (j == 0) {
				tab[i][j] = '|';
				continue;
			}
			if (i == (RZAD / 2)) {
				if (j == KOL - 1) {
					tab[i][j] = '->';
				}
				else {
					tab[i][j] = '-';
				}
				continue;
			}
			tab[i][j] = ' ';
		}
	}

	int indeks;
	for (int i = 0; i < KOL; i++) {
		int min = y_val[0];
		for (int j = 0; j < RZAD; j++) {
			if (fabs(y_val[j] - sin_val[i]) <= min) {
				min = fabs(y_val[j] - sin_val[i]);
				indeks = j;
			}
			if (j == RZAD - 1) {
				tab[indeks][i] = '*';
			}
		}
	}

	for (int i = 0; i < RZAD; i++) {
		for (int j = 0; j < KOL; j++) {
			printf("%c", tab[i][j]);
		}
		printf("\n");
	}

	printf("\n\nKoniec programu.\n\n");
	return 0;
} 

Dla pierwszej kolumny x = 0 gwiazdka drukowana jest we właściwym miejscu. Problem pojawia się już w drugiej kolumnie x = 1/16*pi. Po rozpisaniu sobie warunku

		for (int j = 0; j < RZAD; j++) {
			if (fabs(y_val[j] - sin_val[i]) <= min) {
				min = fabs(y_val[j] - sin_val[i]);
				indeks = j;
			}
			if (j == RZAD - 1) {
				tab[indeks][i] = '*';
			}
		}

dla i = 1 obliczyłem, że w momencie, gdy j = 3, wtedy if (fabs(0.25-0.2)<=0.3) po raz ostatni zwraca true, aż do wyjścia z pętli. Z tego powinno wynikać, że w przybliżeniu min = 0.05, a indeks = 3, więc gwiazdka powinna się wydrukować na pozycji tab[3][1]. Niestety tak się nie dzieje, czy ktoś potrafiłby pokazać mi, dlaczego? Wiem, że w kodzie może być więcej błędów, ale póki co skupiam się na tym, żeby gwiazdka wyświetlała się na pozycji tab[3][1], być może po naprawieniu kodu pozostałe gwiazdki również będą na poprawnych pozycjach.

1

Bo tą metodą nie wykonasz wykresu. Co z wartością min w konkretnych zakresach? Lepiej będzie wyliczyć rząd do którego wstawić * poprzez dzielenie zakresu przez ilość rzędów. Wtedy nawet tablica y_val nie będzie potrzebna.
Żebyś nie zostawał z niczym, kilka uwag odnośnie kodu, jak prosiłeś bez rozwiązania :-)

#include <stdio.h>
#include <math.h>
// XXX: Aby na końcu zwrócić ładne EXIT_SUCCESS i mieć dostęp do EXIT_FAILURE
#include <stdlib.h>

// XXX: Zmienił bym nazwę na bardziej opisową
#define NAZWA_FUNKCJI "sin(x)"
// XXX: Tu lepiej M_PI. Masz powód by liczyć z acos()?
//#define PI acos(-1)
// XXX: Lepiej zrobić tak jak X_MAX typem double
#define X_MIN 0.0 //lewy koniec dziedziny
// XXX: W makrach obiliczających, otaczaj je nawiasami. Inaczej potwafią być bardzo "wredne"
#define X_MAX (2 * M_PI)  //prawy koniec dziedziny
#define Y_MAX 1.0   //granica przedzialu zbioru wartosci
#define RZAD 9      //dlugosc osi OY
#define KOL 36      //dlugosc osi OX

// XXX: Sygnaturą funkcji main() w C nie może być to co napisałeś. Albo to co napisałem lub
// int main(int argc, char *argv[];
int main(void) {

    // XXX: Tu w formatowaniu powinien być %f a nie %d. MAX_* są double
    printf("Program rysuje wykres funkcji %s w przedziale [%f, %f].\n\n", NAZWA_FUNKCJI, X_MIN, X_MAX);

    char tab[RZAD][KOL];

    //wypelnienie tablicy jednowymiarowej wartosciami funkcji sin(x) w przedziale [0;6.28]
    double sin_val[KOL+1];
    for (int i = 0; i < (KOL + 1); ++i) {
        sin_val[i] = sin(i * M_PI / (KOL / 2));
    }

    // XXX: Patrz uwaga niżej. Ta tablica nie jest potrzebna do tego rozwiązania.
    //wypelnienie tablicy jednowymiarowej wartosciami y dla kazdego nastepnego rzedu
    double y_val[RZAD];
    for (int i = 0; i < RZAD; ++i) {
        y_val[i] = Y_MAX - (i / ((RZAD - 1) / 2.0)) * Y_MAX;;
    }

    //drukowanie ukladu wspolrzednych
    printf("^\n");
    for (int i = 0; i < RZAD; ++i) {
        for (int j = 0; j < KOL; ++j) {
            if (j == 0) {
                tab[i][j] = '|';
                continue;
            }
            if (i == (RZAD / 2)) {
                if (j == (KOL - 1)) {
                    // XXX: Tu możesz zmieścić 1 znak a nie 2!
                    tab[i][j] = '>';
                } else {
                    tab[i][j] = '-';
                }
                continue;
            }
            tab[i][j] = ' ';
        }
    }

    // XXX: To jest złe podejście. Wartość min nie dla całego zakresu będzie... 
    // pomocna :-/
    int indeks;
    for (int i = 0; i < KOL; ++i) {
        int min = y_val[0];
        for (int j = 0; j < RZAD; ++j) {
            if (fabs(y_val[j] - sin_val[i]) <= min) {
                min = fabs(y_val[j] - sin_val[i]);
                indeks = j;
            }
            if (j == (RZAD - 1)) {
                tab[indeks][i] = '*';
            }
        }
    }

    for (int i = 0; i < RZAD; ++i) {
        for (int j = 0; j < KOL; ++j) {
            // XXX: Lepiej putchar() jeśli masz 1 znak.
            putchar(tab[i][j]);
        }
        putchar('\n');
    }

    printf("\n\nKoniec programu.\n\n");

    return EXIT_SUCCESS;
}
0

Co do M_PI, to w żaden sposób nie mogę się do niego odwołać, tak jakby ta stała nie była zawarta w bibliotece <math.h>. Jedyne, co otrzymuję, to "identifier "M_PI" is undefined". Jeśli chodzi o resztę sugestii, to zabieram się do ich analizowania.

Mam jeszcze pytanie, co jest nie tak z sygnaturą funkcji main w moim kodzie?

1 użytkowników online, w tym zalogowanych: 0, gości: 1