看的第二篇论文matlab程序实现
程序员文章站
2022-04-14 08:19:20
...
一、直纹面边界为二次Bezier曲线设计成可展曲面
有关第二篇论文博客的超链接
论文二次部分的理论:
二、相应的matlab程序:
% date : 2020.10.14
% 第三篇论文的编程实现
% Developable Bezier patches: properties and design
% 双二次的可展曲面设计
% author : mw_1422102031
clear;
clc;
% 直纹面编程示例:
% 直纹面方程:p(u,v) = (1-u)*a(v) + u*b(v) ;
% 其中a(v),b(v)程序中分别取了两个bezier曲线
clear;
clc;
%A曲线的控制顶点
A0 = [0,0,1]; A1 = [1,2,3]; A2 = [2,1,0];
ax = [A0(1),A1(1),A2(1)];
ay = [A0(2),A1(2),A2(2)];
az = [A0(3),A1(3),A2(3)];
[U,V] = meshgrid(0:0.02:1,0:0.02:1);
%给定c0,c2的方向向量
c0 = 0.01*[0,0,2];
c2 = 0.01*[0,3,-1];
%另外一组方向向量
% c0 = 0.01*[0,0,1];
% c2 = 0.01*[1,3,-1];
% 给定参数f的值
f = 125;
%由控制顶点计算a1,a2
a1 = [];
a2 = [];
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);
%求c1的具体数值; cross():叉乘命令
N1 = cross(a1,c0) ;
N2 = cross(a2,c2) ;
c1 = cross(N1,N2) ;
%求参数s的值,需要计算两个行列式
p1 = det([a1;c2;c1]);
q1 = 1/(det([a2;c0;c2]));
s = f*p1*q1;
%求参数t的值
p2 = det([a2;c1;c0]);
q2 = 1/(det([a1;c0;c2]));
t = f*p2*q2;
%计算B曲线的的控制顶点
B0 = A0 + f*s*c0; B1 = A1 + f*c1; B2 = A2 + f*t*c2;
bx = [B0(1),B1(1),B2(1)];
by = [B0(2),B1(2),B2(2)];
bz = [B0(3),B1(3),B2(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)
需要用到的函数(之前文章中都给过,之后可能就不详细列出来了):
% 第i个bernstein基函数
function y = B(x,n,i)
y = N(n,i).*(x.^i).*((1-x).^(n-i));
end
% 组合数 Number of combinations
function y = N(n,i)
y1 = factorial(n); %n的阶乘
y2 = factorial(i)*factorial(n-i);
y = y1/y2;
end