体积计算方法[1]
三角网格的所有三角面片围成的空间区域是封闭的,三角网格模型的体积可由每个三角面片的投影体积之和来计算。图1所示棱长为l的立方体,投影平面与下底面平行且距离为h。由于立方体各侧面内的三角面片与投影平面垂直,投影体积为0,因此立方体体积V 可由上下底面的4个三角面片t1、t2、t3 和t4的带符号投影体积来计算:
四面体的计算公式已知:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczLcVmds92czlGZvwVP9EUTDZ0aRJkSwk0LcxGbpZ2LcBDM08CXlpXazRnbvZ2LcRlMMVDT2EWNvwFdu9mZvwFMrR1T4hjVjRjTywEMW1mY1RzRapnTtxkb5ckYplTeMZTTINGMShUYvwFd4VGdvwlMvw1ayFWbyVGdhd3PwgzN1ITNwEzMwUDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
三角形面片在XOY平面的投影是个5面体,每个5面体可以拆分为3个四面体。
MATLAB程序如下:
clear;clc;
%从STL文件里读取法向量与三角形顶点坐标
fid=fopen('dakong.txt'); %打开文件
f=0; fnum=0; vnum=0; fmlie=1; vmlie=1;m=1; fmhang=1; vmhang=1;vshu=1; vz=0;
while feof(fid) == 0 %循环直到文件读取完成
tline = fgetl(fid); %逐行读取文件内容
fword = sscanf(tline, '%s '); %从获得的一行字符串中删除空格,提取字符型数据存储在fword指针上
if strncmpi(fword, 'f',1) == 1; %从'f'判断是不是法向量
f = sscanf(tline, '%*s %*s %lf %lf%lf'); %读取每个面的法向量的三个坐标(x,y,z)
fnum=fnum+1;
fm(fnum,:)=f';
end
if strncmpi(fword, 'v',1) == 1; % 从'v'判断是不是顶点坐标
v = sscanf(tline, '%*s %lf %lf %lf'); %读取每个三角形的三个顶点坐标(x,y,z)
vnum=vnum+1;
vm(vnum,:)=v';
end
end
fprintf(' The sum of trangle are: %d.\n',fnum); %输出三角形的数目
%计算STL模型的体积
while(fmhang<=fnum)
x1=vm(vmhang,1); y1=vm(vmhang,2); z1=vm(vmhang,3);
x2=vm(vmhang+1,1); y2=vm(vmhang+1,2); z2=vm(vmhang+1,3);
x3=vm(vmhang+2,1); y3=vm(vmhang+2,2); z3=vm(vmhang+2,3);
vmhang=vmhang+3;
VF=[1 1 1 1;x1 x2 x3 x2;y1 y2 y3 y2;z1 z2 z3 0]; %计算四面体的体积
VS=[1 1 1 1;x1 x1 x2 x3;y1 y1 y2 y3;z1 0 0z3];
VT=[1 1 1 1;x1 x2 x3 x3;y1 y2 y3 y3;0 0 0z3];
v1=(1/6)*abs(det(VF));
v2=(1/6)*abs(det(VS));
v3=(1/6)*abs(det(VT));
vds=v1+v2+v3;
f=fm(fmhang,:);
p=[0,0,1];
s=dot(f,p);
if(s>0) %判断三角形的法向量与投影平面的法向量的关系
vdscell(m,1)=vds;
end
if(s<0)
vdscell(m,1)=-vds;
end
m=m+1;
fmhang=fmhang+1;
end
while(vshu<=fnum)
vz=vz+vdscell(vshu,1); %对单独三角形的投影体积进行累加
vshu=vshu+1;
end
fprintf(' Volumn is: %fmm3.\n',vz);
[[i]]王泉德. 任意三角网格模型体积的快速精确计算方法[J]. 武汉:武汉大学.2009,45(18):32-58