[GDI+]PointF-Array "Zoomen" /skalieren

  • C#
  • .NET (FX) 4.5–4.8

Es gibt 21 Antworten in diesem Thema. Der letzte Beitrag () ist von mausekeks.

    [GDI+]PointF-Array "Zoomen" /skalieren

    Hallo Leute,

    vor einiger Zeit habe ich dieses Chart erstellt (siehe Anhang).

    Die Daten werden als Array an das Chart übergeben und auf die angegebene Fläche skaliert(siehe Anhang)

    Nun möchte ich diese Zoomen (Bereich soll näher, größer wirken) wobei die Achsen etc unverändert bleiben.

    Also nur die Datenpunkte bzw. das "Signal" soll gezoomt werden.

    Hat jemand eine Idee oder einen Anhaltspunkt für mich wie ich das am besten bewerkstellige?


    LG mausekeks
    Bilder
    • chart.PNG

      23,61 kB, 1.173×237, 145 mal angesehen
    Brain is Loading: 35%
    @mausekeks Komt darauf an, wie Du die Daten darstellst.
    Wenn Du eine PictureBox in einem Panel einbettest, kannst Du über Größe und Position der PictureBox im Panel ein Zoom realisieren.
    Mach Dir zunächst ein einfaches Testprojekt, um dies zu erforschen.
    Wie willst Du zoomen, wenn die Achsen starr bleiben?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Das ganze ist ein usercontrol und wird direkt gezeichnet.
    Ich werde das mit der Picturebox mal testweise ausprobieren.

    Die daten werden als Array an das chart übergeben, die Werte im Array sind die Y-Achs-Punkte und der jewilige Index die X-Achs-Punkte.

    auf mein chart wird das wie folgt skaliert:

    C#-Quellcode

    1. xAchsenPunkt = X-AchsenOriginPoint + i *(xAchsenBreite / Anzahl der Punkte)
    2. yAchsenpunkt = Y-AchsenHöhe * Datenpunkt / Divisor


    Wie würde ich denn z.B am Besten eine flexible Achse realisieren.(nur mal paar ideen)

    Lg Mausekeks
    Brain is Loading: 35%

    mausekeks schrieb:

    Das ganze ist ein usercontrol
    Klar.
    Und dort rein packst Du das "Doppelcontrol".
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    mausekeks schrieb:

    das heißt ich könnte über meinen Chart Bereich eine PictureBox legen
    Wie genau malst Du denn Deine Kurve?
    Was für Controls sind beteiligt?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    @RodFromGermany,

    Meine kurve wird wie folgt gezeichnet

    C#-Quellcode

    1. for (int i = 0; i < PointsCount; i++)
    2. {
    3. xAxisPoint = xAxisOP.X + i * (xAxisWidth / PointsCount);
    4. yAxisPoint = yAxisHeight * data[i].Point / Divisor;
    5. Points[i] = new PointF(xAxisPoint, yAxisOP.Y + yAxisPoint);
    6. }
    7. using (Pen plotPen = new Pen(plotColor, 1))
    8. {
    9. graphics.DrawLines(plotPen, Points);
    10. }


    Das Chart ist komplett selbst erstellt und alles wird gezeichnet, es sind keine anderen Controls (also kein panel auf dem gezeichnet wird) beteiligt.

    LG

    Mausekeks
    Brain is Loading: 35%
    @mausekeks Wo kommt das Graphics-Objekt her?
    Bitmap oder PictureBox?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!

    C#-Quellcode

    1. graphics.Transform
    bzw Koordinatentransformation ist dein Stichwort.
    Dazu muss man auch kein großer Mathematiker sein (auch wenn man beim Lesen des Wikipedia-Artikels zu diesem Thema das Gefühl bekommt), denn die Matrix-Klasse des .NET-Frameworks bringt alles nötige mit, um ganz einfach und schnell deine Abbildung skalieren und verschieben zu können, ohne dass du irgendetwas an deinen Zeichen-Befehlen ändern musst.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    @Arby,

    danke für den Typ das habe ich probiert bin aber zu keinem vernünftigen ergebnis gekommen.
    Das Problem war das das Ganze immer so aussieht wie unten.



    Das Ziel ist es das ich Wirklich nur das Signal größer darstellen möchte.

    Lg Mausekeks
    Brain is Loading: 35%
    Das ist halt der Nebeneffekt, wenn man etwas "größer" darstellen will, der Bereich, in dem man das tut, aber selbst nicht größer ist.
    Dann bastelt man sich z.B. einen oder zwei Scrollbalken dazu, passt deren Min- und Max-Bereiche an die Größe des Fensters und die Größe der Skalierung an und baut in die Transformationsmatrix noch eine Verschiebung abhängig von der Position der Scrollbalken ein.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Oke danke für die Info,

    wie füge ich denn ein Scrollbar ein.

    \\Edit: ich meinte nicht die Scrollbar an sich, sondern die Verschiebung der Matrix durch die Scrollbar.

    LG
    Brain is Loading: 35%

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „mausekeks“ ()

    Kurz und stichpunktartig:
    - Scrollevent
    - Scrollposition auslesen
    - Graphics.TranslateTransform oder Matrix.Translate

    Es gibt halt drei Basis-Transformationen, die sich auch beliebig kombinieren lassen (und dabei ist die Reihenfolge auch von Bedeutung - im Zweifel ausprobieren):
    TranslateTransform ist für das Verschieben des Koordinatensystems verantwortlich, verschiebt also die Grafikausgabe.
    RotateTransform dreht die Ausgabe.
    ScaleTransform skaliert sie.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    Gut habe ich verstanden,
    ich habe die Matrix bereits verschoben, da ich den 0 Punkt auf den Punkt gelegt habe an dem sich die Achsen treffen.

    C#-Quellcode

    1. m = new Matrix();
    2. m.Translate(xAxisOP.X, xAxisOP.Y);
    3. m.Scale(1, -1);
    4. graphics.Transform = m;



    ich habe nun eine Methode erstellt welche als Rückgabewert eine Scrollbar hat:

    Methode für ScrollBar

    C#-Quellcode

    1. private HScrollBar ScrollBar(Graphics g)
    2. {
    3. List<object> MeasureList = Measurement(g);
    4. PointF xAxisStart = (PointF)MeasureList[1];
    5. PointF xAxisEnd = (PointF)MeasureList[2];
    6. int scrollWidth = (int)(xAxisEnd.X - xAxisStart.X);
    7. HScrollBar scroll = new HScrollBar();
    8. scroll.Width = scrollWidth;
    9. scroll.Height = 20;
    10. return scroll;
    11. }



    In meiner Plot-Methode habe ich eine Abfrage welche prüft ob Zoom auf true ist und mir falls ja die Scrollbar an Ort und Stelle erzeugt.
    if-Abfrage in Plot-Methode

    C#-Quellcode

    1. if (zoom)
    2. {
    3. Scroll = ScrollBar(graphics);
    4. Point pos = new Point();
    5. pos.X = plotArea.Left + 28;
    6. pos.Y = plotArea.Top - 20;
    7. Scroll.Location = pos;
    8. Scroll.Scroll += new ScrollEventHandler((sender, e) => ScrollTransform(sender, e, graphics));
    9. Scroll.Minimum = 0;
    10. Scroll.Maximum = (int)xAxisWidth;
    11. this.Controls.Add(Scroll);
    12. }




    Nun noch mein Eventhandler(der code war nur zum testen gedacht)

    Eventhandler

    C#-Quellcode

    1. private void ScrollTransform(object sender, ScrollEventArgs e , Graphics g)
    2. {
    3. List<object> MeasureList = Measurement(g);
    4. PointF xOP = (PointF)MeasureList[0];
    5. m.Translate(xAxisOP.X +10f, xAxisOP.Y +10f);
    6. g.Transform = m;
    7. }




    führe ich den Code aus bekomme ich immer die Fehlermeldung ungültiger Parameter.
    Weist du woran das liegt?


    Lg Mausekeks
    Brain is Loading: 35%

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „mausekeks“ ()

    Äh... beim Zeichnen erzeugst du die Scrollbar? Irgendwie steige ich grad nicht durch.

    Erzeuge die Scrollbar ein(!) Mal, setze bei Größenänderung oder Änderungen am Wertebereich deines Graphen nur deren Min/Max-Werte und im Scroll-Event sorgst du mit Invalidate nur dafür, dass der Ausgabebereich neu gezeichnet werden muss.

    Und im Paint-Ereignis fragst du dann nur noch die Position der Scrollbar ab und verschiebst mit TranslateTransform die Ausgabe entsprechend, bevor du mit dem Malen des Graphen loslegst.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.