基本概念
有理函数是两个多项式之比。因此,有理样条(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]