天天看點

vtk 二維愛心的制作

 本文是用vtk來實作的,首先通過公式計算出二維愛心的點,然後利用vtkParametricSpline類來将點連接配接起來,最後通過建立二維三角剖分然後再加了一些限制就完成啦,效果如下:

vtk 二維愛心的制作

實作代碼如下 

#include <vtkPolyData.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkProperty.h>
#include <vtkParametricSpline.h>
#include <vtkParametricFunctionSource.h>
#include <vtkSphereSource.h>
#include <vtkPlaneSource.h>
#include <vtkGlyph3DMapper.h>
#include <vtkFillHolesFilter.h>
#include <vtkFeatureEdges.h>
#include <vtkPolyDataNormals.h>
#include <vtkDelaunay2D.h>
#include <vtkVertexGlyphFilter.h>
#include <vtkPolygon.h>

#define PI 3.14159265358979323846
int main(int, char *[])
{
	//存用公式計算出來的點
	vtkSmartPointer<vtkPoints> points =
		vtkSmartPointer<vtkPoints>::New();
	// 建立一個平面來将愛心裡面填沖顔色
	vtkSmartPointer<vtkPlaneSource> planeSource =
		vtkSmartPointer<vtkPlaneSource>::New();
	//限制突變性的形狀
	vtkSmartPointer<vtkPolygon> poly =
		vtkSmartPointer<vtkPolygon>::New();
	//另一種心形,隻是沒有用線連接配接起來,它是用四塊區域拼湊起來的
	//double x, y, x1, y1, y2;
	//int  X = 100, Y = 100;
	//for (x = -360; x <= 360; x++)
	//{
	//	x1 = x / 360.0;
	//	y1 = 360 * (pow(x1, 1.5) + pow(1 - x1 * x1, 0.5));
	//	y2 = 360 * (pow(x1, 1.5) - pow(1 - x1 * x1, 0.5));
	//	double p0[3] = { X + x / 18, Y + y1 / 9, 0 };
	//	double p1[3] = { X + x / 18, Y + y2 / 9, 0 };
	//	double p2[3] = { X - x / 18, Y + y1 / 9, 0 };
	//	double p3[3] = { X - x / 18, Y + y2 / 9, 0 };
	//	
	//	points->InsertNextPoint(p0);
	//	points->InsertNextPoint(p1);
	//	points->InsertNextPoint(p2);
	//	points->InsertNextPoint(p3);
	//}
	double a = 5; int i = 1;
	for (double t = 0; t < 2 * PI; t += 0.21,i++)
	{
		//将二維坐标加入到point中
		double x = a * (2 * sin(t) - sin(2 * t)), y = a * (2 * cos(t) - cos(2 * t));
		double p0[3] = { x, y, 0 };
		cout << x << " " << y << endl;
		points->InsertNextPoint(p0);

	}
	cout << points->GetNumberOfPoints() << endl;
	
	//用線将添加的點按順序連接配接起來 
	vtkSmartPointer<vtkParametricSpline> spline =
		vtkSmartPointer<vtkParametricSpline>::New();
	spline->SetPoints(points);

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

	vtkSmartPointer<vtkVertexGlyphFilter> glyphFilter =
		vtkSmartPointer<vtkVertexGlyphFilter>::New();
	glyphFilter->SetInputData(polydata);
	glyphFilter->Update();


	//指定用于生成曲面細分的參數函數
	vtkSmartPointer<vtkParametricFunctionSource> functionSource =
		vtkSmartPointer<vtkParametricFunctionSource>::New();
	functionSource->SetParametricFunction(spline);
	functionSource->Update();


    //這裡加了一些限制條件,按順序是點連接配接起來
	for (int i = 29; i >0; i--)
	{
		poly->GetPointIds()->InsertNextId(i);
	}
	vtkSmartPointer<vtkCellArray> cell =
		vtkSmartPointer<vtkCellArray>::New();
	cell->InsertNextCell(poly); //設計拓撲結構
	邊界限制
	vtkSmartPointer<vtkPolyData> boundary =
		vtkSmartPointer<vtkPolyData>::New();
	boundary->SetPoints(points);
	boundary->SetPolys(cell); //隻顯示具有拓撲結構部分


	//得到最大的凸包
	vtkSmartPointer<vtkDelaunay2D> content = vtkSmartPointer<vtkDelaunay2D>::New();
	//content->SetInputConnection(functionSource->GetOutputPort());
	content->SetInputData(polydata);
	content->SetSourceData(boundary);
	content->Update();

	//用點練成的線的mapper,actor
	vtkSmartPointer<vtkPolyDataMapper> splineMapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	splineMapper->SetInputConnection(functionSource->GetOutputPort());
	vtkSmartPointer<vtkActor> splineActor =
		vtkSmartPointer<vtkActor>::New();
	splineActor->SetMapper(splineMapper);
	splineActor->GetProperty()->SetColor(1,0,0);

	vtkSmartPointer<vtkSphereSource> sphereSource =
		vtkSmartPointer<vtkSphereSource>::New();
	sphereSource->SetPhiResolution(21);
	sphereSource->SetThetaResolution(21);
	sphereSource->SetRadius(.05);

	vtkSmartPointer<vtkPolyData> splinePointsData =
		vtkSmartPointer<vtkPolyData>::New();
	splinePointsData->SetPoints(points);


	// 把中間的填滿
	vtkSmartPointer<vtkPolyDataMapper> filledMapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	filledMapper->SetInputConnection(content->GetOutputPort());
	vtkSmartPointer<vtkActor> filledActor =
		vtkSmartPointer<vtkActor>::New();
	filledActor->SetMapper(filledMapper);
	//filledActor->GetProperty()->SetDiffuseColor(1.0, 0.3882, 0.2784);
	filledActor->GetProperty()->SetColor(1, 0, 0);

	

	vtkSmartPointer<vtkGlyph3DMapper> splinePointsMapper =
		vtkSmartPointer<vtkGlyph3DMapper>::New();
	splinePointsMapper->SetInputData(splinePointsData);
	splinePointsMapper->SetSourceConnection(sphereSource->GetOutputPort());

	vtkSmartPointer<vtkActor> pointsActor =
		vtkSmartPointer<vtkActor>::New();
	pointsActor->SetMapper(splinePointsMapper);
	pointsActor->GetProperty()->SetColor(1, 0, 0);

	vtkSmartPointer<vtkRenderer> renderer =
		vtkSmartPointer<vtkRenderer>::New();
	vtkSmartPointer<vtkRenderWindow> renderWindow =
		vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->SetSize(600, 600);
	renderWindow->AddRenderer(renderer);
	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	renderWindowInteractor->SetRenderWindow(renderWindow);

	renderer->AddActor(splineActor);
	renderer->AddActor(pointsActor);
	renderer->AddActor(filledActor);

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

	return EXIT_SUCCESS;
}
           

轉載請标明出處。 

參考文獻:

https://lorensen.github.io/VTKExamples/site/Cxx/Filtering/ConstrainedDelaunay2D/

https://shenchunxu.blog.csdn.net/article/details/54864771