VTK笔记-图形相关-线段平滑-vtkSplineFilter类
在实际的开发中,提供有限的连续线段组成一条曲线,需要将该条曲线进行插值处理,生成更高采样率的曲线;这种情况下就需要进行插值;VTK中的线段插值是通过B样条插值实现,使用vtkSplineFilter完成这一功能;
vtkSplineFilter
vtkSplineFilter是一个从多段线的输入集生成输出多段线的Filter。
通过用户可以指定的vtkSpline类(默认情况下使用vtkCardinalSpline),可以对多段线进行统一细分和生成。可以通过多种方式控制线的细分数目。用户可以指定细分的数量,也可以提供每个细分的长度(vtkSplineFilter类将计算出整个多段线上需要计算出多少个细分段)。也可以设置最大细分数。
此Filter的输出是每个输入多段线(或线)的多段线。将创建新的点和纹理坐标。对点数据进行插值,并传递单元数据。任何少于两点的多段线或具有重合点的多段线都将被忽略。
接口
细分段个数
vtkSetClampMacro(NumberOfSubdivisions, int, 1, VTK_INT_MAX);
vtkGetMacro(NumberOfSubdivisions, int);
vtkSetClampMacro(MaximumNumberOfSubdivisions, int, 1, VTK_INT_MAX);
vtkGetMacro(MaximumNumberOfSubdivisions, int);
void SetSubdivideToSpecified() { this->SetSubdivide(VTK_SUBDIVIDE_SPECIFIED); }
void SetSubdivideToLength() { this->SetSubdivide(VTK_SUBDIVIDE_LENGTH); }
vtkSetClampMacro(Subdivide, int, VTK_SUBDIVIDE_SPECIFIED, VTK_SUBDIVIDE_LENGTH);
vtkGetMacro(Subdivide, int);
vtkSetClampMacro(Length, double, 0.0000001, VTK_DOUBLE_MAX);
vtkGetMacro(Length, double);
const char* GetSubdivideAsString();
SetNumberOfSubdivisions:设置为多段线创建的细分数目。只有将Subdivisions设置为SetSubdivisionsToSpecify()时,此方法才有效。
SetSubdivideToSpecified:指定如何确定细分数目。
SetLength基于绝对长度控制为多段线创建的细分数目。样条曲线的长度除以此长度以确定细分的数目。只有将Subdivisions设置为SetSubdivideToLength()时,此方法才有效。
SetMaximumNumberOfSubdivisions:设置为每条多段线创建的最大细分数。
插值类型对象
vtkSpline是样条插值的样条抽象类,SetSpline设置了vtkSplineFilter使用的vtkSpline的派生类对象,可以使用vtkCardinalSpline/vtkKochanekSpline/vtkSCurveSpline;
virtual void SetSpline(vtkSpline*);
vtkGetObjectMacro(Spline, vtkSpline);
纹理坐标
纹理坐标可以通过三种方式生成:归一化(0,1)生成;基于长度(除以纹理长度);通过使用输入的标量值。
宏 | 意义 |
---|---|
VTK_TCOORDS_FROM_NORMALIZED_LENGTH | 归一化方式 |
VTK_TCOORDS_FROM_LENGTH | 基于长度方式 |
VTK_TCOORDS_FROM_SCALARS | 基于输入的标量值方式 |
vtkSetClampMacro(GenerateTCoords, int, VTK_TCOORDS_OFF, VTK_TCOORDS_FROM_SCALARS);
vtkGetMacro(GenerateTCoords, int);
void SetGenerateTCoordsToOff() { this->SetGenerateTCoords(VTK_TCOORDS_OFF); }
void SetGenerateTCoordsToNormalizedLength(){this->SetGenerateTCoords(VTK_TCOORDS_FROM_NORMALIZED_LENGTH);}
void SetGenerateTCoordsToUseLength() { this->SetGenerateTCoords(VTK_TCOORDS_FROM_LENGTH); }
void SetGenerateTCoordsToUseScalars() { this->SetGenerateTCoords(VTK_TCOORDS_FROM_SCALARS); }
const char* GetGenerateTCoordsAsString();
vtkSetClampMacro(TextureLength, double, 0.000001, VTK_INT_MAX);
vtkGetMacro(TextureLength, double);
vtkSpline
vtkSpline插值一组数据点(插值意味着样条曲线通过这些点)。
vtkSpline是一个抽象类:它的子类vtkCardinalSpline、vtkKochanekSpline和vtkSCurveSpline实现vtkSpline提供的接口功能。请注意,此样条曲线将1D参数化坐标t映射为单个值x。因此,如果要使用样条曲线插值点(即x[3]),则必须为每个x-y-z坐标创建三条样条曲线。vtkParametricSpline类可以将离散点拟合成一条样条曲线。通常,样条曲线是通过添加一系列参数坐标/数据(t,x)值,然后使用求值函数(例如,vtkCardinalSpline::Evaluate())来使用的。因为这些样条曲线是一维的,所以这里的一个点是独立/因变量对。样条曲线也可以设置为关闭或打开。闭合样条曲线以连续函数和导数值从最后一点延续到第一点(无需复制第一个点即可闭合样条曲线,只需设置ClosedOn即可)。
样条曲线的这种实现不使用规范化的参数化坐标。如果样条曲线打开,则参数空间为(tMin<=t<=tMax),其中tMin和tMax是执行AddPoint()时看到的最小和最大参数值。如果样条曲线是闭合的,那么参数空间是(tMin<=t<=(tMax+1)),其中tMin和tMax是执行AddPoint()时看到的最小和最大参数值。但是,请注意,可以通过显式设置ParametricRange(tMin,tMax)来更改此行为。如果设置,则参数空间保持不变(tMin<=t<=tMax),除非参数值超出此范围的数据的添加被限制在此范围内。
样条:通过一组指定点集生成平滑曲线的柔型带;
样条曲线:计算机图形学中,样条曲线指多项式曲线段连接而成的曲线;
样条(Spline) 可以理解为 多段 Cubic Curve 的拼接,不过样条在 Cubic Curve 拼接的时候,提出了特殊要求:两段 Cubic Curve 在拼接的位置,需要能够“平滑衔接”,以保证整个样条的曲线平滑。这种“平滑衔接”,是通过导数和曲线的连续性来实现的。
需要实现的两个接口
virtual void Compute() = 0;
virtual double Evaluate(double t) = 0;
参数空间
void SetParametricRange(double tMin, double tMax);
void SetParametricRange(double tRange[2]) { this->SetParametricRange(tRange[0], tRange[1]); }
void GetParametricRange(double tRange[2]) const;
SetParametricRange设置参数空间范围;如果未设置,则通过跟踪t的(min,max)参数值隐式确定范围。如果设置了,AddPoint()方法会将t值钳制在指定的范围内。
样条曲线拟合的点
void AddPoint(double t, double x);
void RemovePoint(double t);
void RemoveAllPoints();
int GetNumberOfPoints();
AddPoint添加一对要与样条曲线拟合的点。
RemovePoint移除一个坐标对应的点;
RemoveAllPoints移除所有点;
夹逼模式
vtkSetMacro(ClampValue, vtkTypeBool);
vtkGetMacro(ClampValue, vtkTypeBool);
vtkBooleanMacro(ClampValue, vtkTypeBool);
SetClampValue设置插值夹逼类型,如果启用,插值结果将被钳制为输入数据的最小值/最大值。
样条区间是否打开
vtkSetMacro(Closed, vtkTypeBool);
vtkGetMacro(Closed, vtkTypeBool);
vtkBooleanMacro(Closed, vtkTypeBool);
SetClosed()设置是否开启闭合样条曲线,闭合样条曲线形成一个连续的循环:第一个点和最后一个点是相同的,导数是连续的。
vtkSetClampMacro(LeftConstraint, int, 0, 3);vtkGetMacro(LeftConstraint, int);vtkSetClampMacro(RightConstraint, int, 0, 3);vtkGetMacro(RightConstraint, int); vtkSetMacro(LeftValue, double);vtkGetMacro(LeftValue, double);vtkSetMacro(RightValue, double);vtkGetMacro(RightValue, double);
SetLeftConstraint和SetRightConstraint设置左(右)端点的约束类型。
有四个约束:
值 | 含义 |
---|---|
0 | 最左(右)点的一阶导数由前(后)两点定义的直线确定 |
1 | 最左(右)点的一阶导数设为左(右)值 |
2 | 最左(右)点的二阶导数设为左(右)值 |
3 | 最左(右)点的二阶导数是左(右)值乘以第一个内点的二阶导数 |
SetLeftValue和SetRightValue用来设置左右两边导数的值。
vtkCardinalSpline
在Cardinal样条中,一个控制点的一阶导数值可以由两个相邻控制点的坐标进行计算。
一个Cardinal样条完全由四个连续控制点给出,中间两个控制点是曲线端点,另外两个点用于计算端点斜率。
如图14.12所示,设P(u)是两控制点Pk和Pk+1间的参数三次函数式,则从Pk-1到Pk+1间的四个控制点用于建立cardinal样条段的边界条件:
P(0) = pk;
P(1) = pk+1;
P’(0) =1/2*(1-t)(pk+1-pk-1);
P’(1) =1/2(1-t)*(pk+2-pk);
控制点Pk和Pk+1处的一阶导数(斜率)分别和弦Pk-1Pk+1和PkPk+2成正比。参数t称为张量(tension)参数,因为t控制cardinal样条与输入控制点之间的松紧程度。图14.14说明了张量t取很大和很小值时cardinal曲线的形状。当t=0时,这样的曲线称为Catmull-Rom样条或Overhauser样条。
接口
在这里插入代码片
vtkKochanekSpline
vtkKochanekSpline提供三个参数来控制花键的形状:
张力:更改切线向量的长度;
偏差:主要改变切向量的方向;
连续性:改变切线之间变化的清晰度;
给出了四个连续控制点,记为Pk-1、Pk、Pk+1和Pk+2,在Pk和Pk+1间的Konchanek-Bartels曲线段中的边界条件定义为:
P(0) = pk;
P(1) = pk+1;
P’(0)in =1/2*(1-t*)[(1+b)(1-c)*(pk-pk-1)+(1-b)+(1-b)*(1+c)*(pk+1-pk)];
P’(1)out 1/2*(1-t*)[(1+b)(1+c)*(pk+1-pk)+(1-b)+(1-b)*(1-c)*(pk+2-pk+1)];
其中t是张量(tension)参数,b是偏离(bias)参数,c是连续性(continuity)参数。在Konchanek-Bartels公式中,导数在曲线段边界处不一定是连续。
张量参数t具有cardinal样条公式中同样的解释,即该参数控制曲线段的松紧程度。偏离参数b用来调整曲线段在端点处弯曲的数值,因此曲线段可以偏向一个端点或另一个端点(参见图14.19)。参数c控制切向量在曲线段边界处的连续性。若c取非零值,则曲线在曲线段边界处的斜率上具有不连续性。
#include <vtkActor.h>
#include <vtkGlyph3DMapper.h>
#include <vtkKochanekSpline.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkParametricFunctionSource.h>
#include <vtkParametricSpline.h>
#include <vtkPointSource.h>
#include <vtkPoints.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
using namespace std;int main()
{vtkNew<vtkNamedColors> colors;int numberOfPoints = 10;vtkNew<vtkPointSource> pointSource;pointSource->SetNumberOfPoints(numberOfPoints);pointSource->Update();vtkPoints* points = pointSource->GetOutput()->GetPoints();vtkNew<vtkKochanekSpline> xSpline;vtkNew<vtkKochanekSpline> ySpline;vtkNew<vtkKochanekSpline> zSpline;vtkNew<vtkParametricSpline> spline;spline->SetXSpline(xSpline);spline->SetYSpline(ySpline);spline->SetZSpline(zSpline);spline->SetPoints(points);vtkNew<vtkParametricFunctionSource> functionSource;functionSource->SetParametricFunction(spline);functionSource->SetUResolution(50 * numberOfPoints);functionSource->SetVResolution(50 * numberOfPoints);functionSource->SetWResolution(50 * numberOfPoints);functionSource->Update();// Setup actor and mappervtkNew<vtkPolyDataMapper> mapper;mapper->SetInputConnection(functionSource->GetOutputPort());vtkNew<vtkActor> actor;actor->SetMapper(mapper);actor->GetProperty()->SetColor(colors->GetColor3d("DarkSlateGrey").GetData());actor->GetProperty()->SetLineWidth(3.0);// Glyph the pointsvtkNew<vtkSphereSource> sphere;sphere->SetPhiResolution(21);sphere->SetThetaResolution(21);sphere->SetRadius(.02);// Create a polydata to store everything invtkNew<vtkPolyData> polyData;polyData->SetPoints(points);vtkNew<vtkGlyph3DMapper> pointMapper;pointMapper->SetInputData(polyData);pointMapper->SetSourceConnection(sphere->GetOutputPort());vtkNew<vtkActor> pointActor;pointActor->SetMapper(pointMapper);pointActor->GetProperty()->SetColor(colors->GetColor3d("Peacock").GetData());// Setup render window, renderer, and interactorvtkNew<vtkRenderer> renderer;vtkNew<vtkRenderWindow> renderWindow;renderWindow->AddRenderer(renderer);renderWindow->SetWindowName("KochanekSpline");vtkNew<vtkRenderWindowInteractor> renderWindowInteractor;renderWindowInteractor->SetRenderWindow(renderWindow);renderer->AddActor(actor);renderer->AddActor(pointActor);renderer->SetBackground(colors->GetColor3d("Silver").GetData());renderWindow->Render();renderWindowInteractor->Start();return 0;
}
vtkSCurveSpline
vtkSCurveSpline 使用曲线基计算插值样条曲线。使用方法同vtkKochanekSpline;
示例
1.生成8条线段;
float x[8][3] = {{0,0,0},{1,0,0},{1,1,0},{0,1,0},{0,0,1},{1,0,1},{1,1,1},{0,1,1}};vtkNew<vtkPolyData> geometry;vtkNew<vtkPoints> points;for (size_t i = 0; i < 8; i++) {points->InsertPoint(i, x[i]);}vtkNew<vtkCellArray> polys;polys->InsertNextCell(8);for (size_t i = 0; i < 8; i++) { polys->InsertCellPoint(i);}geometry->SetPoints(points);geometry->SetLines(polys);vtkNew<vtkPolyDataMapper> geometryMapper;geometryMapper->SetInputData(geometry);vtkNew<vtkActor> geometryActor;geometryActor->SetMapper(geometryMapper);vtkNew<vtkRenderer> renderer;renderer->AddActor(geometryActor);renderer->ResetCamera();renderer->SetBackground(0, 0, 0);vtkNew<vtkRenderWindow> renWin;renWin->AddRenderer(renderer);renWin->SetSize(300, 300);vtkNew<vtkRenderWindowInteractor> iren;iren->SetRenderWindow(renWin);renWin->Render();iren->Start();
2.使用样条插值后
float x[8][3] = {{0,0,0},{1,0,0},{1,1,0},{0,1,0},{0,0,1},{1,0,1},{1,1,1},{0,1,1}};vtkNew<vtkPolyData> geometry;vtkNew<vtkPoints> points;for (size_t i = 0; i < 8; i++) {points->InsertPoint(i, x[i]);}vtkNew<vtkCellArray> polys;polys->InsertNextCell(8);for (size_t i = 0; i < 8; i++) { polys->InsertCellPoint(i);}geometry->SetPoints(points);geometry->SetLines(polys);vtkNew<vtkCardinalSpline> spline;spline->SetLeftConstraint(2);spline->SetLeftValue(0.0);spline->SetRightConstraint(2);spline->SetRightValue(0.0);vtkNew<vtkSplineFilter> filter;filter->SetInputData(geometry);filter->SetNumberOfSubdivisions(100);filter->SetSpline(spline);filter->Update();vtkNew<vtkPolyDataMapper> geometryMapper;geometryMapper->SetInputData(filter->GetOutput());vtkNew<vtkActor> geometryActor;geometryActor->SetMapper(geometryMapper);vtkNew<vtkRenderer> renderer;renderer->AddActor(geometryActor);renderer->ResetCamera();renderer->SetBackground(0, 0, 0);vtkNew<vtkRenderWindow> renWin;renWin->AddRenderer(renderer);renWin->SetSize(300, 300);vtkNew<vtkRenderWindowInteractor> iren;iren->SetRenderWindow(renWin);renWin->Render();iren->Start();
参考文献
1.vtkSpline
2.vtkCardinalSpline
3.vtkKochanekSpline
4.vtkSCurveSpline
VTK笔记-图形相关-线段平滑-vtkSplineFilter类相关推荐
- VTK笔记-图形相关-圆锥体-vtkConeSoure类
圆锥体 文章目录 圆锥体 前言 一.代码 1.1流程 二.遇到的问题 1.运行时异常 2.在ThinkPad E530C笔记本上出现的异常 3.运行结果 三.相机旋转 四.vtkConeSource ...
- VTK笔记-图形相关-多边形数据转换图像数据-vtkPolyData转换为vtkImageData
VTK中vtkImageData类和vtkPolyData类使用频率极高,vtkImageData类和vtkPolyData类派生自vtkDataSet类,是数据集的一种. vtkPolyDa ...
- VTK笔记-图像相关-vtkImageViewer2类
vtkImageViewer2 vtkImageViewer2类用来显示二维图像:vtk的版本更新,使用vtkImageViewer2替代vtkImageViewer类: vtkImageVi ...
- VTK笔记-CT图像获取皮肤等值面-vtkContourFilter类的使用
文章目录 vtkContourFilter SetValue GenerateValues SetValue与GenerateValues的区别与联系 实例 代码 各个对象的关系图 运行效果 引用 本 ...
- qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)
原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7851 ...
- Java快速入门学习笔记7 | Java语言中的类与对象
有人相爱,有人夜里开车看海,有人却连LeetCode第一题都解不出来!虽然之前系统地学习过java课程,但是到现在一年多没有碰过Java的代码,遇到LeetCode不知是喜是悲,思来想去,然后清空自己 ...
- C++学习笔记-第4单元-对象和类(基础)
C++学习笔记 文章目录 C++学习笔记 第4单元 对象和类(基础) 单元导读 4.1 用类创建对象 4.1.1 对象和类 4.1.2 创建对象并访问 4.2 对象拷贝.分离声明与实现 4.2.1 对 ...
- Dubins曲线学习笔记及相关思考
本篇博客主要记录在学习Dubins曲线过程中的笔记及相关思考和概括总结 一.主要参考资料 1.Andy G's Blog:[点击此处跳转] 2.Andy G's Blog的P ...
- 数据结构专题-学习笔记:李超线段树
数据结构专题 - 学习笔记:李超线段树 1. 前言 2. 详解 3. 应用 4. 总结 5. 参考资料 1. 前言 本篇博文是博主学习李超线段树的学习笔记. 2020/12/21 的时候我在 线段树算 ...
最新文章
- 计算机应用基础 pdf 陈建军教案,温州市第二职业中等专业学校(温五中) 教学资源 温州市《计算机应用基础》学业水平测试考纲(转发)...
- release8_如何在Windows 8 Release Preview中将Chrome用作Metro浏览器
- 认识JSON补丁:JSON-P 1.1概述系列
- python含多个附件的邮件_Python发送带有多个图像附件的电子邮件
- 修改oracle rac sid,修改Oracle RAC的_asm_hbeatiowait的方法
- 月薪10000在中国是什么水平?
- java 函数式编程 示例_Java套接字编程–套接字服务器,客户端示例
- 查看Linux是Redhat 还是centos 还是...
- python时间戳格式定义_关于Python时间戳是什么讲解
- 根据 ”艾宾浩斯遗忘曲线“复习时间点生成的复习计划模板
- 根据出库、入库表,实现对库存的信息查询
- uniapp获取本机ip地址
- HTML如何把输入框变成必填值,required输入框为必填项
- 【算法】生成n个互异随机数的初步算法
- Intel汇编指令在线手册
- 目标跟踪技术及其数据集
- 山石网科面经(附参考回答)
- 极简主义、人工智能与Readhub的产品哲学
- 【渝粤教育】21秋期末考试建筑工程计量与计价10517k1
- PS缩小图层兼如何使用蒙版