基于MATLAB的B样条曲面绘制

一、基础三次B样条曲面绘制

% 清空环境
clc; clear; close all;

% 定义控制点网格(3x3矩阵)
ctrlPoints = [
    0  0  0;
    2  0  1;
    4  0  0;
    0  2  0;
    2  2  1;
    4  2  0;
    0  4  0;
    2  4  1;
    4  4  0
];

% 转换为3D坐标矩阵
P = reshape(ctrlPoints', 3, 3, 3);

% 定义节点向量(均匀分布)
knots_u = [0 0 0 0 1 1 1 1];  % u方向节点向量
knots_v = [0 0 0 0 1 1 1 1];  % v方向节点向量

% 生成参数网格
[u, v] = ndgrid(linspace(0,1,20), linspace(0,1,20));

% 计算B样条基函数
def = spapi(4, knots_u, ctrlPoints(:,1));
def2 = spapi(4, knots_v, ctrlPoints(:,2));
def3 = spapi(4, knots_u, ctrlPoints(:,3));

% 计算曲面坐标
X = fnval(def, u);
Y = fnval(def2, v);
Z = zeros(size(X));

% 绘制曲面
figure;
surf(X, Y, Z, 'EdgeColor', 'none', 'FaceLighting', 'phong');
hold on;
plot3(ctrlPoints(:,1), ctrlPoints(:,2), ctrlPoints(:,3), 'ro-');
xlabel('X'); ylabel('Y'); zlabel('Z');
title('三次B样条曲面');
view(3); daspect([1 1 0.5]);
camlight; lighting gouraud;

二、关键参数解析

参数 说明 典型值
控制点矩阵 定义曲面形状的基准点 3x3或4x4矩阵
节点向量 控制B样条段连接方式的参数序列
阶数(k) 曲线段的多项式次数 3(三次B样条)
参数采样密度 网格细分程度 linspace(0,1,20)

三、进阶应用示例

1. 网格数据插值

% 生成网格数据
[Xi,Yi] = meshgrid(-5:0.5:5, -5:0.5:5);
Zi = peaks(Xi,Yi);

% 转换为控制点矩阵
ctrlPoints = [Xi(:), Yi(:), Zi(:)];

% 重构B样条曲面
knots = augknt([0 0 0 0 1 1 1 1], 3);
sp = spapi(knots, ctrlPoints);

% 参数采样
[u,v] = ndgrid(linspace(0,1,50));
[X,Y,Z] = fnval(sp, u, v);

% 绘制对比
figure;
subplot(1,2,1);
surf(Xi,Yi,Zi);
title('原始数据');
subplot(1,2,2);
surf(X,Y,Z);
title('B样条插值');

2. 动态曲面变形

% 创建交互式图形窗口
h = figure('MenuBar', 'none', 'ToolBar', 'none');

% 初始控制点
ctrlPoints = [linspace(-2,2,5)', linspace(-2,2,5)', peaks(5)];

% 创建曲面对象
surfCtrl = surf(ctrlPoints(:,1), ctrlPoints(:,2), ctrlPoints(:,3));
shading interp;
axis equal;
camva('auto');

% 定义更新函数
updateSurf = @(src,event) set(surfCtrl, ...
    'XData', ctrlPoints(:,1), ...
    'YData', ctrlPoints(:,2), ...
    'ZData', ctrlPoints(:,3));

% 添加滑块控件
s = uicontrol('Style','slider','Position',[20 20 200 20],...
    'Min',-2,'Max',2,'Value',0,'Callback',@(src,event) updateControl(src,value));

% 控制点更新函数
function updateControl(src,val)
    delta = val*(src.Max-src.Min)/100;
    ctrlPoints(:,3) = peaks(5) + delta*ones(5,1);
    updateSurf([]);
end

四、技术要点说明

  1. 节点向量构造

    • 使用augknt函数自动扩展节点向量:

      knots = augknt([0 0 0 0 1 1 1 1], 3);
      
    • 节点向量长度需满足:length(knots) = numCtrlPts + degree + 1

  2. 基函数计算 spapi函数自动生成B样条基函数对象 支持多维参数输入:fnval(sp, u, v)

  3. 可视化优化 光照效果:lighting gouraud 材质属性:material([0.8 0.8 0.8 10 0.5]) 交互式控制:通过callback函数实现动态调整

参考代码 matlab绘制B样条曲面代码 www.youwenfan.com/contentcnl/65421.html

五、应用场景对比

场景 控制点策略 节点向量选择
机械零件曲面 均匀分布+局部加密 均匀节点向量
汽车车身设计 非均匀分布(边缘密集) 非均匀节点向量
医学图像重建 基于采样点自适应分布 张力控制节点向量
建筑曲面设计 对称分布+关键点控制 分段均匀节点向量

六、性能优化

  1. 大规模数据处理

    % 使用稀疏矩阵存储
    ctrlPoints_sparse = sparse(ctrlPoints);
    
  2. GPU加速计算

    if canUseGPU
        ctrlPoints_gpu = gpuArray(ctrlPoints);
        [X,Y,Z] = fnval(sp, gpuArray(u), gpuArray(v));
    end
    
  3. 内存管理

    % 清理中间变量
    clear P def def2 def3;
    

七、扩展功能实现

1. 曲面连续性分析

% 计算连续性阶数
C0_continuity = all(diff(knots) > 1e-10);
C1_continuity = all(diff(knots,2) > 1e-10);
disp(['C0连续性: ', num2str(C0_continuity)]);
disp(['C1连续性: ', num2str(C1_continuity)]);

2. 曲率可视化

% 计算曲面主曲率
[~,c1,c2] = surfnorm(X,Y,Z);
curvature = (c1.^2.*c2)./(c1.^2 + c2.^2 + eps);

% 绘制曲率分布
figure;
surf(X,Y,Z,curvature,'EdgeColor','none');
colormap(jet);
colorbar;
title('主曲率分布');

posted @ 2025-11-12 16:35  w199899899  阅读(15)  评论(0)    收藏  举报