VTK笔记——点(point)和向量(vector)投影到平面(plane)

有时候,三维空间的点需要投影到某一特定的平面。比如说,一个点集,连接成一个平面,如果不进行投影,直接连接,可能会出现怪异的现象。

为了简单,示例只用到了一个点的投影。多个点的投影,延伸一下就可以了

需求:将p点投影到x0y平面。

VTK笔记——点(point)和向量(vector)投影到平面(plane)_第1张图片

怎样做

方法一

需求是投影到x0y平面,不难理解,这个平面z=0.

	double p[] = {11.0, 8.3, 5.7};
	p[2] = 0;

方法一属于偷懒的做法,有很大的局限性,如果想投影到空间中的任意平面,可以用下面的方法二,更通用的办法。

方法二

该方法是借助vtkPlane来进行投影,一个原点和一根法向量可以确定一个平面。有了平面以后,再使用ProjectPoint方法得到投影点。

	vtkSmartPointer plane =
		vtkSmartPointer::New();
	double origin[] = { 0, 0, 0 };
	double normal[] = { 0, 0, 1 };
	plane->SetOrigin(origin);
	plane->SetNormal(normal);
	
	double p[] = {11.0, 8.3, 5.7};
	double projected[3];
	plane->ProjectPoint(p, origin, normal, projected);

效果:
VTK笔记——点(point)和向量(vector)投影到平面(plane)_第2张图片

示例代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main(int, char *[])
{
	vtkSmartPointer plane =
		vtkSmartPointer::New();
	double origin[] = { 0, 0, 0 };
	double normal[] = { 0, 0, 1 };
	plane->SetOrigin(origin);
	plane->SetNormal(normal);
	
	double p[] = {11.0, 8.3, 5.7};
	double projected[3];
	plane->ProjectPoint(p, origin, normal, projected);

	char outputMsg[256] = {0};
	//sprintf_s(outputMsg, sizeof(outputMsg), "p(%f, %f, %f)", p[0], p[1], p[2]);
	sprintf_s(outputMsg, sizeof(outputMsg), "p(%f, %f, %f)\nprojected(%f, %f, %f)", p[0], p[1], p[2], 
		projected[0], projected[1], projected[2]);

	vtkSmartPointer textActor =
		vtkSmartPointer::New();
	textActor->SetPosition2(100, 40);
	textActor->GetTextProperty()->SetFontSize(24);
	textActor->GetTextProperty()->SetColor(0, 1, 0);
	textActor->SetInput(outputMsg);

	vtkSmartPointer pointsSphere =
		vtkSmartPointer::New();
	pointsSphere->SetPhiResolution(21);
	pointsSphere->SetThetaResolution(21);
	pointsSphere->SetRadius(.5);

	vtkSmartPointer points =
		vtkSmartPointer::New();
	points->InsertNextPoint(p);
	points->InsertNextPoint(projected);

	vtkSmartPointer pointsData =
		vtkSmartPointer::New();
	pointsData->SetPoints(points);

	vtkSmartPointer pointsMapper =
		vtkSmartPointer::New();
	pointsMapper->SetInputData(pointsData);
	pointsMapper->SetSourceConnection(pointsSphere->GetOutputPort());

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

#define LINE_LEN 10.
	vtkSmartPointer axesActor =
		vtkSmartPointer::New();
	axesActor->SetPosition(0, 0, 0);
	axesActor->SetTotalLength(LINE_LEN, LINE_LEN, LINE_LEN);
	axesActor->SetShaftType(0);
	axesActor->SetAxisLabels(0);
	axesActor->SetCylinderRadius(0.02);
	
	vtkSmartPointer renderer =
		vtkSmartPointer::New();
	vtkSmartPointer renderWindow =
		vtkSmartPointer::New();
	renderWindow->SetSize(600, 600);
	renderWindow->AddRenderer(renderer);
	vtkSmartPointer renderWindowInteractor =
		vtkSmartPointer::New();
	renderWindowInteractor->SetRenderWindow(renderWindow);

	renderer->AddActor2D(textActor);
	renderer->AddActor(pointsActor);
	renderer->AddActor(axesActor);

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

	return EXIT_SUCCESS;
}

向量投影

向量投影和点投影类似,不同的是用ProjectVector方法。

	vtkSmartPointer plane =
		vtkSmartPointer::New();
	double origin[] = { 0, 0, 0 };
	double normal[] = { 0, 0, 1 };
	plane->SetOrigin(origin);
	plane->SetNormal(normal);

	double vector[] = { 3.4, 8.3, 5.7 };
	plane->ProjectVector(vector, vector);

Reference

ProjectPointPlane
vtk学习笔记 — 投影点集合到指定的平面
vtkPlane Class Reference
VTK笔记——点(point)和向量(vector)投影到平面(plane)_第3张图片

你可能感兴趣的:(VTK笔记)