*線織面の作成(VTKライブラリ) [#kfb39c21]

[[VTK:http://www.vtk.org]]ライブラリを使用して、2つの円周に対する線織面を作成します。

下図のように、各円周上に対応する点を取り、片方を固定し、もう一方をz-軸を中心にα度だけ回転させ、さらにθを0°から360°まで変えてたときに、その2点を結んだ線が描く面は線織面となります。

#ref(offset.png,center,nowrap,40%,線織面のパラメータ表示);
#ref(offset.png,center,nowrap,50%,線織面のパラメータ表示);

α=30°, =90°,=135°としたときは下のプログラムを使用して描画すると以下のようになります。

#ref(ruled_surfaces.png,center,nowrap,80%,線織面);

以下は、プログラムの実行方法です。

  RuledSurfaceFilter.exe radius resolution angle(degree) translation

プログラムの引数の意味は以下となります。

|radius|2つの円の半径|
|resolution|円周上の点数(解像度)|
|angle(degree)|オフセットする角度|
|translation|2つの円周間の距離(z軸方向)|

例えば、α=135°のときは、以下のような実行になります。

  RuledSurfaceFilter.exe 10.0 100 135.0 20.0


**RuledSurfaceFilter.cxx [#u94070ad]
#code(c){{
#include <vtkSmartPointer.h>

#include <vtkDiskSource.h>
#include <vtkPolyLine.h>
#include <vtkRuledSurfaceFilter.h>
#include <vtkTransform.h>
#include <vtkTransformPolyDataFilter.h>
#include <vtkSTLWriter.h>

#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCellArray.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkCamera.h>

int main(int argc, char *argv[])
{
  if (argc != 5)
  {
    std::cout << "Required parameters: radius resolution angle(degree) translation" << std::endl;
    return EXIT_FAILURE;
  }

  double radius = atof(argv[1]);
  int resolution = atoi(argv[2]);
  double angle = atof(argv[3]); // degree
  double translation = atof(argv[4]);

  // Create first disk source.
  auto disk1 = vtkSmartPointer<vtkDiskSource>::New();
  disk1->SetInnerRadius(0.0);
  disk1->SetOuterRadius(10.0);
  disk1->SetRadialResolution(1);
  disk1->SetCircumferentialResolution(resolution);
  disk1->Update();

  // Create second disk source.
  auto disk2 = vtkSmartPointer<vtkDiskSource>::New();
  disk2->SetInnerRadius(0.0);
  disk2->SetOuterRadius(10.0);
  disk2->SetRadialResolution(1);
  disk2->SetCircumferentialResolution(resolution);

  auto transform = vtkSmartPointer<vtkTransform>::New();
  transform->RotateWXYZ(angle, 0, 0, 1);
  transform->Translate(0, 0, translation);

  auto transformFilter = vtkSmartPointer<vtkTransformPolyDataFilter>::New();
  transformFilter->SetTransform(transform);
  transformFilter->SetInputConnection(disk2->GetOutputPort());
  transformFilter->Update();

  auto points = vtkSmartPointer<vtkPoints>::New();

  auto polyLine1 = vtkSmartPointer<vtkPolyLine>::New();
  polyLine1->GetPointIds()->SetNumberOfIds(resolution+1);
  for (int i = 0; i < resolution; ++i)
  {
    points->InsertNextPoint(disk1->GetOutput()->GetPoint(2*i+1));
    polyLine1->GetPointIds()->SetId(i, i);
  }
  polyLine1->GetPointIds()->SetId(resolution, 0);

  auto polyLine2 = vtkSmartPointer<vtkPolyLine>::New();
  polyLine2->GetPointIds()->SetNumberOfIds(resolution+1);
  for (int i = 0; i < resolution; ++i)
  {
    points->InsertNextPoint(transformFilter->GetOutput()->GetPoint(2*i+1));
    polyLine2->GetPointIds()->SetId(i, resolution + i);
  }
  polyLine2->GetPointIds()->SetId(resolution, resolution);
  
  auto polyLines = vtkSmartPointer<vtkCellArray>::New();
  polyLines->InsertNextCell(polyLine1);
  polyLines->InsertNextCell(polyLine2);

  auto polydata = vtkSmartPointer<vtkPolyData>::New();
  polydata->SetPoints(points);
  polydata->SetLines(polyLines);

  vtkSmartPointer<vtkRuledSurfaceFilter> ruledSurfaceFilter =
    vtkSmartPointer<vtkRuledSurfaceFilter>::New();
  ruledSurfaceFilter->SetInputData(polydata);
  ruledSurfaceFilter->SetResolution(resolution+1, resolution+1);
  ruledSurfaceFilter->SetRuledModeToResample();
  ruledSurfaceFilter->Update();

  auto writer = vtkSmartPointer<vtkSTLWriter>::New();
  writer->SetFileName("ruled_surface.stl");
  writer->SetInputData(ruledSurfaceFilter->GetOutput());
  writer->Write();

  vtkSmartPointer<vtkRenderer> renderer = 
    vtkSmartPointer<vtkRenderer>::New();
    
  vtkSmartPointer<vtkRenderWindow> renderWindow = 
    vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  
  vtkSmartPointer<vtkRenderWindowInteractor> interactor = 
    vtkSmartPointer<vtkRenderWindowInteractor>::New();
  interactor->SetRenderWindow(renderWindow);
  
  vtkSmartPointer<vtkPolyDataMapper> mapper =
    vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInputConnection(ruledSurfaceFilter->GetOutputPort());

  vtkSmartPointer<vtkActor> actor =
    vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);
  actor->GetProperty()->SetColor(0.89, 0.81, 0.34);
 
  // Add the actors to the renderer, set the background and size
  renderer->AddActor(actor);
  renderer->SetBackground(.3, .4, .5);

  renderer->ResetCamera();
  renderer->GetActiveCamera()->Azimuth(60);
  renderer->GetActiveCamera()->Elevation(60);
  renderer->GetActiveCamera()->Dolly(1.2);
  renderer->ResetCameraClippingRange();

  renderWindow->Render();
  interactor->Start();

  return EXIT_SUCCESS;
}

}}

**ダウンロードとビルド [#m8119037]
ソースコードと'''CMakeLists.txt'''ファイル:
#ref(RuledSurface.zip)

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS