资源简介
VC++实现的三次B样条插值类,采用Deboor算法,下过很多代码都不是我想要的,花了不少时间实现的。插值点过输入的点,可以修改插值间隔,可以任意等间隔重采样,可以计算切线和法线。此外提供两条优化思路:计算插值点的函数可以放入循环中,并且节点矢量的差值。重采样的优化思路:若采用插值点的累积长度来算弧长的思路,则可在循环外用MMX计算插值点之间的偏移和长度,MMX一次可以计算四个浮点运算。
代码片段和文件信息
#include “StdAfx.h“
#include “BSpline.h“
#include
#include
LBSpline::LBSpline()
{
FStep = Sample_STEP;
}
LBSpline::LBSpline(vector inPointsint step)
{
ShapePoints = inPoints;
FStep = step;
Need();
}
LBSpline::~LBSpline()
{
}
void LBSpline::clear()
{
FStep = Sample_STEP;
ShapePoints.clear();
ControlPoints.clear();
BSplinePoints.clear();
NodeVectors.clear();
}
void LBSpline::Need()
{
if (ShapePoints.size()<3)
return;
CalNodeVector();
CalControlPnts();
CalBSplinePnts();
}
//由输入的型值点利用向心模型计算节点矢量
void LBSpline::CalNodeVector()
{
if (NodeVectors.size() != 0)
NodeVectors.clear();
int num = ShapePoints.size();
double* distance = new double[num-1];
double totalDistance = 0; //总弦长
for (int i = 0; i < num -1; i++)
{
double x1 = ShapePoints[i].x;
double x2 = ShapePoints[i+1].x;
double y1 = ShapePoints[i].y;
double y2 = ShapePoints[i+1].y;
//distance[i] = sqrt(sqrt(pow(x1-x22)+pow(y1-y22)));
distance[i] = sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
totalDistance += distance[i];
}
for (int i = 0; i < 4; i++)
NodeVectors.push_back(0.0);
double temp = 0;
for (int i = 4; i < num+2; i++)
{
temp = NodeVectors[i-1] + distance[i-4]/totalDistance;
NodeVectors.push_back(temp);
}
for (int i = num+2; i < num+6; i++)
NodeVectors.push_back(1.0);
delete distance;
return;
}
//用追赶法由型值点计算控制点(非周期曲线)
void LBSpline::CalControlPnts()
{
if (ControlPoints.size()!=0)
ControlPoints.clear();
int num = ShapePoints.size();
vector alpha;
vector beta;
vector gama;
LFPoint point(0.00.0);
for (int i = 0; i < num+2; i++)
ControlPoints.push_back(point);
for (int i = 0; i < num; i++) //计算alphabetagama
{
double a = NodeVectors[i+4] - NodeVectors[i+3];
double b = NodeVectors[i+4] - NodeVectors[i+2];
double c = NodeVectors[i+4] - NodeVectors[i+1];
double d = NodeVectors[i+3] - NodeVectors[i+2];
double e = NodeVectors[i+5] - NodeVectors[i+2];
double alpha_i = (a*a)/(b*c);
double gama_i = (d*d)/(e*b);
double beta_i = 1 - alpha_i - gama_i;
alpha.push_back(alpha_i);
beta.push_back(beta_i);
gama.push_back(gama_i);
}
double alpha_0beta_0gama_0;
double alpha_nbeta_ngama_n;
vector a;
vector b;
vector c;
vector d;
vector pVector;
vector qVector;
//自由边界条件下
alpha_0 = 6.0;
beta_0 = 6.0*(2.0*NodeVectors[0]-NodeVectors[4]-NodeVectors[5])/(NodeVectors[5]-NodeVectors[0]);
gama_0 = 6.0*(NodeVectors[4]-NodeVectors[0])/(NodeVectors[5]-NodeVectors[0]);
beta_n = 6.0*(NodeVectors[num+1]+NodeVectors[num]-2.0*NodeVectors[num+4])/(NodeVectors[num+4]-NodeVectors[num]);
alpha_n = 6.0*(NodeVectors[num+4]-NodeVectors[num+1])/(NodeVectors[num+4]-NodeVectors[num]);
gama_n = 6.0;
//初始化a,b,c,d
a.push_back(0.0);
b.push_back(1.0);
c.push_back(0.0);
d.push_back(LFPoi
属性 大小 日期 时间 名称
----------- --------- ---------- ----- ----
文件 15470 2012-11-30 15:39 BSpline.cpp
文件 1624 2012-11-30 15:39 BSpline.h
- 上一篇:MFC单文档实现多视图
- 下一篇:姿态解算c代码
相关资源
- 三次样条插值的C语言实现
- C++数据结构分段线性插值
- C语言实现拉格朗日插值
- c语言写的图像插值算法
- c语言实现 拉格朗日插值方法
- 双三次B样条曲面算法
- 抛物线法—二次插值法C++编程
- 拉格朗日插值、分段线性插值、三次
- 双三次B样条曲面算法 计算机图形学
- 三次B样条曲线算法 计算机图形学 案
- 曲线绘制Bezier、三次B样条、Hermite
- 2.Newton插值公式.cpp
- 三次样条插值算法c语言
- 三次样条差值C语言程序,亲测有用!
- 径向基函数RBF插值算法cpp实现
- 三次样条插值算法C++源代码
- RGB图像通道值分离、最邻近插值法、
- 双线性插值求亚像素
- Bezier曲线,三次B样条曲线
- 基于OpenCV最近邻插值算法
- 双立方线性插值算法C++实现即说明
- 散点插值及等值线绘制
- 在MFC单文档中绘制平面bezier曲线、三
评论
共有 条评论