# MATLAB | 一文解决各类曲面交线绘制，包含三维隐函数曲面交线

## 两显函数交线

% 显函数绘制曲面交线
[X,Y]=meshgrid(-2:.1:2);
Z1=5-2.*X-1.5.*Y;
Z2=X.^2+Y.^2;
% 绘制曲面
surf(X,Y,Z1,'EdgeColor','none','FaceAlpha',0.5,'FaceColor',[82,124,179]./255)
hold on
surf(X,Y,Z2,'EdgeColor','none','FaceAlpha',0.5,'FaceColor',[169,64,71]./255)
% 求出交线数值解并绘图
Z3=Z1-Z2;
CXY=contour3(X,Y,Z3,[0,0],'Visible','off');
CX=CXY(1,2:end);
CY=CXY(2,2:end);
% 以下两种方式均可，用任意显函数均可
plot3(CX,CY,5-2.*CX-1.5.*CY,'LineWidth',2,'Color',[0,0,0])
% plot3(CX,CY,CX.^2+CY.^2,'LineWidth',2,'Color',[0,0,0])
view(60,14)


## 显函数与隐函数交线

% 显函数与隐函数绘制曲面交线
f1=@(x,y,z)5-2.*x-1.5.*y-z;
f2=@(x,y,z)x.^2+y.^2+z.^2-12;

[X,Y]=meshgrid(-3:.1:4);
Z1=5-2.*X-1.5.*Y;

% 绘制曲面
surf(X,Y,Z1,'EdgeColor','none','FaceAlpha',0.5,'FaceColor',[82,124,179]./255)
hold on;
fimplicit3(f2,'EdgeColor','none','FaceAlpha',0.5,'FaceColor',[169,64,71]./255)

% 通过切片contour函数获取0等势面
[CX,CY,CZ]=meshgrid(-3:.1:4);
CV=f1(CX,CY,CZ)-f2(CX,CY,CZ);
S=contourslice(CX,CY,CZ,CV,X,Y,Z1,[0,0]);
S.EdgeColor=[0,0,0];
S.LineWidth=2;


## 两隐函数交线

{ y − x tan ⁡ ( z ) = 0 x 2 + y 2 = 1 \begin{cases} y-x\tan(z)=0\\ x^2+y^2=1 \end{cases}

function [nX,nY,nZ]=isocurve3(X,Y,Z,f1,f2)
% 获取f1隐函数的三角面和三角顶点
V1=f1(X,Y,Z);
hel=isosurface(X,Y,Z,V1,0);
% 将f1获取的三角顶点带入f2求得数值
V2=f2(hel.vertices(:,1),hel.vertices(:,2),hel.vertices(:,3));
% 检查三个顶点的数值是否同时含有有大于0数值及小于0数值
cross=(outcount==2)|(outcount==1);
crossing_tris=hel.faces(cross,:);
% 通过旋转交换三个顶点次序，将小于0的点放在第一列
flip=sum(out_vert,2)==1;
out_vert(flip,:)=1-out_vert(flip,:);
ntri=size(out_vert,1);
overt=zeros(ntri,3);
for i=1:ntri
v1i=find(~out_vert(i,:));
v2i=1+mod(v1i,3);
v3i=1+mod(v1i+1,3);
overt(i,:)=crossing_tris(i,[v1i v2i v3i]);
end
% 类似于求重心
u=(-V2(overt(:,1)))./(V2(overt(:,2))-V2(overt(:,1)));
v=(-V2(overt(:,1)))./(V2(overt(:,3))-V2(overt(:,1)));
uverts=repmat((1-u),[1 3]).*hel.vertices(overt(:,1),:)+repmat(u,[1 3]).*hel.vertices(overt(:,2),:);
vverts=repmat((1-v),[1 3]).*hel.vertices(overt(:,1),:)+repmat(v,[1 3]).*hel.vertices(overt(:,3),:);
% 因为可能含有多条曲线，因此逐段连线
nX=nan(3,ntri);
nX(1,:)=uverts(:,1)';
nX(2,:)=vverts(:,1)';
nY=nan(3,ntri);
nY(1,:)=uverts(:,2)';
nY(2,:)=vverts(:,2)';
nZ=nan(3,ntri);
nZ(1,:)=uverts(:,3)';
nZ(2,:)=vverts(:,3)';
end


f1=@(x,y,z)x.^2+y.^2-z.^2;
f2=@(x,y,z)x.^2+1.5*y.^2+z.^2-12;

% 绘制曲面
fimplicit3(f1,'EdgeColor','none','FaceAlpha',0.5,'FaceColor',[82,124,179]./255)
hold on;
fimplicit3(f2,'EdgeColor','none','FaceAlpha',0.5,'FaceColor',[169,64,71]./255)

[X,Y,Z]=meshgrid(-5:.1:5);
[nX,nY,nZ]=isocurve3(X,Y,Z,f1,f2);
line(nX(:),nY(:),nZ(:),'LineWidth',2,'Color',[0,0,0]);


• 14
点赞
• 50
收藏
• 打赏
• 8
评论
10-14 125
10-28 332
11-04 3289
07-16 2677
05-18 9336
12-04 3681
02-21 3万+
07-05 2691
02-22
03-09 2558

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

• 非常没帮助
• 没帮助
• 一般
• 有帮助
• 非常有帮助

slandarer

¥2 ¥4 ¥6 ¥10 ¥20

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