VTK笔记——插值样条曲线(Parametric Spline)

相信大家对曲线并不陌生,在生活工作学习中都会接触到。同样,在3D方面,曲线也大有用处。

什么是样条曲线

我们先看下百度词条的定义:

所谓样条曲线(Spline Curves)是指给定一组控制点而得到一条曲线,曲线的大致形状由这些点予以控制,一般可分为插值样条和逼近样条两种,插值样条通常用于数字化绘图或动画的设计,逼近样条一般用来构造物体的表面。

也就是说,要构造一条曲线,首先需要控制点,然后确定插值方法。需要多少控制点,这个根据实际情况来定,一般不少于3个控制点,曲线的形状最终是由曲线方程来表示的。
构造样条曲线,通常有两种方法:拟合和插值。拟合不要求通过所有控制点,只要神似即可。插值则要形似,要穿过每个控制点。
下面介绍的方法是插值。

如何构造插值样条曲线

我们今天要用的方法就是vtkParametricSpline.
先看下它的描述:
vtkParametricSpline Description

parametric function for 1D interpolating splines

vtkParametricSpline is a parametric function for 1D interpolating splines. vtkParametricSpline maps the single parameter u into a 3D point (x,y,z) using three instances of interpolating splines. This family of 1D splines is guaranteed to be parameterized in the interval [0,1]. Attempting to evaluate outside this interval will cause the parameter u to be clamped in the range [0,1].

When constructed, this class creates instances of vtkCardinalSpline for each of the x-y-z coordinates. The user may choose to replace these with their own instances of subclasses of vtkSpline.

vtkParametricSpline是参数方程,三次样条插值的默认方法是vtkCardinalSpline,当然可以用另外的方法,比如vtkKochanekSpline[详见Kochanek, D., Bartels, R., “Interpolating Splines with Local Tension, Continuity, and Bias Control,” Computer Graphics, vol. 18, no. 3, pp. 33-41, July 1984].

那么,插值样条曲线,用vtk的类就比较简单。先将控制点插到vtkPoints,然后通过vtkParametricSpline就完成了。
举个例子,给定4个点,拟合一条曲线:

vtkSmartPointer<vtkPoints> points =
	vtkSmartPointer<vtkPoints>::New();
points->InsertNextPoint(p0);
points->InsertNextPoint(p1);
points->InsertNextPoint(p2);
points->InsertNextPoint(p3);

vtkSmartPointer<vtkParametricSpline> spline =
	vtkSmartPointer<vtkParametricSpline>::New();
spline->SetPoints(points);

下面就是由4个控制点得到的样条曲线:
4个点
几个可能会涉及到的问题:
1.如果我们要让曲线闭合,怎么办?
调用SetClosed/ClosedOn即可。
在这里插入图片描述

2.参数化的方式默认是长度,可以通过SetParameterizeByLength/ParameterizeByLengthOff修改。

3.插值方法默认是vtkCardinalSpline,要修改为vtkKochanekSpline,可以通过SetXSpline/SetYSpline/SetZSpline修改。

4.在使用vtkParametricFunctionSource可视化的过程中,可能发现控制点不跟随,那就需要提高分辨率,SetUResolution/SetVResolution/SetWResolution.
在这里插入图片描述

示例代码

#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 <vtkGlyph3DMapper.h>

int main(int, char *[])
{
	double p0[3] = { 1.0, 0.0, 0.0 };
	double p1[3] = { 0.0, 1.0, 0.0 };
	double p2[3] = { 0.0, 0.0, 1.0 };
	double p3[3] = { 1.0, 2.0, 3.0 };

	vtkSmartPointer<vtkPoints> points =
		vtkSmartPointer<vtkPoints>::New();
	points->InsertNextPoint(p0);
	points->InsertNextPoint(p1);
	points->InsertNextPoint(p2);
	points->InsertNextPoint(p3);

	vtkSmartPointer<vtkParametricSpline> spline =
		vtkSmartPointer<vtkParametricSpline>::New();
	spline->SetPoints(points);

	vtkSmartPointer<vtkParametricFunctionSource> functionSource =
		vtkSmartPointer<vtkParametricFunctionSource>::New();
	functionSource->SetParametricFunction(spline);
	functionSource->Update();

	vtkSmartPointer<vtkPolyDataMapper> splineMapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	splineMapper->SetInputConnection(functionSource->GetOutputPort());

	vtkSmartPointer<vtkActor> splineActor =
		vtkSmartPointer<vtkActor>::New();
	splineActor->SetMapper(splineMapper);

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

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

	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);

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

	return EXIT_SUCCESS;
}

Reference
VTKExamples/Cxx/PolyData/ParametricSpline
vtkParametricSpline Class Reference
样条曲线 百度百科
在这里插入图片描述

  • 3
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值