3.样条曲线之NURBS

基本概念

        有理函数是两个多项式之比。因此,有理样条(rational spline)是两个样条函数之比。例如,有理B样条曲线可以使用向量描述为:
在这里插入图片描述
        通常,图像设计软件包使用非均匀节点向量表达式来构造有理B样条,这些样条称为非均匀有理样条(Non-Uniform Rational B-Splines, NURBS)。 构造有理B样条表达式与构造非有理表达式有相同的步骤。给定控制点集、多项式次数、加权因子、节点向量,使用递归关系即可获得混合函数。

示例演示

        在B样条曲线的基础上,实现NURBS曲线。

/**********************************************************************

Copyright (c) Mr.Bin. All rights reserved.
For more information visit: http://blog.csdn.net/webzhuce

**********************************************************************/
#include <vtkPolyDataMapper.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkActor.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkProperty.h>
#include <vtkPoints.h>
#include <vtkSphereSource.h>
#include <vtkGlyph3DMapper.h>
#include "vtkNurbSource.h"

int main()
{
	double p0[3] = { -100.0, -40.0, 0.0 };
	double p1[3] = { 0.0, 40.0, 0.0 };
	double p2[3] = { 100.0, -40.0, 0.0 };

	vtkNew<vtkPoints> points;
	points->InsertNextPoint(p0);
	points->InsertNextPoint(p1);
	points->InsertNextPoint(p2);

	// spline points
	vtkNew<vtkSphereSource> spheresource;
	spheresource->SetPhiResolution(20);
	spheresource->SetThetaResolution(20);
	spheresource->SetRadius(10);
	spheresource->Update();
	vtkNew<vtkPolyData> ctrlpointsdata;
	ctrlpointsdata->SetPoints(points);
	vtkNew<vtkGlyph3DMapper> ctrlpointsmapper;
	ctrlpointsmapper->SetInputData(ctrlpointsdata);
	ctrlpointsmapper->SetSourceConnection(spheresource->GetOutputPort());
	ctrlpointsmapper->Update();
	vtkNew<vtkActor> ctrlpointsactor;
	ctrlpointsactor->SetMapper(ctrlpointsmapper);
	ctrlpointsactor->GetProperty()->SetColor(1.0, 0.0, 0.0);

	//spline
	vtkNew<vtkNurbSource> spline;
	//open uniform
	int d = 3;
	std::vector<float> knots = { 0.0f, 0.0f, 0.0f, 1.0f, 1.0f,1.0f};
	float r = 0.5f;  //抛物线段
	std::vector<float> weights = { 1.0f, r/(1.0f - r), 1.0f};
	
	spline->SetParameters(points, d, knots, weights);
	vtkNew<vtkPolyDataMapper> splinemapper;
	splinemapper->SetInputConnection(spline->GetOutputPort());
	vtkNew<vtkActor> splineactor;
	splineactor->SetMapper(splinemapper);
	splineactor->GetProperty()->SetColor(1.0, 0.0, 0.0);
	
	
	//render
	vtkNew<vtkRenderer> renderer;
	renderer->AddActor(ctrlpointsactor);
	renderer->AddActor(splineactor);
	renderer->SetBackground(1.0, 1.0, 1.0);
	vtkNew<vtkRenderWindow> renderwindow;
	renderwindow->SetSize(400, 200);
	renderwindow->AddRenderer(renderer);
	vtkNew<vtkRenderWindowInteractor> interactor;
	interactor->SetRenderWindow(renderwindow);
	vtkNew<vtkInteractorStyleTrackballCamera> style;
	interactor->SetInteractorStyle(style);
	interactor->Initialize();
	interactor->Start();

	return EXIT_SUCCESS;

}

运行结果

r = 0.5 抛物线段
在这里插入图片描述
r > 0.5 双曲线段
r < 0.5 椭圆线段
r = 0 直线段

参考资料

  • 《计算机图形学(第四版)》[M]

猜你喜欢

转载自blog.csdn.net/webzhuce/article/details/104168324
今日推荐