欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

绘制Bezier三角面片

程序员文章站 2022-07-14 16:13:55
...

算法简介

首先要介绍的是三角形的重心坐标

重心坐标

重心坐标的几何意义如下图

绘制Bezier三角面片

三角域Bernstein基函数

设T=(P0,P1,P2)非奇异,P=uP0+vP1+wP2,重心坐标满足(u+v+w)^n=1,展开得

绘制Bezier三角面片

绘制Bezier三角面片

为三角域Bernstein基函数

Bezier三角(曲面)片

设{Q_i,j,k,i+j+k=n}是给定的一组R3中的点,则称

绘制Bezier三角面片

为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)
实现效果如下图

绘制Bezier三角面片

我这里是用一个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);

绘制Bezier三角面片

实现效果如下图