基本概念
在计算机图形中,样条曲线(spline curve)指由多项式曲线段连接而成的曲线,在每段的边界处满足特定的连续性条件。样条曲面(spline surface)可以使用两组样条曲线进行描述。
给定一组称为控制点的坐标点,可以得到一条样条曲线,这些点给出了曲线的大致形状。根据这些坐标位置,可以使用以下两种方法之一选取分段连续参数多项式函数。当选取的多项式使得曲线通过每个控制点,则所得曲线称为这组控制点的插值(interpolate)样条曲线。另一情况,当选取的多项式使部分或全部控制点都不在生成的曲线上,所得曲线称为这组控制点的逼近(approximate)样条曲线。
贝塞样条曲线
这个样条逼近方法是法国工程师皮埃尔·贝济埃(Pierre Bézier)为雷诺公司设计汽车车身而开发的。这里给出它的公式,并用VTK实现。下面是公式介绍。
下面是代码,vtkBezierSplineSource类是根据上面公式写的。完整工程。
/**********************************************************************
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 "vtkBezierSplineSource.h"
int main()
{
double p0[3] = { -40.0, -40.0, 0.0 };
double p1[3] = { -10.0, 200.0, 0.0 };
double p2[3] = { -40.0, -200.0, 0.0 };
double p3[3] = { 40.0, 40.0, 0.0 };
vtkNew<vtkPoints> points;
points->InsertNextPoint(p0);
points->InsertNextPoint(p1);
points->InsertNextPoint(p2);
points->InsertNextPoint(p3);
// 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<vtkBezierSplineSource> spline;
spline->SetControlPoints(points);
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;
}
运行结果
参考资料
- 《计算机图形学(第四版)》[M]