Zoomen und Zeichnen in einem GUI-Fenster (Qt)



  • Hallo liebes Forum,

    ich zeichne über die QPainter-Klassen Dreiecke in ein Widget.

    Ich kann meine Dreiecke mit gedrückter linker Maustaste verschieben. Ich komme allerdings nicht darauf, wie ich eine Zoom-Funktion realisieren kann. Die Pixelkoordinaten sind nicht wirklich richtig.

    Hat jemand sowas schon mal gemacht? Ich möchte Offset und Zoom vernünftig auf die Mauskoordinaten in meinem Widget rechnen!

    Danke! 🙂

    Viele Grüße,
    anjohn



  • Zum einen sehe ich kein Problem sowas zu implementieren, von dem her kann ich auch nicht nachvollziehen, wo du hier Probleme siehst, vor allem, wenn du das Verschieben schon implementiert hast.

    Und außerdem... Kennst du QGraphicsScene und QGraphicsView? Die können das alles und viel mehr schon von Haus aus.



  • Danke für die Antwort! 🙂

    Diese Klassen kannte ich noch nicht, aber sie klingen interessant und ich werde sie bestimmt noch brauchen, da ich riesige Mengen an Primitiven Rendern möchte. 😉

    Die Grundidee für den Zoom ist, dass bei einem Zoomfaktor von 2.0 ein Pixel nur noch einer halben Längeneinheit entspricht, usw.

    Wenn ich z.B. die Ansicht auf den Punkt (20;40) verschiebe und hundertfach heranzoome, dann befindet sich meine Maus in der Mitte des Bildschirms immer noch an Position (20;40) und 100 Pixel darum ändern sich die Koordinaten höchstens um eine Längeneinheit (z.B. (19;40) oder (20;41)) .......

    Soweit, so gut. Würde ich jedes Pixel nun von Hand einfärben, wäre ich jetzt wohl fertig. Aber ich zeichne ja nun mal mit Qt:

    Interessant sind ja die Translate- und Scale-Funktionen, die auch in der QPainter-Klasse zur Verfügung stehen.
    Aber ich weiß nicht, wie ich die Translate- und Scale-Funktionen von Qt verwenden soll, um so zu zeichnen, wie ich das möchte. Ich habe immer das Gefühl, dass die Scale-Funktion meine Primitiven verschiebt. Male ich in die Mitte des Bildes einen Punkt und zoome, dann wandert dieser weg. An den Koordinaten meines Punktes änder ich nichts!

    Kann man mich verstehen? 😃

    Vor dem Zeichnen mache ich also sowas

    painter.scale(zoom,zoom);
    painter.translate(offsetX+width()/2,offsetY-height()/2);
    

    bzw.

    QTransform matrix(zoom,0,0,0,zoom,0,offsetX+width()/2,offsetY-height()/2*zoom,1);
    painter.setWorldTransform(matrix);
    

    klicke ich auf den Bildschirm, habe ich sowas:

    QVector2D *newPoint = new QVector2D(((event->x()-static_cast<float>(width())/2.0)/zoom-offsetX),(-(event->y()-static_cast<float>(height())/2.0)/zoom+offsetY));
    

    und offsetX und offsetY wären jetzt z.B. besagter Punkt (20;40)...



  • Ja, scale verschiebt die Punkte natürlich. Wenn der Punkt an Position 20/20 war, und du um den Faktor 2 skalierst, ist er danach bei 40/40. D.h., danach musst du verschieben, also ist deine Idee schon richtig. Wie da die Werte konkret aussehen, musst dir halt anschauen oder reindebuggen, hab jetzt keine Lust mich so genau reinzudenken 🙂



  • Ach na klar 🙂

    painter.scale(zoom,zoom);
    painter.translate(lookAtX+static_cast<float>(width())/2.0/zoom,lookAtY-static_cast<float>(height())/2.0/zoom);
    

    wäre jetzt eigentlich die Lösung.

    Male ich in die Mitte des Bildes, dann bleibt nach Zoomen die X-Koordinate nun auch unverändert. Aber der Punkt wandert immer noch nach unten.

    Woran kann das denn liegen? Hat das was mit dem Seitenverhältnis des Widgets zu tun oder mit der Bildschirmauflösung? 😕

    -----Edit-----

    Das Problem war, dass ich in meinen Zeichne-Routinen noch überall paint(Objekt.X , Height-Objekt.y) drin hatte, da man so ohne Scaling schön das Koordinatensystem umdrehen konnte. Das hatte ich vergessen. Der Trick ist, dem Painter die echten Koordinaten à la Paint(Objekt.X , Objekt.Y) zu geben, um dann die Zeichnung entlang der X-Achse mittels einem negativen Scaling-Faktor für Y zu invertieren:

    painter.scale(zoom,-zoom);
    painter.translate(offsetX+width/2.0/zoom,-offsetY-height/2.0/zoom);
    

Log in to reply