Sinus zeichnen lassen



  • Oh. Ich dachte, das wäre die Aufgabenstellung.

    SeppJ, da hast Du sogar recht. Habe die Aufgabe gar nicht soo genau gelesen...

    Naja, machen wir halt 2-dimensional weiter.

    Abgesehen davon hielte ich ein Zuerst-die-Werte-Berechnen (eindimensional...), Dann-Werte-ausgeben für didaktisch wesentlich sinnvoller und auch für Anfänger nicht schwerer als die geforderte Brute-Force-Methode.



  • Vielleicht könnt ihr euch aus diesen Code ein paar Ideen holen. Ich hab den mal vor einiger Zeit aus dem IRC gefischt, keine Ahnung mehr von wem 😕 Ist aber imo sehr beeindruckend!

    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    
    int plot[25] = {
      ' ', ',', '/', '/', '|',
      '_', '_', '/', '/', '|',
      '\\', ',', '-', '\'', '/',
      '|', '\\', '`', '\'', '\'',
      '|', '\\', '\\', '\'', ' '
    };
    
    double f(double x) {
      return sin(x);
    }
    
    int main() {
      double xn = 0.0,
             xx = 2*M_PI;
      double yn = -1,
             yx = 1;
      double ab, be, up, mi;
      int nx = 75,
          ny = 10;
      int i, j, p;
      double *v = calloc(nx+1, sizeof(double));
      for(i=0; i<=nx; i++) {
        v[i] = f(xn+(xx-xn)/nx*i);
      }
      for(j=0; j<=ny; j++) {
        ab = yn+(yx-yn)*(ny-j)/ny;
        be = yn+(yx-yn)*(ny-j-1)/ny;
        up = be+(ab-be)/3;
        mi = be+(ab-be)*2.0/3;
        for(i=1; i<=nx; i++) {
          if(v[i-1]>=ab) p=4; else if(v[i-1]>=up) p=3; else if(v[i-1]>=mi) p=2; else if(v[i-1]>=be) p=1; else p=0;
          p*=5;
          if(v[i]>=ab) p+=4; else if(v[i]>=up) p+=3; else if(v[i]>=mi) p+=2; else if(v[i]>=be) p+=1;
          putchar(plot[p]);
        }
        putchar('\n');
      }
    }
    


  • Biolunar schrieb:

    Ist aber imo sehr beeindruckend!

    Beeindruckend unverständlich. Der Name "plot" passt übrigens nicht ins Schema, "pt" würde passen 🙄



  • wieso wollen alle sowas auf der console zeichnen? nur weil wir hier im c89/99 subforum sind können wir trotzdem grafiken zeichnen und wenns nur ne *.bmp als ausgabe ist 😡



  • Weil das Ding nicht um Grafik geht sondern eine Übung, wie man seine Daten strukturiert und damit umgeht. Die Ausgabe ist nur Mittel zum Zweck.

    @Biolunar: Ein Programm(code) ist dann gut, wenn er einem (menschlichen) Leser so klar wie möglich beschreibt, was es macht und seine Struktur offenbart. Dazu gehören in erster Linie mal sprechende Variablen- und Funktionsnamen und wenn das nicht reicht der eine oder andere präzise Kommentar.

    Ein solches Programm hier tut all das nicht, und was soll ein Anfänger daraus lernen? Am besten: Wie man keine Programme schreiben sollte.



  • Gut, ich hab gelesen, dass man für mein Übungsprogramm gar kein 2-dimensionales array braucht. Ich würde es dann gerne mit einem 1-dimensionalen Array versuchen. Wie gehe ich da dann vor?

    Passt da mein Schema noch: y- und x-Wert des Sinusberechnen lassen und dann eben ausgeben?

    EDIT: Sorry, wir sollten schon 2-dimensional weitermachen, weil ja die Aufgabe tatsächlich ein 2-dimensionales Feld verlangt.



  • @SeppJ:

    Das passt überhaupt nicht. Denk nochmal darüber nach. Und versuch dir etwas mehr Mühe zu geben und mitzudenken. Du willst ein zweidimensionales Array auf 0 setzen. Kann dein Code dies leisten?

    Warumm will ich mein 2-dimensionales Feld komplett auf 0 setzen?

    Gut, aber nun, wenn du es sagst, dann mach ich es eben:

    Hier mein Code, der hoffentlich das leistet was du sagst:

    for(i=0; i<21; i=i+1)
     {
      array[i][41] = 0;
     }
    
     for(i=0; i<41; i=i+1)
     {
      array[21][i] = 0;
     }
    


  • Ich hab ihn jetzt mal ausprobiert, aber ich bekomm eine Endlosschleife... An was liegt das jetzt? Die Bedingungen der beiden for-Schleifen hab ich doch richtig gesetzt... Die Endlosschleife produziert mir auch nur die zweite Schleife, also die, die mir die Elemente in 2. Dimension reinschreibt... Versteh ich nicht.


  • Mod

    bandchef schrieb:

    Warumm will ich mein 2-dimensionales Feld komplett auf 0 setzen?

    Ich dachte, dies sei deine Ursprungsidee gewesen, dass im Array hinterher so etwas steht:

    0000##00000000000
    000#00#0000000000
    0#00000#000000000
    #0000000#00000000
    000000000#000000#
    0000000000#0000#0
    00000000000#00#00
    000000000000##000
    

    Ich hätte das zwar niemals so gemacht, aber das war das was du beschrieben hast.

    Hier mein Code, der hoffentlich das leistet was du sagst:

    Das tut er nicht annähernd. Ich habe dir sogar schon ganz genau gesagt wie es geht.



  • Das Array initialisiert man üblicherweise gleich bei der Definition mit 0, z.B.

    char array[21][41] = {0};
    

    und das wegen der besseren Lesbarkeit auch global/statisch.



  • 0000##00000000000
    000#00#0000000000
    0#00000#000000000
    #0000000#00000000
    000000000#000000#
    0000000000#0000#0
    00000000000#00#00
    000000000000##000

    Das ist zwar das Grundprinzip, aber meine "Zeichnung" in der Aufgabe, zeigt die Rauten, aber keine Nullen.



  • @SeppJ:

    Ich hab jetzt mein Array auf 0 gesetzt, und zwar so wie Wutz gezeigt hat; nämlich gleich bei der Deklaration.

    #include<iostream>
    #include<math.h>
    using namespace std;
    
    int main()
    {
     int i, j
     char array[21][41] = {0};
    
    system("pause");
    return 0;
    }
    

    Hier ein Link zur Originalskizze: http://yfrog.com/jjunbenanntpsj

    Ich denke, aber ich kann ja mein Array auch mit " " Leerzeichen initialisieren, oder? Dann erziele ich doch genau den Effekt, oder? Nur isses doch dann ein char, oder?



  • bandchef schrieb:

    0000##00000000000
    000#00#0000000000
    0#00000#000000000
    #0000000#00000000
    000000000#000000#
    0000000000#0000#0
    00000000000#00#00
    000000000000##000

    Das ist zwar das Grundprinzip, aber meine "Zeichnung" in der Aufgabe, zeigt die Rauten, aber keine Nullen.

    Dann solltest du dein Array auch mit ' ' initialisieren und nicht mit 0. Ich würde dir auch dringend raten, das nochmal über Schleifen zu probieren. Der direkte Weg ist zwar sauberer, aber es bringt nichts, dass du dich am nächsten Teil versuchst, wenn du den Umgang mit verschachtelten Schleifen ( ⚠ ) noch nicht verstanden hast.



  • Wenn ich nun mit Leerzeichen intitialisiere, dann sieht mein Code so aus:

    #include<iostream>
    #include<math.h>
    using namespace std;
    
    int main()
    {
     int i, j;
     char array[21][41] = {' '};
    
    system("pause");
    return 0;
    }
    

    Da ich ja anscheinend meine Array nun richtig intialisiert habe wie geht es nun weiter? Muss ich nun die x- bzw- y-Werte des Sinus berechnen lassen?


  • Mod

    bandchef schrieb:

    Ich denke, aber ich kann ja mein Array auch mit " " Leerzeichen initialisieren, oder? Dann erziele ich doch genau den Effekt, oder? Nur isses doch dann ein char, oder?

    Problem ist nur, dass es nicht so einfach ist, ein 2D-Array auf diese Art mit etwas anderem als Null zu initialisieren. Denn an sich, wäre das Leerzeichen (welches ' ' ist, nicht " ") besser als die 0. Deshalb hätte ich die Schleifen bevorzugt.

    Nichtsdestotrotz: Nächste Aufgabe: Wie kann man Werte zwischen 0 und 40 auf das Intervall 0 bis 2*Pi übertragen? Und wie kann man Werte zwischen -1 und +1 auf den Bereich 0 bis 20 umrechnen?



  • ...wäre das Leerzeichen (welches ' ' ist, nicht " ") besser als die 0...

    Beachte meinen letzten Beitrag, ich hab da ' ' stehen...

    Wie kann man Werte zwischen 0 und 40 auf das Intervall 0 bis 2*Pi übertragen?

    Ich schlage das vor (sicher bin ich mir aber nicht): (2*pi)/41

    Und wie kann man Werte zwischen -1 und +1 auf den Bereich 0 bis 20 umrechnen?

    Ich schlage das vor (sicher bin ich mir aber nicht): 1/10; (-1)/10 (Was mit der Nulllinie geschehen soll weiß ich nicht...

    Edit: Ich hab nochmal überlegt, für die y-Werte wärs besser wenn man sagt: -1 bis zu Nulllinie = 0 - 9 und ab der Nulllinie bis +1 = 11 - 20. Die Nulllinie selbst ist dann quasi 10.


  • Mod

    bandchef schrieb:

    ...wäre das Leerzeichen (welches ' ' ist, nicht " ") besser als die 0...

    Beachte meinen letzten Beitrag, ich hab da ' ' stehen...

    Hatte ich noch nicht gelesen. Im vorherigen Beitrag war es noch falsch. Du wirst jedoch feststellen, dass nur der Eintrag array[0][0] ein Leerzeichen ist, der Rest ist 0.

    Wie kann man Werte zwischen 0 und 40 auf das Intervall 0 bis 2*Pi übertragen?

    Ich schlage das vor (sicher bin ich mir aber nicht): (2*pi)/41

    Das ist eine Zahl, keine Antwort. Angenommen meine Zahl zwischen 0 und 40 wäre x, was wäre eine passende Zahl zwischen 0 und 2*pi?:



  • Angenommen meine Zahl zwischen 0 und 40 wäre x, was wäre eine passende Zahl zwischen 0 und 2*pi?:

    Ich denke, es sollte folgen: (2*pi)/x, wobei x aus [0,40]



  • Du wirst jedoch feststellen, dass nur der Eintrag array[0][0] ein Leerzeichen ist, der Rest ist 0.

    So sollte aber jetzt jedes Element ein ' ' haben, oder?

    #include<iostream>
    #include<math.h>
    using namespace std;
    
    int main()
    {
     int i, j;
     char array[21][41];
    
     for(i=0; i<21; i=i+1)
     {
              for(j=0; j<41; j=j+1)
              {
               array[i][j] = ' ';
              }
     }
    
    system("pause");
    return 0;
    }
    

  • Mod

    bandchef schrieb:

    Angenommen meine Zahl zwischen 0 und 40 wäre x, was wäre eine passende Zahl zwischen 0 und 2*pi?:

    Ich denke, es sollte folgen: (2*pi)/x, wobei x aus [0,40]

    Ok, rechnen wir mal nach:
    x=0 ➡ unendlich
    x=1 ➡ 2*pi
    x=2 ➡ pi
    x=3 ➡ 2/3 *pi
    ...
    x=40 ➡ 1/20 *pi

    Das liegt zwar, bis auf x=0, alles zwischen 0 und 2*pi, aber eigentlich wäre es doch schöner etwas zu haben, wo 0 auf 0 abgebildet wird und die 40 auf 2*pi und die Zahlen dazwischen in regelmäßigen Abständen liegen.

    So sollte aber jetzt jedes Element ein ' ' haben, oder?

    Fast. Achte auf die Grenzen.


Anmelden zum Antworten