12

Qt 4.7 QPainter を使用して、ポリゴンなどをウィジェットに描画しています。(0,0) がウィジェットの中心になり、x/y 軸が標準的な「デカルト」の方法で動作するように座標系を変更したいと考えています (つまり、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 ドキュメントと Web を精査した後、私はそれを理解できません!

ありがとう、
クリス

4

4 に答える 4

26

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

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

必要なのは、座標系を次のように変換することだけです。

  • 原点(0,0)からウィジェットの中央に変換します。
    代替テキスト

  • Y 軸-1係数でスケーリングします。
    代替テキスト

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 );

結果:
代替テキスト

2014 年 4 月 7 日更新

この質問はずっと前に尋ねられたもので、それ以来多くのことが変わっています。今日 (2014 年の初め) に同じ質問を自問する人のために、私の個人的な答えは、Qt 4.3 以降、テキストの反転の問題をより簡単に解決できるということです。

あなたが正しいです。同じペインターで描かれているため、テキストも失敗します。可能であれば、すべての反転描画が完了したら、最後にテキストを描画できます。この方法は、テキスト位置の新しい計算のために便利ではありません。また、ペインターの設定をドロップする必要があります。QGraphicsView2D ペインティングが大幅にサポートされているため、を使用することをお勧めします。また、各QGraphicsItem ItemIgnoresTransformationsフラグを設定すると、継承された変換を無視できます (つまり、その位置は親に固定されたままですが、親またはビューの回転、ズーム、またはせん断変換は無視されます)。このフラグは、テキスト ラベル アイテムを水平に保ち、拡大縮小しない場合に役立ちます。そのため、グラフィック ビューが変換された場合でも読み取り可能になります。

于 2010-12-11T09:26:13.813 に答える
3

上記の回答もテキストを反転し、「p」は「b」になります。これを回避するには、テキストを描画する前に y 軸を反転する必要があり、描画時にテキスト位置の y 座標の符号を変更する必要があります。これは少し醜いと思いますが、もっと良い方法はありますか?

于 2012-03-19T12:40:24.270 に答える
2

前述のように、描画テキストも上下逆さまに表示されます。簡単な解決策があります。以下を参照してください。テキスト描画のワールド変換を一時的に無効にします。テキストはもうスケーリングされていないことに注意してください。

描画コードでは、座標 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);
于 2015-09-02T14:03:16.163 に答える