绘制Bezier三角面片
程序员文章站
2022-07-14 16:13:55
...
算法简介
首先要介绍的是三角形的重心坐标
重心坐标
重心坐标的几何意义如下图
三角域Bernstein基函数
设T=(P0,P1,P2)非奇异,P=uP0+vP1+wP2,重心坐标满足(u+v+w)^n=1,展开得
记
为三角域Bernstein基函数
Bezier三角(曲面)片
设{Q_i,j,k,i+j+k=n}是给定的一组R3中的点,则称
为T上的n次Bezier三角片
实验结果
下面为实现的函数,其中控制顶点是n*n个控制点,num表示把每条边分为多少份表示
function trepBer = triBerzier( controls,num)
%TRIBERZIER Summary of this function goes here
% Detailed explanation goes here
points=cell(num,num);
for i=1:num
for j=1:i
points{i,j}=[(j-1)*(1/(num-1)),1-(i-1)*(1/(num-1)),(i-j)*(1/(num-1))];
end
end
n=size(controls,1);
Bpoints=cell(num,num);
for i=1:num
for j=1:i
Bpoints{i,j}=[0,0,0];
for u=1:n
for v=1:u
%i=v-1;j=n-u;k=u-v
Bpoints{i,j}=Bpoints{i,j}+controls{u,v}*2/(factorial(v-1)*factorial(n-u)*factorial(u-v))*(points{i,j}(1)^(v-1)*points{i,j}(2)^(n-u)*points{i,j}(3)^(u-v));
end
end
end
end
triConPoi=zeros(n*(n+1)/2,3);
temp=1;
for i=1:n
for j=1:i
triConPoi(temp,:)=controls{i,j};
temp=temp+1;
end
end
triConSur=zeros((n-1)^2,3);
temp=1;
for i=2:n%the first in the i-th line is n(n-1)/2
for j=1:i-1
%Counter clockwise order,up triangle
triConSur(temp,:)=[i*(i-1)/2+j,i*(i-1)/2+j+1,i*(i-1)/2+j+1-i];
temp=temp+1;
end
end
for i=2:n-1%the first in the i-th line is n(n-1)/2
for j=1:i-1
%Counter clockwise order,down triangle
triConSur(temp,:)=[i*(i-1)/2+j+1,i*(i-1)/2+j,i*(i-1)/2+j+1+i];
temp=temp+1;
end
end
trepCon=triangulation(triConSur,triConPoi);
triBezPoi=zeros(n*(n+1)/2,3);
temp=1;
for i=1:num
for j=1:i
triBezPoi(temp,:)=Bpoints{i,j};
temp=temp+1;
end
end
triBerSur=zeros((num-1)^2,3);
temp=1;
for i=2:num%the first in the i-th line is n(n-1)/2
for j=1:i-1
%Counter clockwise order,up triangle
triBerSur(temp,:)=[i*(i-1)/2+j,i*(i-1)/2+j+1,i*(i-1)/2+j+1-i];
temp=temp+1;
end
end
for i=2:num-1%the first in the i-th line is n(n-1)/2
for j=1:i-1
%Counter clockwise order,down triangle
triBerSur(temp,:)=[i*(i-1)/2+j+1,i*(i-1)/2+j,i*(i-1)/2+j+1+i];
temp=temp+1;
end
end
trepBer=triangulation(triBerSur,triBezPoi);
trisurf(trepCon,'edgecolor','k','FaceColor', 'interp');axis equal;alpha(.4);hold on;
trisurf(trepBer,'edgecolor','none','FaceColor', 'interp');alpha(.8);
% for i=1:3
% for j=1:i
% plot3(controls{i,j}(1),controls{i,j}(2),controls{i,j}(3),'r*');hold on;
% end
% end
% hold on;
% for i=1:num
% for j=1:i
% plot3(Bpoints{i,j}(1),Bpoints{i,j}(2),Bpoints{i,j}(3),'b*');hold on;
% end
% end
end
下面举一例controls = cell(3,3);
controls{1,1}=[0,0,0];
controls{2,1}=[0.5,1,-0.2];controls{2,2}=[-0.4,0.9,0.1];
controls{3,1}=[1,1.8,0];controls{3,2}=[0.1,2,0.1];controls{3,3}=[-0.9,1.9,-0.2];
trepBer = triBerzier( controls,30)
实现效果如下图
我这里是用一个30*30的三角网格逼近
再举一个三次的
controls = cell(4,4);
controls{1,1}=[0,0,0];
controls{2,1}=[0.5,1,-0.2];controls{2,2}=[-0.4,0.9,0.1];
controls{3,1}=[1,1.8,0];controls{3,2}=[0.1,2,0.1];controls{3,3}=[-0.9,1.9,-0.2];
controls{4,1}=[1.4,2.8,0.1];controls{4,2}=[0.4,2.95,-0.1];controls{4,3}=[-0.5,3.0,0];controls{4,4}=[-1.4,2.85,0.2];
trepBer = triBerzier( controls,30);
实现效果如下图
上一篇: 一堆数组