メインコンテンツに移動

座標変換

vtkStructuredGridでは, 線形座標変換を定義することができます.サンプルのfilter_1です.サンプルでは, vtkMultiBlockDataSetであるbodyに, 構造格子vtkStructuredGridがいくつか入ったものを作成します. こやつを, 線形変換しましょう.

Affine変換

Affine変換を行うことができます. 同次座標表示で

\[ \begin{bmatrix} a_{11}&a_{12}&a_{13}&b_1\\a_{21}&a_{22}&a_{23}&b_2\\a_{31}&a_{32}&a_{33}&b_3\\0&0&0&1 \end{bmatrix} \begin{bmatrix} x_1\\x_2\\x_3\\1\end{bmatrix} \]による変換が可能です.

まずはMatrixを作成:

auto myMatrix=vtkSmartPointer<vtkMatrix4x4>::New();
myMatrix->Zero();
myMatrix->SetElement(0,0,1.0);//a_11
...
myMatrix->Print(std::cout);

これで

vtkMatrix4x4 (0x10340dcf0)
Elements:
    1 0.1 0 0
    0 1   0 0
    0 0   1 0
    0 0   0 1 ​​​

が得られる.

Transformを作成

auto myTransform=vtkSmartPointer<vtkTransform>::New();
myTransform->SetMatrix(myMatrix);

これでmyMatrixを変換行列とする線形変換が定義できる. 行列以外に, 回転とかスケールとかで指定する方法もある.

Transformを確認

myTransform->Print(std::cout);

これにより, 変換行列をゲットできます:

vtkTransform (0x1032e2f00)
Debug: Off
...
    Elements:
        2 0 0 0
        0 1 0 0
        0 0 1 0
        0 0 0 1 

まあこんな感じですわ

TransformFilterを作成

Transformを実行するフィルターを作成します.

auto myFilter=vtkSmartPointer<vtkTransformFilter>::New();
auto vtkData=body->GetBlock(idom);//idom番目のvtkStructuredGridを取得
myFilter->SetInputData(vtkData);
myFilter->SetTransform(myTransform);
myFilter->Update();//パイプラインを走らせます
auto res=myFilter->GetOutput();
vtkData->ShallowCopy(res);//オリジナルを書き換えておきます.

これで,こんな感じに菱形の領域ができました:

a

どうせなら中身も変換

上の方法では, 幾何形状は変換されますが, PointData, CellDataにベクトルやテンソルがあっても, 変換されません.

設定により3Dベクトルまでは同様に変換できるらしいんですが, テンソルは無視するクソ仕様なので,役に立たないかもですね.