#include <stdio.h>
#include<stdlib.h>
#include"b_spline.h"
/*
计算最终b样条平滑时生成的点数.
num_points:输入的散点数量.
degree:b样条曲线的阶次,可选2次或者3次
num_div:两点之间细分的线段数量.
*/
int cal_b_spline_points_num(int num_points,int degree, int num_div)
{
int num;
num = (num_points +2-degree) *num_div+ 1;
return num;
}
/*
生成多个控制点之间的b样条的曲线.
p_array:三个点或者四个点组成的数组,数据排布格式为x0,y0,z0,x1,y1,z1,...,xn,yn,zn.
degree:样条曲线的阶次,可选二次或者三次.
num_div : 两点之间细分线段的数量.
dims:坐标点的维度数,可以是二维或者三维.
results:保存计算结果的缓冲区,数据排布格式为x0,y0,z0,x1,y1,z1.....xn,yn,zn
'*/
void b_spline(float* p_array, int degree, int num_div, int dims, float* results)
{
float scale = 1.0f / num_div;
float t, t1, t2, t3, b0, b1, b2, b3;
if (degree == 2)
{
for (int i = 0; i <= num_div; i++)
{
t = i * scale;
t1 = t;
t2 = t1 * t;
b0 = 0.5 * (t2 - 2 * t1 + 1);
b1 = 0.5*(-2*t2+2*t1+1);
b2 = 0.5 * t2;
for (int j = 0; j < dims; j++)
{
results[i * dims + j] = p_array[j] * b0 + p_array[dims+j] * b1 + p_array[2*dims+j] * b2;
}
}
}
else
{
for (int i = 0; i <= num_div; i++)
{
t = i * scale;
t1 = t;
t2 = t1 * t;
t3 = t2 * t;
b0 =(-t3+3*t2-3*t1+1)/6.0;
b1 =(3*t3-6*t2+4)/6.0;
b2 =(-3*t3+3*t2+3*t1+1)/6.0;
b3 =t3/6.0;
for (int j = 0; j < dims; j++)
{
results[i * dims + j] = p_array[j] * b0 + p_array[dims+j] * b1 + p_array[2*dims+j] * b2+p_array[3*dims+j]*b3;
}
}
}
}
/*
通过一系列散点生成b样条平滑曲线.
p_array : 曲线散点序列,数组形状为(N, 2), 或者(N, 3), 点的坐标是二维坐标(x, y)或三维坐标(x, y, z).例如,散点输入为 [[1, 2, 3], [2, 1, 1], ...] .
num_points:输入散的点数量.
degree:样条曲线的阶次.
num_div : 两散点之间划分的线段数量,数值越大,线段越多,曲线越平滑.
dims:坐标点的维度数,可以是二维或者三维.
results:保存计算结果的缓冲区,数据排布格式为x0,y0,z0,x1,y1,z1.....xn,yn,zn.
*/
void b_spline_curve(float* p_array, int num_points, int degree, int num_div, int dims, float* results)
{
float* points = (float*)malloc(sizeof(float) * (num_points+2) * dims);
if (degree == 2)
{
for (int i = 0; i < dims; i++)
{
points[i] = p_array[i];
}
float* q = &points[dims];
int m = num_points * dims;
for (int i = 0; i < m; i++)
{
*q= p_array[i];
q++;
}
for (int i = 0; i < dims; i++)
{
q[i] = p_array[(num_points - 1) * dims + i];
}
}
else
{
for (int i = 0; i < dims; i++)
{
points[i] = 2 * p_array[i] - p_array[dims+i];
}
float* q = &points[dims];
int m = num_points * dims;
for (int i = 0; i < m; i++)
{
*q = p_array[i];
q++;
}
for (int i = 0; i < dims; i++)
{
q[i] = 2 * p_array[(num_points - 1) * dims + i] - p_array[(num_points - 2) * dims + i];
}
}
int num_seg = num_points+2-degree;
for (int i = 0; i <num_seg; i++)
{
int j = i * dims;
int offset = i * num_div * dims;
b_spline(&points[j],degree,num_div,dims,&results[offset]);
}
free(points);
}
没有合适的资源?快使用搜索试试~ 我知道了~
温馨提示
这是一份C语言版本的b样条曲线算法代码,可以实现二次和三次的b样条曲线绘制,可作为曲线平滑或者曲线拟合的代码使用。代码实现封装为连个函数,一个是实现给定三点或者四点计算样条曲线平滑点,一个是计算一些列散点的平滑曲线。可实现二维平面曲线和三维空间曲线的样条曲线计算。样条曲线的阶次和曲线平滑度均可以通过函数的参数配置。代码具有必要的注释,可供使用者学习。还配备了一份测试代码,里边有一个使用案例,可供使用学习和参考。
资源推荐
资源详情
资源评论
收起资源包目录
b_spline_curve.zip (6个子文件)
bmp.cpp 3KB
b_spline_curve.bmp 768KB
bmp.h 165B
b_spline.cpp 3KB
b_spline.h 253B
test.cpp 1KB
共 6 条
- 1
资源评论
- ziyoudebailu2024-02-06资源使用价值高,内容详实,给了我很多新想法,感谢大佬分享~
- Xpray62023-11-02这个资源对我启发很大,受益匪浅,学到了很多,谢谢分享~
- m0_510197762024-02-11资源和描述一致,质量不错,解决了我的问题,感谢资源主。
- paidahai882024-07-28资源很赞,希望多一些这类资源。
- 2401_849786112024-05-21资源内容详尽,对我有使用价值,谢谢资源主的分享。
shifenglv
- 粉丝: 1468
- 资源: 78
下载权益
C知道特权
VIP文章
课程特权
开通VIP
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功