2010-12-10 21 views
10

Qt 4.7 QPainterを使用して、ポリゴンなどをウィジェットに描画しています。私は座標系を変更して、(0,0)が私のウィジェットの中心にあり、x/y軸が標準的な "デカルト"のやり方で動作するようにしたいと考えています(つまりyは "上がり"ダウン")。言い換えれば、座標を「コンピュータグラフィックス」のように「数学」にしたいと思います。 :-)ウィンドウ/ビューポートを使ってQPainterのy軸を反転する

私は、自分の座標で直接描画メソッドを呼び出すことができればいいと思うので、自分自身で計算するのではなく、setViewport()とsetWindow()を使ってこれを実行しようとしています。

は、ここで私はこれまで持っているものです:それは画面の真ん中に素敵な青い四角を描くことに

// Setup coordinates 
double screenWidth = width(); 
double screenHeight = height(); 

double windowWidth = 100.0; 
double windowHeight = (screenHeight/screenWidth) * windowWidth; 

painter.setViewport(0, 0, screenWidth, screenHeight); 
painter.setWindow(-(windowWidth/2.0), -(windowHeight/2.0), windowWidth, windowHeight); 

// Draw stuff 
painter.setPen(Qt::NoPen); 
painter.setBrush(Qt::blue); 
painter.drawRect(-10, -10, 20, 20); 

は、今これは、うまく動作します。問題は、左上隅が(-10、-10)と言わなければならないということです。私はそれを作ることができるようにしたいと思っています(-10、10)、それはデカルトの座標になるでしょう。

私はこの「y軸フリップ」を得るためにsetWindow/setViewportを使いこなそうとしましたが、役に立たなかった。これは本当に簡単なやり方のようですが、Qtのドキュメントとウェブを精査した後、私はそれを理解できません!

おかげで、
クリス

答えて

22

使用クラスQMatrix。 2D変換を指定します。 QMatrixQPainterに設定されます。

しかし、あなたはデカルトcoordsのにウィジェットのCOORDSを変換する場合は、あなたのケースで、あなたは-10,10((ないで(-10、-10)で最初のポイントを配置する必要がありますが、覚えておいてください) Y軸は、今までを成長し、X軸は今を成長するので、(0,0を中心とする矩形を描画する)あなたが言及したようになかったです。
alt text

  • :ウィジェットの真ん中に

    • (0,0)から起源を翻訳

      必要なのは、あなたのCOORDシステムをこのように変換することですスケールY軸-1因子:
      ここalt text

    ウィジェットのpaintEvent()関数に入力したコードは、次のとおりです

    QPainter pn(this); 
    
    int w_2 = width()/2; 
    int h_2 = height()/2; 
    
    { // X- and Y-Axis drawing 
        pn.setPen(Qt::blue); 
        pn.drawLine(0, h_2, width(), h_2);  // X-Axis 
        pn.drawLine(w_2, 0 , w_2, height()); // Y-Axis 
    } 
    
    QMatrix m; 
    m.translate(w_2, h_2); 
    m.scale(1, -1); 
    
    pn.setMatrix(m); 
    pn.setPen(Qt::NoPen); 
    pn.setBrush(QBrush(Qt::blue, Qt::Dense4Pattern)); 
    pn.drawRect(-10, -10, 20, 20); 
    

    結果:
    alt text

    更新2014年4月7日

    この長い間前に質問されたそれ以来多くのことが変わりました。今日(2014年の初めに)同じ質問をする人にとって、私の個人的な答えは、Qt 4.3以降では、より簡単に文字が反転する問題を解決することができるということです。

    あなたは正しいです。テキストは同じペインタで描画されるため、塗りつぶされます。可能であれば、反転したすべての図面が終了したら、最後にテキストを描画することができます。この方法は、テキスト位置の新しい計算のために納得のいくものではありません。また、ペインタの設定を削除する必要があります。 2Dペインティングを大いにサポートしているので、QGraphicsViewを使用することをお勧めします。また、それは継承変換を無視することを可能に設定することができ、各QGraphicsItemItemIgnoresTransformationsフラグのために(すなわち、その位置はまだ親に固定されているが、親またはビューの回転、ズームまたは剪断変換が無視されます)。このフラグは、水平およびスケーリングされていないテキストラベルの項目を維持するのに便利ですので、グラフィックスビューは

  • +1

    ただし、テキストを反転することもできますが、修正する必要があります。それはほとんど望ましくない! – bkausbk

    +0

    ありがとうございます;) – Stormenet

    3

    を変換された場合、彼らはまだ読めるとなります上記の答えはまた、「P」フリップのテキストは、「B」になります。テキストが描画される前にy軸を元に戻す必要がなく、描画するときにテキスト位置のy座標を変更する必要があります。これはちょっと醜いと思いますが、もっと良い方法がありますか?

    1

    前述のように、描画テキストも逆さまに反転して表示されます。それには簡単な解決策があります。下記を参照してください。我々は一時的にテキストの描画のための世界の変換を無効にします。テキストはもうスケーリングされないことに注意してください。我々は座標QPointF P上のテキストを描画したいあなたのペイントコードで

    Painter pn(this); 
    
    // calculate the point with the transform 
    QPointF p = pm.transform().map(P); 
    
    // Disable Transform temporary 
    pn.setWorldMatrixEnabled(false); 
    
    // draw it ordinary, no scaling etc 
    pn.drawText(p, QString("HI FRIENDS!")); 
    
    // Enable the transform again 
    pn.setWorldMatrixEnabled(true); 
    
    関連する問題