Coords & e.Location

  • C#
  • .NET 4.5

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

    Coords & e.Location

    Hallo liebe Community,

    ich habe mal wieder ein Problem vil. kann mir (wie sonst auch^^) ja jemand weiterhelfen.

    Ich habe ein Chart erstellt welches eine positive Y-Achse als auch eine negative Y-Achse hat. (bzw. eine Achse mit + & - Bereich).

    Nun möchte ich mir wenn ich mit der Maus über einen Punkt fahre, das er mir diesen in einem ToolTip anzeigt mit den entsprechenden Werten.

    Ich habe den Coordinaten Ursprung verschoben wie auf dem Anhang zu sehen (roter dicker punkt).

    Wie realisiere ich es das ich auch die Negativen Werte angezeigt bekomme, da in der Form der Cooridnaten Ursprung oben links ist und im Formberiech ja keine negativen Achsen besitzt?

    [Edit:] Das Chart ist ein Usercontrol und wird nicht in der Form direkt gezeichnet o. ä.

    Ich hoffe meine Frage ist verständlich

    LG Mausekeks
    Bilder
    • oszilloskop.PNG

      6,98 kB, 861×346, 24 mal angesehen
    Brain is Loading: 35%
    @mausekeks Rein prinzipiell:
    Diese Transformation besteht aus zwei Teilen.
    • Lege den Ursprung in den roten Punkt,
    • Skaliere die Achsen auf Dein Maß.
    Das erste ist ein linearer Offset auf die Mauskoordinate, das zweite ein Faktor für x und einer für y.
    Den Offset solltest Du aus den Properties des Controls bekommen, den Rest aus den Daten selbst.
    Arbeite im MouseMove-Event des UserControls, gib die Koordinaten zunächst dynamisch in einem Label aus.
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    Arbeite mit 2d-Transformationen. Deine Darstellung benutzt zwei solcher Transformationen (die man zu einer zusammenfassen kann): Translation (Verschiebung) und Skalierung. Die Skalierung in x beträgt dabei 1.0 und in y ist sie -1.0, dadurch ergibt sich die positive y-Achse von unten nach oben (anstelle von Form-Koordinaten, die ihren Ursprung oben links haben und in y nach unten größer werden).

    Berechne also eine 2d-Matrix, die diese beiden Transformationen beinhaltet, um den Graphen auszugeben, dann kannst du in Nachhinein mit ihrer Inversen aus den Mauskoordinaten wiederum die Position im Graphen berechnen.

    Der Namensraum System.Drawing enthält übrigens bereits fertige Klassen für solche Matrizen und Berechnungen.
    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 die Antwort.

    Ja ich habe den Koordinaten ursprung mit

    C#-Quellcode

    1. graphics.TranslateTransform(xAxisOP.X,xAxisOP.Y)
    verschoben
    und mit

    C#-Quellcode

    1. ​graphics.ScaleTransform(1, -1);
    die skalierung verändert.

    Ich muss nur leider gestehen das ich mit diesen Mathematischen begriffen leider nicht recht was Anfangen kann da ich weder ausreichend Mathematik in der Schule hatte und auch nicht studiert habe ^^
    Aber ich werde mich jetzt mal einlesen in Matrizen etc.

    Lg Mausekeks
    Brain is Loading: 35%
    Da die Klassen das ganze für dich bereits übernehmen, ist das ziemlich einfach:

    C#-Quellcode

    1. Matrix m = new Matrix();
    2. m.Translate(xAxisOP.x, xAxisOP.y);
    3. m.Scale(1, -1);
    4. // Inverse berechnen:
    5. Matrix inverse = m.Clone();
    6. inverse.Invert();


    und dann vorm Zeichnen:

    C#-Quellcode

    1. graphics.Transform = m;


    Im MouseMove-Event (oder welches Mouse-Event auch immer):

    C#-Quellcode

    1. Point p = e.Location;
    2. inverse.TransformPoints(new Point[] { p });
    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

    Mit vor dem zeichnen meinst du bevor irgendetwas gezeichnet wird oder bevor Daten geplottet werden.

    [Edit:] Hab es hinbekommen mit der Matrix, versthe ich das jetzt richtig das er im MouseMOve event alle locations jezt auf die matrix umrechnet ?


    LG Mausekeks
    Brain is Loading: 35%

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

    mausekeks schrieb:

    versthe ich das jetzt richtig das er im MouseMOve event alle locations jezt auf die matrix umrechnet ?

    Mit dem geposteten Code sollte in p die Mausposition in Graph-Koordinaten enthalten sein, ja. Probier's aus, ob's stimmt.
    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.

    mausekeks schrieb:

    meinst du mit faktor, um welche werte ich das koordinatensystem verschoben hab?
    What :?:
    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).
    VB-Fragen über PN / Konversation werden ignoriert!
    @Arby,

    Danke hat geklappt, hab nur etwas gebraucht um die Funktionsweise zu verstehen.

    Eine frage am Rande allerdings noch:

    Ich prüfe momentan ob mein Cursor auf einem Punkt liegt wie folgt:

    Spoiler anzeigen

    C#-Quellcode

    1. protected override void OnMouseMove(MouseEventArgs e)
    2. {
    3. if(showtooltips == true && data != null && listPoints != null)
    4. {
    5. Point p = e.Location;
    6. Point[] inversePoints = { p };
    7. bool overpoint = false;
    8. if (inverse != null)
    9. {
    10. inverse.TransformPoints(inversePoints);
    11. p = inversePoints[0];
    12. Debug.WriteLine("X-Coord: " + p.X + Environment.NewLine + "Y-Coord: " + p.Y);
    13. for(int i= 0; i < listPoints.Length; i++)
    14. {
    15. if(Point.Round(listPoints[i]) == p)
    16. {
    17. overpoint = true;
    18. tooltipmessage = "X-Coordinate: " + listPoints[i].X + Environment.NewLine;
    19. tooltipmessage += "Y-Coordinates: " + listPoints[i].Y;
    20. tip.IsBalloon = true;
    21. tip.SetToolTip(this,tooltipmessage);
    22. }
    23. if(overpoint == true)
    24. {
    25. break;
    26. }
    27. }
    28. if (overpoint == false)
    29. {
    30. tip.Hide(this);
    31. }
    32. }
    33. }
    34. base.OnMouseMove(e);
    35. }



    Dies klappt auch, da aber die Punkte mit einem Pen

    C#-Quellcode

    1. Pen pen = new Pen(Color.Black, 1)


    gezeichnet sind ist die erkennungsrate doch etwas naja Mangelhaft da es schwer ist mit dem Cursor auf einen expliziten Punkt zu treffen.

    [Edit]: Die Linien wurden mit dem Stift gezeichnet, sry ich muss auf meine Ausdrucksweise achten ^^ will ja keine falschen / irritierenden angaben machen.[EndEdit]

    Hat jemand eventuell eine Idee wie man das ein besser gelöst bekommt ohne die Stiftdicke zu erhöhen.


    LG
    Brain is Loading: 35%

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

    Ich vermute mal, dein Problem basiert auf diesem Vergleich:

    mausekeks schrieb:

    C#-Quellcode

    1. if(Point.Round(listPoints[i]) == p)


    Wollte schon wieder nen ganzen Roman schreiben um Lösungen zu bieten, aber eigentlich wäre das deine Aufgabe. Ich beschränke mich daher im Kern auf den zugrundeliegenden Tipp, deine listPoints nicht direkt mit p zu vergleichen, sondern bei der Suche nach dem richtigen Element in deinem listPoints-Array auch Abweichungen mit einer zu definierenden Toleranz zuzulassen.

    Ja, das bedeutet mehr Rechenaufwand, aber dafür hat man doch schließlich einen Computer und die Möglichkeit, ihn zu programmieren... ;)
    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.