双三次Bezier可展曲面及matlab实现

一、理论出处

       本次实现三次Bezier可展曲面的理论出处为:

       
       作者: Chih-Hsing Chu, Carlo H. Sequin
       
       文章名: Developable Bezier patches: properties and design
       
       出处: Computer-Aided Design 34 (2002) 511—527

       
       
       
       

二、可展的相关理论及算法

具体图示:
       
       
在这里插入图片描述
在这里插入图片描述
具体理论:
       
       

在这里插入图片描述
       
       
在这里插入图片描述
       
       

在这里插入图片描述

四、 matlab程序实现

function Developable_Cubic_surface
% date : 2020.10.16 ---- 202.10.17
% 第三篇论文的编程实现
% Developable Bezier patches: properties and design
% 双三次的可展曲面设计
% author : mw_1422102031
clear;
clc;
%A曲线的控制顶点
A0 = [0,0,0.1];  A1 = [1,2,2];  A2 = [2,1,1]; A3 = [3,0,-3]; 
ax = [A0(1),A1(1),A2(1),A3(1)];
ay = [A0(2),A1(2),A2(2),A3(2)];
az = [A0(3),A1(3),A2(3),A3(3)];                                  
[U,V] = meshgrid(0:0.05:1,0:0.05:1);
%给定c0,c3的方向向量
c0 = [0,1,1]; 
c3 = [0,3,-1];   
%由控制顶点计算a1,a2,a3
a1 = [];    a2 = [];     a3 = [];
a1(1) = ax(2) - ax(1);  a1(2) = ay(2) - ay(1);  a1(3) = az(2) - az(1);
a2(1) = ax(3) - ax(2);  a2(2) = ay(3) - ay(2);  a2(3) = az(3) - az(2);
a3(1) = ax(4) - ax(3);  a3(2) = ay(4) - ay(3);  a3(3) = az(4) - az(3);
%计算求解过程中的中间量
d11 = -det([a2;c0;a1])*det([a3;c0;c3]);
d = det([a2;c0;a1])*det([a2;a3;c3]) - det([a1;c0;a3])*det([a3;a1;c3]);
d1 = d11 / d;

d21 = det([a1;c0;c3])*det([a3;a1;c3]);
d2 = d21 / d;

d31 = det([a1;c0;a3])*det([a3;c0;c3]);
d3 = d31 / d;

d41 = -det([a1;c0;c3])*det([a2;a3;c3]);
d4 = d41 / d;

% 计算非线性方程组的系数
f1 = det([a1;c0;a3]);
f2 = 3*det([a1;c0;c3])          +    3*d2*det([a1;c0;a3]);
f3 = 3*d1* det([a1;c0;a3]);
f4 = 4* det([a2;c0;c3])         +    4*d2* det([a2;c0;a3])     +      d4* det([a3;c0;a1]);
f5 = 4*d1* det([a2;c0;a3])    +    d3* det([a3;c0;a1]);

g1 = d1* det([a1;a3;c3])      +    4*d3* det([a2;a1;c3])     +      4* det([a2;c0;c3]);
g2 = d2* det([a1;a3;c3])      +    4*d4* det([a2;a1;c3]);
g3 = det([a3;c0;c3]);
g4 = 3* det([a3;c0;c3])        +    3*d3* det([a3;a1;c3]);
g5 = 3*d4* det([a3;a1;c3]);

h1 = det([a1;c0;c3]);
h2 = det([a2;c0;c3]);
h3 = 3*det([a2;c0;c3])        +    3*d3* det([a2;a1;c3])        +     3*d2*det([a2;c0;a3]) + ...
        3*d1*d4*det([a2;a1;a3])   +   3*d2*d3*det([a2;a1;a3]);
h4 = 3*d4*det([a2;a1;c3])   +    3*d2*d4*det([a2;a1;a3]);
h5 = 3*d1*det([a2;a1;a3])   +    3*d1*d3*det([a2;a1;a3]);
h6 = det([a3;c0;c3]);

k = 1;
syms x y z
f(x,y,z)   =   f1*x*y    +   f2*k*z    +   f3*z^2   +   f4*k*x    +     f5*x*z;
g(x,y,z)  =   g1*y*z   +   g2*k*y   +   g3*x*y   +  g4*k*z    +    g5*k^2;
h(x,y,z)  =   h1*y*z   +   h2*x*y   +   h3*k*z   +  h4*k^2    +    h5*z^2  +  h6*k*x;

eqns = [f(x,y,z)==0,g(x,y,z)==0,h(x,y,z)==0];
[x,y,z] = vpasolve(eqns,x,y,z);    %会出现多个解
% 得到的的非线性方程组的解不唯一,成为了列向量的形式
A = [x,y,z];

%求解非线性方程组得到的向量A(:,i) = (α,β,μ),i = 1,2,3,...;  α,β,μ对应论文中的未知量
%确定c0,c3 的具体向量值,求解c1,c2
%β = beta , α = alpha , μ =  mu , η = eta = k,    ρ = rho ,δ = delta 
x = A(:,2);
%因为求出来的解是虚数,我将虚数取模了
x = [norm(x(1),Inf),norm(x(2),Inf),norm(x(3),Inf)];
c0_bar = x(1)*c0;
c3_bar = x(2)*c3;

rho = d1*x(3) + d2*k;
delta = d3*x(3) + d4*k;
c1 = x(3)*c0 + delta*a1;
c2 = k*c3 + rho*a3;

%计算B曲线的的控制顶点
B0 = A0 + c0_bar;  B1 = A1 + c1;  B2 = A2 + c2;  B3 = A3 + c3_bar;
bx = [B0(1),B1(1),B2(1),B3(1)];
by = [B0(2),B1(2),B2(2),B3(2)];
bz = [B0(3),B1(3),B2(3),B3(3)];

%A_bezier曲线
x = V;
n=length(ax)-1;
Ax = 0;
Ay = 0;
Az = 0;
for i = 1:n+1
    Ax = Ax + ax(i)*B(x,n,i-1) ;       %将控制顶点与Bernstein基函数相乘得到bezier曲线
    Ay = Ay + ay(i)*B(x,n,i-1) ;
    Az = Az + az(i)*B(x,n,i-1) ;
end
figure(1)
plot3(ax,ay,az,'k',ax,ay,az,'m*')         %控制多边形
hold on
plot3(Ax,Ay,Az,'r')                             %bezier曲线A(v)
%B_bezier曲线
x = V;
n=length(bx)-1;
Bx = 0;  By = 0;  Bz = 0;
for i = 1:n+1
    Bx = Bx + bx(i)*B(x,n,i-1) ;       %将控制顶点与Bernstein基函数相乘得到bezier曲线
    By = By + by(i)*B(x,n,i-1) ;
    Bz = Bz + bz(i)*B(x,n,i-1) ;
end
figure(2)
plot3(bx,by,bz,'k',bx,by,bz,'m*')               %控制多边形
hold on
plot3(Bx,By,Bz,'r')   

%将两条边界bezier曲线带入直纹面方程
X = (1-U).*Ax + U.*Bx ;
Y = (1-U).*Ay + U.*By ;
Z = (1-U).*Az + U.*Bz ;
%两种方式画图
figure(3)
mesh(X,Y,Z)

end

       
       
结果显示:
在这里插入图片描述

       
       
       
       
具体的理论在我之前的博客里面有:https://blog.csdn.net/mw_1422102031/article/details/108932741
超链接

五、 matlab程序实现(中间编程出错误的版本)

function X_Developable_Cubic_surface
%用一般牛顿法求解非线性方程出现错误,可能涉及到精度问题,具体原因不找了
% date : 2020.10.16 ---- 202.10.17
% 第三篇论文的编程实现
% Developable Bezier patches: properties and design
% 双三次的可展曲面设计
% author : mw_1422102031
clear;
clc;
%A曲线的控制顶点
A0 = [0,0,0];  A1 = [1,2,2];  A2 = [2,1,1]; A3 = [3,0,-1]; 
ax = [A0(1),A1(1),A2(1),A3(1)];
ay = [A0(2),A1(2),A2(2),A3(2)];
az = [A0(3),A1(3),A2(3),A3(3)];                                  
[U,V] = meshgrid(0:0.02:1,0:0.02:1);
%给定c0,c3的方向向量
c0 = 0.01*[0,1,1]; 
c3 = 0.01*[0,3,-1];   
%由控制顶点计算a1,a2,a3
a1 = [];    a2 = [];     a3 = [];
a1(1) = ax(2) - ax(1);  a1(2) = ay(2) - ay(1);  a1(3) = az(2) - az(1);
a2(1) = ax(3) - ax(2);  a2(2) = ay(3) - ay(2);  a2(3) = az(3) - az(2);
a3(1) = ax(4) - ax(3);  a3(2) = ay(4) - ay(3);  a3(3) = az(4) - az(3);
%计算求解过程中的中间量
d11 = -det([a2;c0;a1])*det([a3;c0;c3]);
d = det([a2;c0;a1])*det([a2;a3;c3]) - det([a1;c0;a3])*det([a3;a1;c3]);
d1 = d11 / d;

d21 = det([a1;c0;c3])*det([a3;a1;c3]);
d2 = d21 / d;

d31 = det([a1;c0;a3])*det([a3;c0;c3]);
d3 = d31 / d;

d41 = -det([a1;c0;c3])*det([a2;a3;c3]);
d4 = d41 / d;

% 计算非线性方程组的系数
f1 = det([a1;c0;a3]);
f2 = 3*det([a1;c0;c3])          +    3*d2*det([a1;c0;a3]);
f3 = 3*d1* det([a1;c0;a3]);
f4 = 4* det([a2;c0;c3])         +    4*d2* det([a2;c0;a3])     +      d4* det([a3;c0;a1]);
f5 = 4*d1* det([a2;c0;a3])    +    d3* det([a3;c0;a1]);

g1 = d1* det([a1;a3;c3])      +    4*d3* det([a2;a1;c3])     +      4* det([a2;c0;c3]);
g2 = d2* det([a1;a3;c3])      +    4*d4* det([a2;a1;c3]);
g3 = det([a3;c0;c3]);
g4 = 3* det([a3;c0;c3])        +    3*d3* det([a3;a1;c3]);
g5 = 3*d4* det([a3;a1;c3]);

h1 = det([a1;c0;c3]);
h2 = det([a2;c0;c3]);
h3 = 3*det([a2;c0;c3])        +    3*d3* det([a2;a1;c3])        +     3*d2*det([a2;c0;a3]) + ...
        3*d1*d4*det([a2;a1;a3])   +   3*d2*d3*det([a2;a1;a3]);
h4 = 3*d4*det([a2;a1;c3])   +    3*d2*d4*det([a2;a1;a3]);
h5 = 3*d1*det([a2;a1;a3])   +    3*d1*d3*det([a2;a1;a3]);
h6 = det([a3;c0;c3]);

%给出非线性方程组
k = 1.5;
syms x y z
f(x,y,z)   =   f1*x*y    +   f2*k*z    +   f3*z^2   +   f4*k*x    +     f5*x*z;
g(x,y,z)  =   g1*y*z   +   g2*k*y   +   g3*x*y   +  g4*k*z    +    g5*k^2;
h(x,y,z)  =   h1*y*z   +   h2*x*y   +   h3*k*z   +  h4*k^2    +    h5*z^2  +  h6*k*x;
%求这三个方程的偏导数
f_1(x,y,z) = diff(f(x,y,z),x);    f_2(x,y,z) = diff(f(x,y,z),y);    f_3(x,y,z) = diff(f(x,y,z),z);
g_1(x,y,z) = diff(g(x,y,z),x);  g_2(x,y,z) = diff(g(x,y,z),y);  g_3(x,y,z) = diff(g(x,y,z),z);
h_1(x,y,z) = diff(h(x,y,z),x);  h_2(x,y,z) = diff(h(x,y,z),2);  h_3(x,y,z) = diff(h(x,y,z),z);
%%一般牛顿法求解非线性方程组
x0 = [0.1, 0.1, -0.1]';
eps1 = 1e-8 ;
eps2 = 1e-8 ;
KMAX = 20;

x = x0;
k = 0;
for k = 0:KMAX
    %求解F(x)
    m = zeros(size(x));
    m(1) = f(x(1),x(2),x(3)) ;
    m(2) = g(x(1),x(2),x(3)) ;
    m(3) = h(x(1),x(2),x(3)) ;
    b = m;
    norm_b = norm(b,Inf);
    if norm_b<eps1
        break
    end
    %求解Jac(x)
    A = [];
    A = [f_1(x(1),x(2),x(3)),     f_2(x(1),x(2),x(3)),    f_3(x(1),x(2),x(3));...
           g_1(x(1),x(2),x(3)),    g_2(x(1),x(2),x(3)),   g_3(x(1),x(2),x(3));...
           h_1(x(1),x(2),x(3)),    h_2(x(1),x(2),x(3)),    h_3(x(1),x(2),x(3))];
    dx = -A\b;
    x = x+dx;
    norm_dx = norm(dx,Inf);
    if norm_dx < eps2
        break
    end
end
x
%求解非线性方程组得到的向量x = (α,β,μ);  α,β,μ对应论文中的参数
%确定c0,c3 的具体向量值,求解c1,c2
%β = beta , α = alpha , μ =  mu , η = eta = k,    ρ = rho ,δ = delta  
c0_bar = x(1)*c0;
c3_bar = x(2)*c3;

rho = d1*x(3) + d2*k;
delta = d3*x(3) + d4*k;
c1 = x(3)*c0 + delta*a1;
c2 = k*c3 + rho*a3;

%计算B曲线的的控制顶点
B0 = A0 + c0_bar;  B1 = A1 + c1;  B2 = A2 + c2;  B3 = A3 + c3_bar;
bx = [B0(1),B1(1),B2(1),B3(1)];
by = [B0(2),B1(2),B2(2),B3(2)];
bz = [B0(3),B1(3),B2(3),B3(3)];

%A_bezier曲线
x = V;
n=length(ax)-1;
Ax = 0;
Ay = 0;
Az = 0;
for i = 1:n+1
    Ax = Ax + ax(i)*B(x,n,i-1) ;       %将控制顶点与Bernstein基函数相乘得到bezier曲线
    Ay = Ay + ay(i)*B(x,n,i-1) ;
    Az = Az + az(i)*B(x,n,i-1) ;
end
figure(1)
plot3(ax,ay,az,'k',ax,ay,az,'m*')         %控制多边形
hold on
plot3(Ax,Ay,Az,'r')                             %bezier曲线A(v)
%B_bezier曲线
x = V;
n=length(bx)-1;
Bx = 0;  By = 0;  Bz = 0;
for i = 1:n+1
    Bx = Bx + bx(i)*B(x,n,i-1) ;       %将控制顶点与Bernstein基函数相乘得到bezier曲线
    By = By + by(i)*B(x,n,i-1) ;
    Bz = Bz + bz(i)*B(x,n,i-1) ;
end
figure(2)
plot3(bx,by,bz,'k',bx,by,bz,'m*')               %控制多边形
hold on
plot3(Bx,By,Bz,'r')   

%将两条边界bezier曲线带入直纹面方程
X = (1-U).*Ax + U.*Bx ;
Y = (1-U).*Ay + U.*By ;
Z = (1-U).*Az + U.*Bz ;
%两种方式画图
figure(3)
mesh(X,Y,Z)

end


       
       结果就不展示了,本身这个编程就是失败的。
       
       这个我用一般牛顿法去求解非线性方程组,中间迭代的时候一直出错,并且得到得结果是错的。然后用matlab中自带的求解非线性方程组的方法把这个问题解决的。

       
       

  • 3
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
双三次B样条曲面C是一种用于描绘三维空间中曲面的数学工具。它是由二维的双三次B样条曲线扩而来,通过在两个参数方向上应用双三次插值来生成曲面双三次B样条曲面C由一个矩形控制网格和一组控制点组成。矩形控制网格由两个参数u和v定义,分别对应曲面上的位置。控制点则是用于定义曲面的形状和结构的点。 在生成双三次B样条曲面C时,首先需要创建一个规则的控制网格,并在该网格的顶点位置上放置控制点。接下来,在每个网格单元中使用双三次插值方法来确定曲线上的其他点。这些插值点的位置将由其相邻的控制点决定。 双三次B样条曲面C具有平滑的外观和柔和的过渡特性。这是由于其插值方法所带来的效果。在曲线上的每个点,其位置是根据其周围若干个控制点的位置来确定的,从而使得整个曲面具有高度的平滑性。 另外,双三次B样条曲面C也具有局部调整性。这意味着在修改曲面形状时,只需要改变控制点的位置,而不会对整个曲面进行重新计算。这种特性使得双三次B样条曲面C在计算机图形学和计算机辅助设计等领域中得到广泛应用。 总而言之,双三次B样条曲面C是一种用于描述三维空间中曲面的数学工具。它通过插值方法生成平滑的曲面,并具有局部调整性。这种曲面在计算机图形学和计算机辅助设计等领域中具有重要应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值