7

与えられた 4 ポイントが次の結果であるとします。

QPolygon poly = transform.mapToPolygon(QRectF(0, 0, 1, 1));

どうすれば見つけられますQTransform transformか? (さらに良い:任意のソース長方形も与えられます)

動機:遠近法で歪んだ座標系で描画される画像の 4 つの頂点が与えられた場合、QPainter を使用して画像を描画するにはどうすればよいですか?

問題の図解

これは GIMP の問題を示すスクリーンショットで、レイヤーの 4 つのコーナーを移動することでレイヤーを変換できます。これにより、透視変換が行われます。Qtアプリケーションでもまったく同じことをしたいです。QTransform はアフィン変換に限定されず、透視変換も処理できることを知っています。

4

2 に答える 2

3

でこれを行うことができるはずですQTransform.squareToQuadQPolygonF変換したいものを渡すだけです。

私は時々、squareToQuad で自分のやりたいことを実行するのに問題があり、QTransform.quadToQuad代わりに使用して、独自の開始クワッドを定義する必要がありましたが、もっと運がいいかもしれません。

于 2012-07-25T17:22:22.550 に答える
1

変換行列を段階的に計算する解決策を見つけたと思います。

// some example points:
QPointF p1(1.0, 2.0);
QPointF p2(2.0, 2.5);
QPointF p3(1.5, 4.0);
QPointF p4(3.0, 5.0);

// define the affine transformation which will position p1, p2, p3 correctly:
QTransform trans;
trans.translate(p1.x(), p1.y());
trans.scale(p2.x() - p1.x(), p3.y() - p1.y());
trans.shear((p3.x() - p1.x()) / trans.m11(), (p2.y() - p1.y()) / trans.m22());

これまで、trans は平行四辺形変換を記述していました。このパラレログラム内で、次のステップで (比較的) p4 を見つけます。これは、トランスの反転を伴わない直接式を使用して実行できると思います。

// relative position of the 4th point in the transformed coordinate system:
qreal px = trans.inverted().map(p4).x();
qreal py = trans.inverted().map(p4).y();

// this defines the perspective distortion:
qreal y = 1 + (py - 1) / px;
qreal x = 1 + (px - 1) / py;

xyを説明するのは困難です。そのうちの 1 つだけ (もう 1 つを に設定1) を指定すると、これは only の相対的なスケーリングを定義しますp4。しかし、x と y の両方の透視変換の組み合わせ、x と y の意味は難しいです。試行錯誤で数式を見つけました。

// and thus the perspective matrix:
QTransform persp(1/y, 0, 1/y-1,
                 0, 1/x, 1/x-1,
                 0, 0, 1);

// premultiply the perspective matrix to the affine transformation:
trans = persp * trans;

いくつかのテストでは、これが正しい結果につながることが示されました。ただし、2 つの点が等しい場合や、そのうちの 1 つが他の 2 つの点の間の線分上にある場合などの特殊なケースはテストしていません。このような状況では、このソリューションは壊れる可能性があると思います。

したがって、ポイント座標, ... ,が与えられた場合、マトリックス値m11, m12...の直接式を検索します。m33p1.x()p1.y()p4.x()p4.y()

于 2012-07-16T22:53:02.890 に答える