線織面の作成(VTKライブラリ) †
VTKライブラリを使用して、2つの円周に対する線織面を作成します。
下図のように、各円周上に対応する点を取り、片方を固定し、もう一方をz-軸を中心にα度だけ回転させ、さらにθを0°から360°まで変えてたときに、その2点を結んだ線が描く面は線織面となります。
α=30°, =90°,=135°としたときは下のプログラムを使用して描画すると以下のようになります。
以下は、プログラムの実行方法です。
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 †
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
-
|
-
|
|
!
|
|
|
|
|
|
-
!
|
|
|
|
|
|
-
!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
!
|
|
|
|
|
-
|
|
!
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
!
|
|
|
|
|
|
|
|
|
|
|
|
!
| #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]); double translation = atof(argv[4]);
auto disk1 = vtkSmartPointer<vtkDiskSource>::New();
disk1->SetInnerRadius(0.0);
disk1->SetOuterRadius(10.0);
disk1->SetRadialResolution(1);
disk1->SetCircumferentialResolution(resolution);
disk1->Update();
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);
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;
}
|
ダウンロードとビルド †
ソースコードとCMakeLists.txtファイル: