Graphen zeichnen mit Canvas



  • #include <vcl.h>
    #include <list>
    #pragma hdrstop
    using namespace std;
    //---------------------------------------------------------------------------
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
     list<int> hoehen;
     list<int>::iterator lIter;
     Canvas->MoveTo (10, 500);
     for (int i=0; i<100; i++)
     {
      srand(0);
      hoehen.push_back(rand() % 3 - 2);
      Canvas->LineTo(10*1, 500 - 10 * hoehen.back());
     }
    }
    

    Also ich will einen Grapf zeichnen der 100 Punkte hat.
    Die Veränderungen auf der Y-Achse = hoehen soll entweder +10, 0 oder -10 sein.
    Die X-Achse ändert sich pro Schleifendurchlauf um 10.
    Startpunkt ist 10,500.Leider zeigt er bei mir nichts an.
    Kann mir jemand sagen, wieso ich nichts sehe?

    Danke für eure Hilfe.



  • 1. srand() brauchst Du nur einmal initialisieren.
    2. zeichnest Du nur eine senkrechte Linie, da 1 != i in Zeile 15, X-Argument.
    3. Solltest Du in Zeile 14 1 und nicht 2 abziehen.



  • Okay jetzt läuft das soweit, aber mir ist aufgefallen, dass das Programm jetzt nicht +10, 0, -10 vom alten Wert geht, sondern nur vom Ausgangspunkt.
    Wie bekomme ich das den hin?



  • In dem Du den alten Wert in und für Zeile 15 eben zwischenspeicherst und nicht die Konstante 500 verwendest ...



  • list<int> hoehen;
     list<int>::iterator lIter;
     srand(0);
     ghoehe = 500;
     Canvas->MoveTo (10, 500);
     for (int i=0; i<100; i++)
     {
      hoehe = rand() % 3 - 1;
      hoehen.push_back(hoehe);
      ghoehe -= hoehen.back();
      Canvas->LineTo(5 * i, ghoehe * 10);
     }
    

    Das ist nun meine Lösung die auch funktioniert. Jetzt muss ich aber erreichen. Das der Graph beim 100. Durchlauf auch wieder bei 500 endet, aber es darf rand() % 3 - 1; nicht geändert werden.



  • Wenn Du das schaffst, möchte ich das Du für mich eine Runde Lotto spielst.
    🙂



  • Kann mir da vlt jemand helfen?
    Muss ich da einen anderen Ansatz wählen?



  • Beschreibe doch mal genauer, was Du erreichen willst. Mit einem Zufallsgenerator zu einem vorgegebenen Punkt zu steuern ist per se nicht möglich. Man könnte einen Gradienten definieren der den Bereich zu ermittelnder Zahlen so verschiebt, dass Du wieder bei 500 landest. Aber das darf ja auch nicht sein...



  • Also ich habe einen Anfangspunkt 0|0 am Ende möchte ich beim Punkt 100|0 sein.
    Bedingungen:
    1. Y-Wert nicht negativ
    2. der Y-Wert darf sich beim nächsten X-Wert nur um -1,0 oder +1 im Vegleich zum vorherigen X-Wer wechseln

    Bsp:
    0|0, 1|1, 2|1, 3|0, 4|1, .... 99|1, 100|0



  • Na ja, mit ein bißchen Mogeln ist das schon möglich...

    int offset;
    int y = 0;
    for(int x = 0; x < 100; x++)
    {
    	if (y == 0)
    		offset = RandomRange(0, 5);	// Y ist Null, es darf kein negativer Offset erzeugt werden
    		// Als RangeTo 5, um eine Chance auf eine steigende Kurve zu erhöhen (vielleicht passt Dir ein anderer Wert besser, musst Du asprobieren)
    	else
    		offset = RandomRange(5, -1);
    	if (offset > 1) // positiven Offset grundsätzlich auf 1 beschränken
    		offset = 1;
    	if (y - (100 - x) == 0) // wenn wahr, muss die 'Kurve' ab hier permanent fallen, um bei Schritt 100 Y == 0 zu erreichen
    		offset = -1;
    
    	y += offset;
    


  • Ich möchte das aber gerne mit einer Liste machen, den ich will gerne die einzelnen Höhen auch ausgeben können wollen.



  • Ja, und was hindert Dich daran?
    Ich sehe das Problem nicht.



  • list<int> hoehen;
     list<int>::iterator lIter;
     srand(0);
     lIter = hoehen.begin();
     ghoehe = 500;
     Canvas->MoveTo (10, 500);
    int offset;
    int y = 0;
    for(int x = 0; x < 100; x++)
    {
        if (y == 0)
            {
            offset = RandomRange(0, 5);    // Y ist Null, es darf kein negativer Offset erzeugt werden
            }// Als RangeTo 5, um eine Chance auf eine steigende Kurve zu erhöhen (vielleicht passt Dir ein anderer Wert besser, musst Du asprobieren)
        else
            offset = RandomRange(5, -1);
        if (offset > 1) // positiven Offset grundsätzlich auf 1 beschränken
            {
            offset = 1;
            }
        if (y - (100 - x) == 0) // wenn wahr, muss die 'Kurve' ab hier permanent fallen, um bei Schritt 100 Y == 0 zu erreichen
            {
            offset = -1;
            }
    
        y += offset;
    
        Canvas->LineTo(5 * x, y * 10);
        hoehen.insert(lIter, y);
     }
    

    so sieht mein Code nun aus, aber er kennt die Funtkion RandomRange nicht. Muss ich noch irgendeine Bibliothek hinzufügen, wenn ja welche?



  • Ja, die math.hpp.
    Das kann man auch relativ leicht herausfinden. Wenn Du die Hilfe zu RandomRange aufrufst, steht oben links Unit: Math. Das ist der Header, den Du einbinden musst. Enweder mit der Endung .h oder .hpp.
    (Und bevor das Geschrei jetzt losgeht: Ich weiß, das ist so zwar nicht immer ganz richtig, da bestimmte Header über andere Header eigebunden werden müssen und Header aus der Standardbibliothek werden normalerweise auch komplett ohne Angabe der Dateiendung eingebunden, aber für den Anfang sollte es so reichen. 😉 )



  • Hmm jetzt wird der grapf von oben links nach unten rechts gezeichnet, und ich möchte ja das der Ursprung 10,500 ist.

    Was muss ich da ändern?



  • Problem gelöst war nur ein falscher Operator



  • Hi,
    ich wollte mal fragen, wie man BEIM EDITIREN zoomen kann ?

    PS: wenn mir jemand einen guten graphik editor (als code) geben könnte, wäre ich SEHR zufrieden.

    mfg irgendjemand


Log in to reply