Seite 1 von 1

Painter rotieren/skalieren funktioniert nicht

Verfasst: 21. Juni 2011 04:07
von marvel
Hallo nochmal,
mittlerweile sollte der eine oder andere mich in diesem Forum kennen, deswegen möchte ich mich nochmals recht herzlich für eure Geduld und für die nette Hilfe bedanken, denn ohne euch hätte ich wahrscheinlich noch Jahre für meine App gebraucht. Nun, ich bin fast durch mit dem praktischen Teil meiner Diplomarbeit und habe noch Zeit bis Ende diesen Monats alles abzuschließen. Leider stehe ich noch vor einer letzten großen Hürde und wie gesagt, die Zeit drängt !!!!

Ich habe in einem Widget mit dem Painter diverse Muster gezeichnet. Bevor ich diese Muster gezeichnet habe musste ich das Koordinatensystem, welches in der oberen, linken Ecke beginnt, mit setWindow() ändern. Dieses hat beispielsweise einen Wertebereich von x=770 und y=6670 bis x=800 und y=6600. Wie man erkennen kann beginnt die y-Achse mit dem größeren Wert und endet mit einem kleinerem Wert. Das habe ich bewusst so gemacht, damit die Muster korrekt gezeichnet werden, da die Koordinaten für solch ein Koordinatensystem ausgelegt sind. Im nächsten Schritt wollte ich dem Benutzer die Möglichkeit einräumen das Bild rotieren bzw skalieren zu lassen.

Dies habe ich folgendermaßen umgesetzt :

painter->setWindow(770,6670,30,-70);
painter->rotate(10.0);
painter->drawLine(770,6670,800,6600);

Nach meinem Verständnis sollte das Koordinatensystem um 10 Grad rotiert werden und dann gezeichnet werden. Leider passiert nichts bzw es wird einfach nicht gezeichnet. Der gleiche Code ohne das rotate() funktioniert einwandfrei bzw wenn ich ohne setWindow arbeite kann ich rotieren. Habe ich etwas übersehen oder falsch verstanden ? Muss ich irgendwas am Viewport ändern bzw welche Werte müsste ich übernehmen ? Für eure Hilfe wäre ich sehr dankbar.

MfG

marvel

Verfasst: 21. Juni 2011 08:16
von franzf
Weil ein rotate IMMER um (0,0) dreht, nicht "links oben im Fenster" - außer du sagst mit mit translate(), wo der Ursprung sein soll.
Beispiel:

Code: Alles auswählen

#include <QPainter>
#include <QWidget>
#include <QApplication>

class QPaintEvent;

class Window : public QWidget {
    void paintEvent(QPaintEvent*) {
        QPainter p(this);
        p.setRenderHint(QPainter::Antialiasing);
        p.setWindow(-20, -20, width()/2, height()/2);
        p.rotate(40);
        p.drawRect(-5,-5, 10,10);
    }
};

int main(int argc, char** argv) {
    QApplication app(argc, argv);
    Window w;
    w.show();
    return app.exec();
}
Das Kästchen ist um den Ursprung.

Wenn du dir überlegst, wie weit du dein Window vom Ursprung weg setzt, wundert es nicht, dass selbst bei 10° Drehen nichts mehr gezeichnet wird. Naja, gezeichnet wird schon, aber nicht im sichtbaren Bereich.

Verfasst: 22. Juni 2011 21:29
von marvel
Weil ein rotate IMMER um (0,0) dreht, nicht "links oben im Fenster" - außer du sagst mit mit translate(), wo der Ursprung sein soll.
Wenn du dir überlegst, wie weit du dein Window vom Ursprung weg setzt, wundert es nicht, dass selbst bei 10° Drehen nichts mehr gezeichnet wird. Naja, gezeichnet wird schon, aber nicht im sichtbaren Bereich.
Das erklärt einiges :)...

Nun, ich versuche seit Stunden eine Lösung für mein Problem zu finden. Den Ursprung mit translate() zu verschieben und dann zu rotieren bringt auch nichts, da sich auch der Wertebereich den ich mit setWindow setze mitverschieben würde. Wie könnte man das angehen bzw. lösen ?

Verfasst: 22. Juni 2011 22:05
von franzf
marvel hat geschrieben:Wie könnte man das angehen bzw. lösen ?
selber ausrechnen :D
Schau, welchen Bereich du malen wolltest (vor translate und rotate), schau dann, wo der Bereich jetzt liegt, und rechne nun aus, welches Rechteck du tatsächlich malen musst, damit dein "schiefer Ausschnitt" auch ganz gezeichnet wird.

Am besten erstellst du dir dazu ein gaaanz simples Testprojekt, in dem du dich Stück für Stück an die Problematik herantastest. So etwas in einem dicken Projekt mit viel "Code-Rauschen" abseits des eigenlichen Problems ist meist zu kompliziert.

Verfasst: 23. Juni 2011 12:15
von marvel
puhhhhh...harter tobak :)

Nur um sicher zu stellen das ich gedanklich auf dem richtigen Weg bin. Ich setzte erstmal den gewünschten Wertebereich mit setWindow, dann rotiere ich das Koordinatensystem und muss nun durch eine Rechnung herausfinden im welchem Bereich das gezeichnete gelandet ist und das ganze am Ende in den sichtbaren Bereich verschieben ?


So ganz konnte ich deinen Lösungsansatz noch nicht nachvollziehen, es wäre sehr nett wenn du mir das vllt etwas genauer erläutern würdest :)

Verfasst: 23. Juni 2011 20:01
von Troll.Soft
franzf hat geschrieben:
marvel hat geschrieben:Wie könnte man das angehen bzw. lösen ?
Am besten erstellst du dir dazu ein gaaanz simples Testprojekt, in dem du dich Stück für Stück an die Problematik herantastest. So etwas in einem dicken Projekt mit viel "Code-Rauschen" abseits des eigenlichen Problems ist meist zu kompliziert.
Einfach dem Tip von Franz folgen und abseits Deines Projektes ein simples Progrämchen schreiben um alles besser abschätzen zu können.
tschüß
Troll.Soft

Verfasst: 24. Juni 2011 05:38
von marvel
Ich habe euren Ratschlag übernommen und ein kleines Testprojekt angelegt und ein wenig rumgetestet.

void test::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.setWindow(100,100,100,100);

double x = 150;
double y = 150;
double x1,y1;

painter.drawLine(150,100,150,200);
painter.drawLine(100,150,200,150);
painter.drawRect(x,y,10,10);

double angle = 45.0;
double pi = 3.14159265358979323846264338327950288419716939937510;

painter.rotate(angle);

x1 = x * cos(angle * pi / 180) + y * sin(angle * pi / 180);
y1 = -x * sin(angle * pi / 180) + y * cos(angle * pi / 180);

qDebug() << x1 << y1;

painter.drawRect(x1,y1,10,10);
}

Verfasst: 24. Juni 2011 11:48
von Troll.Soft
marvel hat geschrieben:Ich habe euren Ratschlag übernommen und ein kleines Testprojekt angelegt und ein wenig rumgetestet.
super
und nun?
bist Du mit dem Ergebnis zufrieden??
tschüß
Troll.Soft