Qt GUIプログラミング:QTransform::operator*() を使って2Dグラフィックスを自由自在に操る


QTransform::operator*() は、2D座標変換を表す QTransform オブジェクトを乗算するための演算子です。この演算子は、複数の変換を連続して適用したい場合などに役立ちます。

構文

QTransform result = transform1 * transform2;

上記の例では、transform1transform2 という 2 つの QTransform オブジェクトがあり、その乗算結果を result に格納しています。

乗算の順序

QTransform オブジェクトの乗算は、左から右に行われます。つまり、上記の例では、transform1 の変換が先に適用され、その後に transform2 の変換が適用されます。

変換の種類

QTransform オブジェクトは、以下の種類の変換を表すことができます。

  • アフィン変換
    上記のすべての変換を組み合わせて設定できます。
  • せん断
    shear() 関数を使用して設定できます。
  • 拡大縮小
    scale() 関数を使用して設定できます。
  • 回転
    rotate() 関数を使用して設定できます。
  • 平行移動
    translate() 関数を使用して設定できます。

以下の例では、QTransform オブジェクトを使用して、矩形を 90 度回転し、2 倍に拡大縮小します。

QTransform transform;
transform.rotate(90);
transform.scale(2, 2);

QRect rect(10, 20, 50, 30);
QRect transformedRect = transform.mapRect(rect);

このコードを実行すると、transformedRect は (20, 10, 100, 60) という値になります。

  • 複数の変換を連続して適用する場合は、変換の順序を考慮する必要があります。
  • QTransform オブジェクトの乗算は、非可逆変換を含む場合、元の座標を復元できない場合があります。


#include <QApplication>
#include <QPainter>
#include <QRect>
#include <QTransform>

int main(int argc, char *argv[]) {
  QApplication app(argc, argv);

  QRect rect(10, 20, 50, 30);

  // 回転と拡大縮小を行う変換を作成
  QTransform transform;
  transform.rotate(90);
  transform.scale(2, 2);

  // 変換された矩形を取得
  QRect transformedRect = transform.mapRect(rect);

  // ペイントウィジェットを作成
  QWidget widget;
  widget.resize(300, 200);
  widget.show();

  // ペイントイベントハンドラ
  void paintEvent(QPaintEvent *event) {
    QPainter painter(&widget);

    // 元の矩形を描画
    painter.setPen(Qt::black);
    painter.drawRect(rect);

    // 変換された矩形を描画
    painter.setPen(Qt::red);
    painter.drawRect(transformedRect);
  }

  QObject::connect(&widget, &QWidget::paintEvent, this, paintEvent);

  return app.exec();
}

このコードを実行すると、以下のようになります。

左側が元の矩形、右側が変換された矩形です。

  1. QRect オブジェクトを使用して、元の矩形 (10, 20, 50, 30) を作成します。
  2. QTransform オブジェクトを作成し、rotate() 関数を使用して 90 度回転し、scale() 関数を使用して 2 倍に拡大縮小します。
  3. mapRect() 関数を使用して、変換された矩形を取得します。
  4. QWidget オブジェクトを作成し、resize() 関数を使用してサイズを設定します。
  5. paintEvent() 関数を定義し、元の矩形と変換された矩形を描画します。
  6. connect() 関数を使用して、paintEvent() 関数を paintEvent シグナルに接続します。


代替方法

以下に、QTransform::operator*() の代替方法をいくつか紹介します。

QPainter を使用する

QPainter クラスは、2D グラフィックスを描画するためのクラスです。QPainter には、translate(), rotate()scale() などの変換関数があり、これらの関数を組み合わせて、任意の変換を適用することができます。

QPainter painter(&widget);

painter.translate(100, 50); // 100 ピクセル右へ、50 ピクセル下へ平行移動
painter.rotate(45);       // 45 度回転
painter.scale(2, 2);       // 2 倍に拡大縮小

painter.drawRect(rect);

QMatrix を使用する

QMatrix クラスは、2D 変換を表すもう 1 つのクラスです。QMatrix には、translate(), rotate()scale() などの変換関数があり、これらの関数を組み合わせて、任意の変換を適用することができます。

QMatrix matrix;
matrix.translate(100, 50);
matrix.rotate(45);
matrix.scale(2, 2);

QRect transformedRect = matrix.mapRect(rect);

painter.drawRect(transformedRect);

GLSL シェーダーを使用する

OpenGL を使用している場合は、GLSL シェーダーを使用して、2D 変換を適用することができます。GLSL シェーダーは、より柔軟で強力な方法で変換を適用することができますが、より複雑な知識が必要となります。

  • GLSL シェーダー
    最も柔軟で強力ですが、最も複雑で知識が必要です。
  • QMatrix
    QTransform よりも高速で効率的ですが、QPainter よりも複雑です。
  • QPainter
    シンプルで使いやすいですが、複雑な変換には向いていません。