VTK_测距&随机数&变换&投影

此生再无相见时 提交于 2020-03-06 01:16:43

vtk测距:

点-点:

#include <iostream>
#include <vtkMath.h>

int main(int argc, char* argv[])
{
	// 创建两个空间点
	double p0[3] = { 0.0, 0.0, 0.0 };
	double p1[3] = { 1.0, 1.0, 1.0 };
	// 平方距离
	double squaredDistance = vtkMath::Distance2BetweenPoints(p0, p1);
	// 真实距离
	double distance = sqrt(squaredDistance);
	// 输出
	std::cout << "SquaredDistance = " << squaredDistance << std::endl;
	std::cout << "Distance = " << distance << std::endl;
	
	return 0;
}

vtk测量距离非常简单,通常需要与vtk拾取一起使用,及拾取两个点,计算间距,其距离计算算法也很简单。

点-线:

#include <iostream>
#include <vtkSmartPointer.h>
#include <vtkLine.h>
#include <vtkPoints.h>

int main(int argc, char* argv[])
{
	double lineP0[3] = { 0.0, 0.0, 0.0 };	// 一条线的两个点
	double lineP1[3] = { 2.0, 0.0, 0.0 };

	double p0[3] = { 3.0, 0, 0 };		// 点
	double p1[3] = { 1.0, 2.0, 0 };

	// Distance**2
	double dist0 = vtkLine::DistanceToLine(p0, lineP0, lineP1);
	std::cout << "Dist0: " << dist0 << std::endl;
	double dist1 = vtkLine::DistanceToLine(p1, lineP0, lineP1);
	std::cout << "Dist1: " << dist1 << std::endl;

	// Distance**2,此外,还可得到最近点的坐标
	double t;	// 保存的比例,点处于第一个点到第二个点之间的比例,在第二个点之外就大于1
	double closest[3];
	dist0 = vtkLine::DistanceToLine(p0, lineP0, lineP1, t, closest);
	std::cout << "Dist0: " << dist0 << " closest point: " << closest[0] << " " << closest[1] << " " << closest[2] << std::endl;

	dist1 = vtkLine::DistanceToLine(p1, lineP0, lineP1, t, closest);
	std::cout << "Dist1: " << dist1 << " closest point: " << closest[0] << " " << closest[1] << " " << closest[2] << std::endl;

//-----Line
	vtkSmartPointer<vtkLine> pLine = vtkLine::New();	// vtk智能指针
	pLine->GetPoints()->SetPoint(0, lineP0);
	pLine->GetPoints()->SetPoint(0, lineP1);

	// Distance	计算距离只能用直线的两点。
	dist0 = vtkLine::DistanceToLine(p0, lineP0, lineP1);
	std::cout << "Dist0: " << sqrt(dist0) << std::endl;
	dist1 = vtkLine::DistanceToLine(p1, lineP0, lineP1);
	std::cout << "Dist1: " << sqrt(dist1) << std::endl;

	return 0;
}

点到先的距离计算函数在vtkLine里面,计算的时候,不能直接使用线对象,需要制定线的两个端点,或者之间的点也是可以的,但这样返回的t(比例)就没有参考价值了。

生成高斯分布的随机数:


#include <vtkMath.h>
#include <ctime>

int main(int, char *[])
{
	unsigned int numRand = 20;

	// 没有这行,生成的全是一样的
	vtkMath::RandomSeed(time(NULL));

	//高斯分布生成随机数(基本规律是中间多,两边少)
	for (unsigned int i = 0; i < numRand; i++)
	{
		double a = vtkMath::Gaussian(0.0, 2.0);	// 生成0~2之间的随机数
		std::cout << a << std::endl;
	}

	return 0;
}

高斯分布具体可百度,大致规律是中间多,两边少。

vtk随机数生成方法:

#include <vtkMath.h>
#include <ctime>

int main(int argc, char* argv[])
{
	unsigned int numRand = 20;

	vtkMath::RandomSeed(time(NULL));

	for (unsigned int i = 0; i < numRand; i++)
	{
		double a = vtkMath::Random(0.0, 2.0);	// 0~2随机数
		std::cout << a << std::endl;
	}

	return 0;
}

Random是生成的随机数,不具有分布性质,完全的随机的。

点的透视变换,标准变换:

#include <vtkSmartPointer.h>
#include <vtkPerspectiveTransform.h>
#include <vtkTransform.h>
#include <vtkMatrix4x4.h>

int main(int, char *[])
{
	// 一个4*4的矩阵,
	// 	1,2,3,4
	// 	2,2,3,4
	// 	3,2,3,4
	// 	4,2,3,4
	vtkSmartPointer<vtkMatrix4x4> m = vtkSmartPointer<vtkMatrix4x4>::New();
	m->SetElement(0, 0, 1);
	m->SetElement(0, 1, 2);
	m->SetElement(0, 2, 3);
	m->SetElement(0, 3, 4);
	m->SetElement(1, 0, 2);
	m->SetElement(1, 1, 2);
	m->SetElement(1, 2, 3);
	m->SetElement(1, 3, 4);
	m->SetElement(2, 0, 3);
	m->SetElement(2, 1, 2);
	m->SetElement(2, 2, 3);
	m->SetElement(2, 3, 4);
	m->SetElement(3, 0, 4);
	m->SetElement(3, 1, 2);
	m->SetElement(3, 2, 3);
	m->SetElement(3, 3, 4);

	vtkSmartPointer<vtkPerspectiveTransform> perspectiveTransform =
		vtkSmartPointer<vtkPerspectiveTransform>::New();	// 透视变换
	perspectiveTransform->SetMatrix(m);

	vtkSmartPointer<vtkTransform> transform =
		vtkSmartPointer<vtkTransform>::New();
	transform->SetMatrix(m);

	double p[3];	// 一个点
	p[0] = 1.0;
	p[1] = 2.0;
	p[2] = 3.0;

	double normalProjection[3];
	transform->TransformPoint(p, normalProjection);		// 将p点标准变换,结果保存在normalProjection

	std::cout << "Standard projection: "
		<< normalProjection[0] << " "
		<< normalProjection[1] << " "
		<< normalProjection[2] << std::endl;

	double perspectiveProjection[3];
	perspectiveTransform->TransformPoint(p, perspectiveProjection);		// 将p点透视变换,结果保存在perspectiveProjection
	std::cout << "Perspective projection: "
		<< perspectiveProjection[0]
		<< " " << perspectiveProjection[1] << " "
		<< perspectiveProjection[2] << std::endl;

	return 0;
}

在上面,这个4*4的矩阵就是变换矩阵,当作为透视变换和标准变换的时候,得到的点不是一样的

点投影到面:


#include <vtkSmartPointer.h>
#include <vtkPlane.h>

int main(int, char *[])
{
	// 一个平面,实际上这是一个位于0,0,0,面向z轴(显示器外)的平面
	vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane>::New();
	plane->SetOrigin(0.0, 0.0, 0.0);	// 通过点
	plane->SetNormal(0.0, 0.0, 1.0);	// 法线

	double p[3] = { 23.1, 54.6, 9.2 };		// 需要投影的点
	double origin[3] = { 0.0, 0.0, 0.0 };	// 平面通过点
	double normal[3] = { 0.0, 0.0, 1.0 };	// 平面法向量
	double projected[3];					// 用于保存投影的点

	plane->ProjectPoint(p, origin, normal, projected);

	std::cout << "Projected: " << projected[0] << " "
		<< projected[1] << " " << projected[2] << std::endl;

	return 0;
}

点投影到面,与点线距离有点类似,都不能直接传入面或者线的对象,而需要直接传入其决定性的参数。

 

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!