Sinus zeichnen lassen



  • Ich muss doch den Sinus von 0 - 2pi auf 0 - 40 strecken. wenn ich mir das in so ner graphensoftware anschaue, dann stimmt das mit dem term überein. sin(((2*pi)/40)*x)

    Wenn ich nun die y-Achse auf 0 - 20 strecken will ("normal" isses ja -1, +1) dann geht das so: y = 10*sin(((2*pi)/40)*x)+10.

    Mal zusammengefasst:
    - Der sinus geht von 0 bis 2pi abgebildet auf 0 bis 40. Hast du ja jetzt.
    - Der sinus liefert Werte im Bereich -1 bis 1 abgebildet auf 0 bis 20. Hast du auch

    D.h. ich hab jetzt meine Werte. Jetzt gehts nur noch darum sie in ein Array richtig reinzuschreiben, oder? Wie geht das jetzt? Hier weiß ich nicht mehr weiter... Muss ich jetzt die x-Werte in die eine Dimension des Arrays und die y-Werte in die andere Dimension des Arrays reinschreiben? Und in welches Array? in ein neues oder in das, welches mit Leerzeichen voll ist?



  • bandchef schrieb:

    y=10*sin(((2*PI)/40)*i)+10?

    Warum steht diese Formel nicht bei dir im Code? Und warum möchtest du so einen langen Ausdruck schreiben?
    Es war außerdem ein gut gemeinter Ratschlag meinerseits, Konstanten zu verwenden.
    Was auffällt:

    const int xdim = 41;
    const int ydim = 21;
    .. 
    ((2*PI)/xdim); // ist ein konstanter Wert, der auch vor der Schleife berechnet werden kann
    // 10 entspricht ydim/2
    

    Warum gehst du den Weg über weitere Arrays? Warum ist dein array nun ein Array aus doubles. Warum hast du array in leerarray umbenannt?
    Du kannst die Werte direkt in leerarray eintragen. Wenn du ganz auf Nummer sicher gehen möchtest, castest du den Ausdruck in einen Integerwert und führst eine Bereichsprüfung durch (Wert>=0 && Wert<ydim).
    Du könntest in einer weiteren Schleife leerarray[xdim-1][k] auf '\n' (Zeilenumbruch) setzen und leerarray[xdim-1][ydim-1] auf '\0'. So könntest du alles direkt ausgeben, ohne eine doppelte Schleife zu nutzen.



  • Warum soll ((2*PI)/xdim) ein konstanter Wert sein? Dieser Wert hängt doch von xdim ab?



  • Hier nun mein Code:

    #include<iostream>
    #include<math.h>
    #define M_PI 3.141592654
    using namespace std;
    
    int main()
    {
     int i;
     char leerarray[21][41];
    
     //Array mit Leerzeichen(' ') auffüllen
     for(i=0; i<21; i=i+1)
     {
              for(j=0; j<41; j=j+1)
              {
               leerarray[i][j] = ' ';
              }
     }
    
    system("pause");
    return 0;
    }
    

    Array hab ich in Leerarray umbenannte weil Leerzeich drin sind. Mir wurd gesagt ich soll aussagekräftige Namen vergeben. Hab ich hiermit gemacht.

    Dass ich double-Werte in ein char Array übergeben daraf wusste ich nicht. Diese konstanten mag ich nicht verwenden weil ich den Eindruck habe, dass es für mich (trotzdem der weniger großen Übersichtlichkeit) "einfacher" ist zu verstehen was das bedeutet.

    Was soll ich nun machen? Kannst dus mal bitte ganz genau erklären? Ich stells mir so vor:

    Ich berechne mir nun in einer Schleife die neuen y-Werte. Dann muss ich irgendwie mit einer schleife die neuen y-Werte in mein leerarray reinschreiben.

    Dann berechne ich mir erneut in einer Schleife die x-Werte und schreib mir die dann in einer weiteren Schleifen die neuen x-Werte ins leerarray.

    Ich weiß, dass sind 4 schleifen, aber alles aufeinmal in einer einzigen Schleife würde mich eh nur überfordern. So hab ich alles schrittweise; ist da was dagegen zu sagen?

    Helft ihr mir noch?



  • So sieht das jetzt aus:

    #include<iostream>
    #include<math.h>
    #define M_PI 3.141592654
    using namespace std;
    
    int main()
    {
     int i, j;
     double y_array[21];
     char leerarray[21][41];
    
     //Array mit Leerzeichen(' ') auffüllen
     for(i=0; i<21; i=i+1)
     {
              for(j=0; j<41; j=j+1)
              {
               leerarray[i][j] = ' ';
              }
     }
    
     //y-Werte berechnen
     for(j=0; j<21; j=j+1)
     {
    	 y_array[j] = 10*sin(((2*M_PI)/40)*j)+10;
     }
    
    system("pause");
    return 0;
    }
    


  • Zu deinem "leerarray": Wenn du das Array so genannt hast, denkst du wohl, dass da nichts anderes mehr reinkommt außer den Leerzeichen? Dann frag dich mal, welchen Sinn ein solches Array hätte.

    Zu deinem "y_array": Hätte dieses Array einen sinnvollen Name, würdest du sehen, dass die Abbruchbedingung der letzten Schleife falsch ist.



  • Du willst doch die Sinuskurve in deinem Array haben. Dann musst du da auch reinschreiben!

    Ich schrieb:

    Array_setzen(' ');
      Achse_zeichnen('-');
      int y;
      for(k=0; k<41; k=k+1)
      {
        y = ... ;// siehe oben
        array[y][k] = '#';
      }
      Ausgabe();
    

    und du:

    y=10*sin(((2*PI)/40)*i)+10?

    abgesehen davon das k=i ist, wo ist da das Problem die zwei Sachen zusammenzuführen?
    Abgesehen von einem Typcast y = (int)10*sin(((2*PI)*k/40))+10;

    Array hab ich in Leerarray umbenannte weil Leerzeich drin sind. Mir wurd gesagt ich soll aussagekräftige Namen vergeben. Hab ich hiermit gemacht.

    Jetzt steht in dem Array aber eine Sinuskurve. Willst du es jetzt sinusarray nennen? 😉



  • Bandchef, was Dir ein wenig fehlt, ist der Biss und der Ehrgeiz, es erstmal alleine zu versuchen. Und Freude daran zu haben!

    Später im Beruf kannst Du Deine Kollegen mal fragen, wenn Du auf dem Schlauch stehst, aber es wird Dich keiner zum Ziel tragen. Man bezahlt Dich dann dafür, dass Du derjenige bist, der die Probleme löst und Lösungen findet.

    Es ist kein Thema, mal was nicht zu wissen. Aber "haben wir in der Schule nicht gehabt" ist im Studium kein Grund mehr, denn man kann (man muss) versuchen, in Literatur und Internet nach Informationen zu suchen und sich erstmal über der Hintergrund von den Sachen, mit denen man arbeitet, auseinanderzusetzen, bis man sie wirklich verstanden hat (in Deinem Fall: For-Schleifen, Arrays, double, int. Lies bitte nochmal in Deinem Lehrbuch zu diesen Themen!).

    Was Du tust ist, einmal gehörte Dinge zusammenzuwürfeln und zu hoffen, dass es irgendwie klappt. Und andere zu fragen, ob das nun richtig ist.

    Nicht, dass andere Dir nicht gerne helfen. Allein, es fehlt ein wenig der "Spirit" zur Eigeninitiative - und zur Mitarbeit. Und Ratschläge anzunehmen. Vicious Falcon hat Dir bereits zweimal etwas Wesentliches geschrieben. Das solltest Du wirklich umsetzen.

    Und als Tip von mir: Lese nochmal nach, wie man ein double in ein int umwandelt und was es hierbei zum Thema "Runden" zu beachten gilt...



  • Mein Code jetzt:

    #include<iostream>
    #include<math.h>
    #define M_PI 3.141592654
    using namespace std;
    
    int main()
    {
     int i, j, k;
     int y_array[41];
     double x_array[41];
     char leerarray[21][41];
    
     //Array mit Leerzeichen(' ') auffüllen
     for(i=0; i<21; i=i+1)
     {
              for(j=0; j<41; j=j+1)
              {
               leerarray[i][j] = ' ';
              }
     }
    
     //y-Werte berechnen
     for(j=0; j<41; j=j+1)
     {
    	 y_array[j] = 10*sin(((2*M_PI)/40)*j)+10;
     }
    
     //x-Werte berechnen
     for(k=0; k<41; k=k+1)
     {
    	 x_array[k] = ((2*M_PI)/40)*k;
     }
    
    system("pause");
    return 0;
    }
    

    Das ich für die y-Werte kein double brauche ist mir jetzt auch klar. Wie geht das dann aber für die x-Werte? Wenn ich hier auch wieder ein int Array verwende, dann bekomm ich 7 mal eine Null hintereinander. Was bei einer Umwandlung von double nach int geschieht weiß ich. Es werden Nachkommastellen abgeschnitten ohne auf korrekte Rundung zu achten. Genau das will man ja bei der Berechnung der y-Werte ja zum Beispiel.



  • Du entfernst dich immer mehr von einem sinnvollen Ansatz.

    Warum denn jetzt schon wieder ein x_array. Deine x werte sind 0, 1, 2, 3, .. 40

    Mal kurz ein paar Vorschläge aus dem Thread zusammengefügt:
    (aber nicht nicht ausprobiert).

    #include <stdio.h>
    #include <math.h>
    #define M_PI 3.141592654 
    
    int main()
    {
     int i, j, k;
     char array[21][41];
    
     //Array mit Leerzeichen(' ') auffüllen
     for(i=0; i<21; i=i+1)
     {
              for(j=0; j<41; j=j+1)
              {
                array[i][j] = ' ';
              }
     }
    
     //y-Werte berechnen
     for(j=0; j<41; j=j+1)
     {   y = (int)(10*0.0+10);  // Achse-Einzeichnen
         array[y][j] = '-';
         y = (int)(10*sin(((2*M_PI)*j/40))+10);  // Sinus-Einzeichnen
         array[y][j] = '#';
     }
    
     for(k=0; k<21; k=k+1)
     {
         printf("%41.41s\n", array[k]); //Zeile k mit 41 Zeichen ausgeben
     }
    
    return 0;
    }
    


  • bandchef schrieb:

    Es werden Nachkommastellen abgeschnitten ohne auf korrekte Rundung zu achten. Genau das will man ja bei der Berechnung der y-Werte ja zum Beispiel.

    Genau das glaube ich nicht. Wenn wir 21 Zeilen haben, gehe ich davon aus, dass genau in der Mitte der mittleren davon die X-Achse verläuft. Also muss ich die Funktionswerte korrekt algebraisch runden, sonst wird die Darstellung nachher asymetrisch. Du hast richtig erkannt, dass double --> int das nicht macht.

    Egal, probier es einfach aus. Wenn Du nachher Deinen Sinus mal ausgedruckt hast, wirst Du sehen, was ich meine (vor allem, wenn Du die Achse mit im Bild hast wie in Beraters Beispiel).



  • Hej, kleine Zwischenfrage. Wie läuft es mit dem Projekt? Klappt alles?



  • Er hat schon ein neues Projekt.



  • Naja, dann kann ich ja noch meine eindimensionale Variante hinterherschieben. Für die, die es noch interessiert...

    #include <stdio.h>
    #include <math.h>
    #define PI2 (2 * 3.14159265)
    
    int main( )
    {
        const int X_SIZE   = 40;   // Teile einer ganzen Periode
        const int Y_FACTOR = 10;
    
        int yValues[ X_SIZE + 1 ];
    
        // Berechne Funktionswerte (multipliziert mit y-Faktor und gerundet)
        for( int x = 0; x <= X_SIZE; ++x )
        {
            double sine = sin( PI2 * x / X_SIZE );
            yValues[ x ] = sine * Y_FACTOR + ( ( sine >= 0 ) ? +0.5 : -0.5 );
        }
    
        // Gebe Funktionswerte Zeile für Zeile aus
        for( int y = Y_FACTOR; y >= -Y_FACTOR; --y )
        {
        	char background = ( 0 == y ) ? '-' : ' ';		// X-Achse, sofern in richtiger Zeile
            for( int x = 0; x <= X_SIZE; ++x )
            {
                putchar( ( yValues[ x ] == y ) ? '#' : background );
            }
            putchar( '\n' );
        }
    
        return 0;
    }
    

Anmelden zum Antworten