ベクトルの表示

投稿者: | 2020年6月30日
The Visualization Toolkit(VTK)を使用しています。
簡単にベクトル表示ができます。
YouTubeチャンネル: yylaboにVTK関連動画を公開しています。

目次

  1. 矢印の表示
  2. 座標点の表示
  3. Boxの表示
  4. 応用例
矢印の表示

例として、3*3*3の座標におけるベクトルを表示します。
vtkPoints::SetNemberOfPointsで座標点の数を設定し、vtkPoints::SetPointで各点の位置を設定します。座標点の番号をid、座標値を(x, y, z)とすると、
vtkPoints::SetPoint(id, x, y, z)
によって設定できます。

VTK_CREATE(vtkPoints, points);
points->SetNumberOfPoints( 3*3*3 );
int id_num = 0;
for( int k = 0; k < 3; k++ ){
 for( int j = 0; j < 3; j++ ){
  for( int i = 0; i < 3; i++ ){
  points->SetPoint( id_num, 10*i, 10*j, 10*k );
  id_num++;
  }
 }
}



次は三成分ベクトルを作成します。
ベクトルの成分数はvtkFloatArray::SetNumberofComponents、ベクトル数はvtkFloatArray::SetNumberofTuplesで設定します。
座標点の番号をid, ベクトル成分を(val_x, val_y, val_z)とすると、
vtkFloatArray::SetTuple3(id, val_x, val_y, val_z)
によって設定できます。

VTK_CREATE(vtkFloatArray, vectors);
vectors->SetNumberOfComponents( 3 );
vectors->SetNumberOfTuples( 3*3*3 );
for( int id_num = 0; id_num < 3*3*3; id_num++){
 vectors->SetTuple3(id_num, val_x, val_y, val_z);
}


ここから、矢印でのビジュアライズの設定を行っていきます。
まず、トポロジカル構造を設定するために、vtkStructuredGridを用います。
先程の座標とベクトルを、
vtkStructuredGrid::SetPoints( points )
vtkStructuredGrid::GetPointData()->SetVectors( vectors )
によって設定します。

VTK_CREATE(vtkStructuredGrid, grid);
grid->SetPoints( points );
grid->SetDimensions(3, 3, 3);
grid->GetPointData()->SetVectors( vectors );


次は、矢印の形状の設定を行います。
vtkArrowSouceを用います。矢印の軸の太さや傘の広がり具合などを設定します。

VTK_CREATE(vtkArrowSource, arrow);
arrow->SetTipLength(0.2);
arrow->SetTipRadius(0.07);
arrow->SetShaftRadius(0.03);


グリフの詳細な設定を行うためにvtkGlyph3Dを用います。
今回は、矢印の縮尺をベクトルのノルムによって決定しています。

VTK_CREATE(vtkGlyph3D, glyphs);
glyphs->SetSource(arrow->GetOutput());
glyphs->SetInput(grid);
glyphs->SetScaleModeToScaleByVector();
glyphs->SetScaleFactor(1);
glyphs->OrientOn();
glyphs->ClampingOff();
glyphs->SetVectorModeToUseVector();
glyphs->SetIndexModeToOff();
glyphs->SetColorModeToColorByVector();


矢印の色調を決定します。
vtkLookupTableを用いて以下の関数を用いて設定することができます。
vtkLookupTable::SetHueRange(hueToLowNorm, hueToHighNorm);
今回はノルムの大きさに比例しながら青から赤の範囲で色を設定します。

VTK_CREATE(vtkPolyDataMapper, glyphMapper);
glyphMapper->SetInputConnection(glyphs->GetOutputPort());
VTK_CREATE( vtkLookupTable, lut );
lut->SetHueRange(0.663, 0.0);
lut->Build();
glyphMapper->SetLookupTable( lut );
glyphMapper->ScalarVisibilityOn();
glyphMapper->SetScalarRange(1, 15);


最後にアクターにマッパーを設定し、マッパーをレンダラに加えます。

VTK_CREATE(vtkActor, glyphActor);
glyphActor->SetMapper(glyphMapper);
renderer->AddActor(glyphActor);

ベクトルの矢印表示はこんな感じになります。

座標点の表示

次に座標点を表示します。
座標点として球を用います。vtkSphereSourceを用います。
球の大きさやカラーも設定できます。

vtkPolyDataMapper* mapper_p[27];
vtkActor* actor_p[27];
for( int i = 0; i < 3; i++ ){
 for( int j = 0; j < 3; j++ ){
  for( int k = 0; k < 3; k++ ){
   int idx = k*9+j*3+i;
   mapper_p[idx] = vtkPolyDataMapper::New();
   actor_p[idx] = vtkActor::New();
   vtkSphereSource* sphereSource = vtkSphereSource::New();
   sphereSource->SetRadius(0.5);
   sphereSource->SetPhiResolution(5);
   mapper_p[idx]->SetInputConnection(SphereSource->GetOutputPort());
   actor_p[idx]->SetPosition(10*i, 10*j, 10*k);
   actor_p[idx]->GetProperty()->SetOpacity(1);
   actor_p[idx]->GetProperty()->SetColor( 0, 0.5, 1.0 );
   actor_p[idx]->SetMapper(mapper_p[idx]);
   sphereSource->Delete();
   renderer->AddActor(actor_p[idx]);
  }
 }
}

座標点をベクトルと一緒に表示させるとこんな感じになります。

Boxの表示

次に、格子に見立てたBoxを表示させます。
立方体であるvtkCubeSourceを用います。
エッジのカラーや透明度を調整することによって、格子のような表現が可能になります。

vtkPolyDataMapper* mapper[27];
vtkActor* actor[27];
for( int i = 0; i < 3; i++ ){
 for( int j = 0; j < 3; j++ ){
  for( int k = 0; k < 3; k++ ){
   int idx = k*9+j*3+i;
   mapper[idx] = vtkPolyDataMapper::New();
   actor[idx] = vtkActor::New();
   vtkCubeSource* cubeSource = vtkCubeSource::New();
   cubeSource->SetXLength(10);
   cubeSource->SetYLength(10);
   cubeSource->SetZLength(10);
   mapper[idx]->SetInputConnection(cubeSource->GetOutputPort());
   actor[idx]->SetPosition(10*i, 10*j, 10*k);
   actor[idx]->GetProperty()->SetOpacity(0.1);
   actor[idx]->GetProperty()->SetEdgeColor( 0, 0, 0 );
   actor[idx]->GetProperty()->SetEdgeVisibility( 1 );
   if( idx == 13 ){
    actor[idx]->GetProperty()->SetColor( 1.0, 0, 0 );
    actor[idx]->GetProperty()->SetOpacity( 0.1);
   }
   actor[idx]->SetMapper(mapper[idx]);
   cubeSource->Delete();
   renderer->AddActor(actor[idx]);
  }
 }
}

応用例

勾配やエネルギーなどのベクトル場を表現するのに便利です。学会や論文の図表をエクセルやワードではなく、VTKで作ることをおススメします。

カテゴリー: VTK

コメントを残す

メールアドレスが公開されることはありません。