Mauspositionszentriertes Zoomen


  • Gesperrt

    Vorheriges Thema. Habe ich falsch geschrieben, so dass ich es löschen sollte?

    Eigentlich wollte ich heute das mauspositionierte Zoomen coden, habe es bis heute Abend nicht geschafft. Hoffe es klappt noch möglichst bald.


  • Gesperrt

    Dieser Beitrag wurde gelöscht!


  • bist du eigentlich irgendwie grad auf drogen oder so?


  • Gesperrt

    Dieser Beitrag wurde gelöscht!


  • Naja, solange die Schuldgefühle hinterher nicht länger dauern als der Rausch selbst. Jetzt mal aus Empathie gesprochen. Und solange man niemanden dabei verletzt.
    Etwas blöd ist, das beim Aufruf des Forum einem solche Threads ins Gesicht springen. Wobei "Mauspositionszentriertes Zoomen" ja noch herrlich unschuldig, sogar interessant wirken.
    Da gibt es hier schlimmere, vulgärpolitische Triggerüberschriften.


  • Gesperrt

    @zeropage sagte in Mauspositionszentriertes Zoomen:

    Und solange man niemanden dabei verletzt.

    Solange man im Rausch nur im C++ Forum schreibt, sollte es ja eigentlich nicht möglich sein, jemanden physisch zu verletzen.

    @zeropage sagte in Mauspositionszentriertes Zoomen:

    Mauspositionszentriertes Zoomen

    Der Titel ist vielleicht nicht so geglückt. Also es ging darum, wenn man mit dem Mausrad zoomt (skaliert), dass dabei die Mausposition nach dem zoomen an der gleichen Stelle wie zuvor von der gerenderten Grafik ist. Funktioniert jetzt, fand es etwas umständlich, hoffe es geht auch einfacher. Funktioniert zwar, aber mache jetzt Pause davon und gehe es dann später nochmals durch.

    if (event.GetWheelRotation() != 0) 
    {
            glm::vec4 preScaledMousePos = glm::inverse(glm::scale(scale_view)) * glm::inverse(glm::translate(translate_view)) * glm::vec4(mousePos, 1);
    
            int wheel_rotation = event.GetWheelRotation();
            
            scale += static_cast<float>(wheel_rotation) / 1200.f;
            //std::cout << scale << '\n';
            scale_view = vec3(std::exp(scale), std::exp(scale), 1.f);
            
            graphic_engine->GetView()->Scale(scale_view);
    
            glm::vec4 postScaledMousePos = glm::inverse(glm::scale(scale_view)) * glm::inverse(glm::translate(translate_view)) * glm::vec4(mousePos, 1);
    
            auto correction = postScaledMousePos - preScaledMousePos;
            auto back_calc = glm::scale(scale_view) * glm::translate(translate_view) * correction;
    
            translate_view += vec3(back_calc);
        }
    


  • @titan99_ sagte in Mauspositionszentriertes Zoomen:

    glm::vec4 preScaledMousePos = glm::inverse(glm::scale(scale_view)) * glm::inverse(glm::translate(translate_view)) * glm::vec4(mousePos, 1);
    

    Ein kleiner Tip aus der Linearen Algebra, weils mir gerade auf den ersten Blick auffällt: Für invertierbare Matrizen gilt: A1B1=(BA)1A^{-1} \cdot B^{-1} = (B \cdot A)^{-1}. Damit lassen sich solche Ausrücke wie da oben mit nur einer (teuren) Matrixinversion schreiben: glm::inverse(glm::translate(translate_view) * glm::scale(scale_view)) * glm::vec4(mousePos, 1)

    Den Rest hab ich mir nicht angesehen, da geht aber sicher noch einiges, vor allem wenn man bedenkt, dass inverse Translation und Skalierung ziemlich simpel sind (intuitiv Verschiebung mit umgekehrtem, mit 1-1 multipliziertem Translationsvektor oder Skalierung mit 1s1 \over s statt ss). Dafür muss man nicht unbedingt ne Matrix invertieren 😉


  • Gesperrt

    @Finnegan sagte in Mauspositionszentriertes Zoomen:

    A1B1=(BA)1A^{-1} \cdot B^{-1} = (B \cdot A)^{-1}

    glm::vec4 postScaleMousePos = glm::inverse(glm::translate(translate_view) * glm::scale(scale_view)) * glm::vec4(mousePos, 1);

    Vielen Dank, wieder mal etwas gelernt. Mir war bisher vor allem bekannt, dass ABBAA\cdot B \neq B \cdot A gilt. Werde später weitere Möglichkeiten für Verbesserungen und/oder Vereinfachungen versuchen zu finden und bedanke mich auch dazu für die Hinweise.

    War vorher noch an der Skalierung. Also scale macht so je langsamste Mausraddrehung 0.1 Schritte. Mit der Exponentialfunktion finde ich das zoomen einigermassen "angenehm". Bloss ist der Zoom-Faktor in Prozent nicht gerundet auf ganze Zahlen. Mit 10x10^{x} und 1 Schritte aus anderen Gründen nicht so gut. Ich glaube ich mach dazu im Moment eine Denkpause...

    scale += static_cast<float>(wheel_rotation) / 1200.f;
    scale_view = vec3(std::exp(scale), std::exp(scale), 1.f);
    

    (Die Optimierung std::exp nur einmal aufzurufen sehe ich noch, mache ich aber später...)



  • @titan99_ sagte in Mauspositionszentriertes Zoomen:

    Also scale macht so je langsamste Mausraddrehung 0.1 Schritte. Mit der Exponentialfunktion finde ich das zoomen einigermassen "angenehm".

    Hehe... ich hab mich eben noch beim überfliegen wegen der Exponentialfunktion gewundert, weil ich erstmal Code erwartet hätte, der bei jedem Zoom-Schritt um einen konstanten Faktor skaliert. Mir war nicht aufgefallen, dass du den Faktor aus der absoluten Mausrad-Rotation jedes mal neu berechnest. Schrittweises skalieren ist natürich auch eine Exponentialfunktion, was den absoluten Skalierungsfaktor angeht. Alles okay 😉

    Deine Variante ist wahrscheinlich sogar besser, da sie auch korrekt arbeitet, wenn das Mausrad so schnell bewegt wird, dass es in einem Frame mehr als einen Schritt macht. Ich habe hier so eine Maus, wo ich das Mausrad per Knopfdruck für extrem schnelles Scrollen/Zoomen auf freilaufend stellen kann. Ich hatte es schon mit einigen Programmen zu tun, die damit überhaupt nicht klar kamen und sich stattdessen noch lahmarschiger bewegt haben.

    Bloss ist der Zoom-Faktor in Prozent nicht gerundet auf ganze Zahlen. Mit 10x10^{x} und 1 Schritte aus anderen Gründen nicht so gut. Ich glaube ich mach dazu im Moment eine Denkpause...

    Machs besser so wie es "angenehm" ist, wie du schreibst. Mir als Anwender wäre das wichtiger als "schöne" Zahlen. Runde lieber nur die Anzeige des Faktors wenn dir die Zahlen zu krumm und lang sind.


Anmelden zum Antworten