14

こんにちは私は三角形を別の三角形に変換できるようにするアフィン変換を作成しようとしています。私が持っているのは2つの三角形の座標です。手伝って頂けますか?

Adam Rosenfieldの回答に続いて、方程式を自分で解くのに退屈している人のために、このコードを思いつきました。

public static AffineTransform createTransform(ThreePointSystem source,
            ThreePointSystem dest) {        
    double x11 = source.point1.getX();
    double x12 = source.point1.getY();
    double x21 = source.point2.getX();
    double x22 = source.point2.getY();
    double x31 = source.point3.getX();
    double x32 = source.point3.getY();
    double y11 = dest.point1.getX();
    double y12 = dest.point1.getY();
    double y21 = dest.point2.getX();
    double y22 = dest.point2.getY();
    double y31 = dest.point3.getX();
    double y32 = dest.point3.getY();

    double a1 = ((y11-y21)*(x12-x32)-(y11-y31)*(x12-x22))/
                ((x11-x21)*(x12-x32)-(x11-x31)*(x12-x22));
    double a2 = ((y11-y21)*(x11-x31)-(y11-y31)*(x11-x21))/
                ((x12-x22)*(x11-x31)-(x12-x32)*(x11-x21));
    double a3 = y11-a1*x11-a2*x12;
    double a4 = ((y12-y22)*(x12-x32)-(y12-y32)*(x12-x22))/
                ((x11-x21)*(x12-x32)-(x11-x31)*(x12-x22));
    double a5 = ((y12-y22)*(x11-x31)-(y12-y32)*(x11-x21))/
                ((x12-x22)*(x11-x31)-(x12-x32)*(x11-x21));
    double a6 = y12-a4*x11-a5*x12;
    return new AffineTransform(a1, a4, a2, a5, a3, a6);
}
4

4 に答える 4

14

ここでは2Dについて話していると仮定します。アフィン変換行列には、次の9つの値が含まれています。

    | a1 a2 a3 |
A = | a4 a5 a6 |
    | a7 a8 a9 |

3つの入力頂点、、、がありx1x2変換x3すると、、、にy1なりy2ますy3。ただし、同次座標で作業しているため、に適用Ax1ても必ずしも得られるとは限りませんy1-の倍数が得られy1ます。したがって、次の方程式を使用して、未知の乗数、、、およびもありk1ますk2k3

A * x1 = k1 * y1
A * x2 = k2 * y2
A * x3 = k3 * y3

これらはそれぞれベクトルであるため、実際には12個の未知数に9個の方程式があり、解は制約が不足します。a7=0、、、a8=0およびが必要な場合a9=1、解は一意になります(入力点が(、、 1)の場合、出力点は常に同次座標1になるため、この選択は自然ですxyしたがって、結果の変換は次のようになります。 2x2変換と変換のみ)。

したがって、これにより方程式は次のようになります。

a1 * x11 + a2 * x12 + a3 = k1 * y11
a4 * x11 + a5 * x12 + a6 = k1 * y12
                   1 = k1
a1 * x21 + a2 * x22 + a3 = k2 * y21
a4 * x21 + a5 * x22 + a6 = k2 * y22
                   1 = k2
a1 * x31 + a2 * x32 + a3 = k3 * y31
a4 * x31 + a5 * x32 + a6 = k3 * y32
                   1 = k3

したがって、k1= k2= k3= 1.これらを接続して行列形式に変換すると、次のようになります。

| x11 x12 1 0 0 0 | | a1 | | y11 |
| x21 x22 1 0 0 0 | | a2 | | y21 |
| x31 x32 1 0 0 0 | * | a3 | = | y31 |
| 0 0 0 x11 x12 1 | | a4 | | y12 |
| 0 0 0 x21 x22 1 | | a5 | | y22 |
| 0 0 0 x31 x32 1 | | a6 | | y32 |

この6x6の連立方程式を解くと、アフィン変換行列が得られますA。ソース三角形の3つのポイントが同一線上にない場合にのみ、独自のソリューションが得られます。

于 2009-07-11T18:04:22.167 に答える
2

ねえ、みんな、一般性を失うことなく、2つの三角形を1つの頂点として原点にする(後でアフィンシフトに取り組むことができます)ので、それらは点0、a、b、c、dで定義され、次に行列NMによる点x

どこ

M = reverse(ab)<---これは、点abを列とする2x2行列です。

N =(cd

それはそれをする必要があります。

于 2009-07-11T18:10:26.413 に答える
1

私がこれを正しく理解していれば、三角形のサイズと角度は同じなので、(少なくとも)1つの共通点を持つように三角形を変形できるはずです。この後、それらは回転のみが異なるか、ミラーリングできるはずなので、三角形の線の間の角度を取得してこれらを回転させてみて、どの角度も機能しない場合は三角形の1つをミラーリングできます。

編集:OK、それだけでは不十分です。アフィン変換にはせん断とスケーリングも含まれる可能性があります...スケーリングは簡単に行うことができ、線の長さを分割するだけで、三角形の対応する線に関する情報も得られますが、せん断はもっと難しくなる...

OTOH、あなたはこれのためにいくつかの方程式系を解くことができませんでしたか?結局のところ、変換行列と3つのポイント(新旧)が必要です...

于 2009-07-11T17:59:01.010 に答える
1

問題を一連の方程式として定式化し、それを解くだけです。

P1 * M = P1'
P2 * M = P2'
P3 * M = P3'

M次のような3x3マトリックスです。

[m00, m01, m02;
 m10, m11, m12;
 0  ,   0,   1]

そしてP_iタプル[k*x_i, k*y_i, k](同次座標)です...

これで、上記の3つの行列方程式を拡張して、m_ijas incognitsを使用して新しいシステムを作成し、それを解くことができますが、何かが欠けていない場合(そしておそらく私がそうである場合)、完全に指定するにはさらに1ポイント必要です。変換しないと、自由度が増します(もちろん、修正することもできます)。

于 2009-07-11T18:03:41.047 に答える