#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);
}
shifenglv
- 粉丝: 1470
- 资源: 78
最新资源
- Oracle10gDBA学习手册中文PDF清晰版最新版本
- 扒网站数据软件项目全套技术资料100%好用.zip
- AI爬虫项目全套技术资料100%好用.zip
- 倪海厦讲义及笔记,易学数据测算
- 智能图书管理系统项目全套技术资料.zip
- 基于java写的爬虫项目全套技术资料.zip
- 218) Leverage - 创意机构与作品集 WordPress 主题 2.2.7.zip
- 220) Vinkmag - 多概念创意报纸新闻杂志 WordPress v5.0.zip
- 219) Axtra - 数字机构创意作品集主题 v2.0.zip
- 217) Voice - 清洁新闻 - 杂志 WordPress 主题 v3.0.3.zip
- 215) Classiera – 分类广告 WordPress 主题 v4.0.28.zip
- 216) Creote - 企业与咨询业务 WordPress 主题 v2.7.8.zip
- 212) Outgrid - 多用途 Elementor WordPress 主题 v2.0.0.zip
- 213) Blacksilver - 摄影 WordPress 主题 v9.4.zip
- 214) Nokri - 招聘板 WordPress 主题 v1.5.9.zip
- 211) TopDeal - 多供应商市场 WordPress 主题(移动布局就绪) v2.3.15.zip
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈