机械硕士转码开篇——基于符号距离场的隐式几何造型与MATLAB可视化实现

1.前言

        985机械硕士在读,研究方向涉及计算机图形学(建模)、拓扑优化等,正在努力学习C++和MATLAB,希望早日脱离苦海(bushi)。想着单纯的看代码和论文略显枯燥,干脆写一点东西记录和分享一下学习内容。这是我第一次写博客,请各位大佬评论区提出宝贵意见。文章展示了我的本科毕业设计部分成果(还是优秀毕业设计哈哈),希望起到抛砖引玉的作用。

2.文章概述

        本文简单介绍了隐式几何造型和符号距离场的概念(3.1),并在(3.2)节中推导了两种简单二维图形的符号距离函数。之后,在(3.3)节中介绍了基于符号距离场的交、并、减三种模型运算和阵列方法。最后,在文章的第4节中介绍了使用MATLAB计算符号距离场和模型操作的算法并进行可视化。

3.隐式几何造型与符号距离场

3.1概念介绍

        符号距离函数(Signed Distance Function)是一种隐式几何表示方法,与显式几何表示方法不同的是,对于一个模型,基于符号距离函数的隐式方法不直接描述它的表面,而是描述在空间中的一个有限区域上确定一个点到区域边界的距离并同时对距离的符号进行定义:点在区域边界内部为挣,外部为负,位于边界上时为0。符号距离场(Signed Distance Function)是指空间域中的点集与几何模型距离的标量场。图1所示为正方形的符号距离场描述。

图1 正方形的符号距离场

         图1中,黑色虚线框为正方形的实体边界,蓝色表示正方形内部,红色表示正方形外部。图中的点旁边的数字表示该点与正方形边界的有符号距离。隐式几何表示的特点为:不表达点的具体位置,而表示点与点的关系(这些点的排列满足一定的函数关系)。其他隐式几何表示方法包括水平集法、代数曲面法和构造实体几何法等。其优点在于不存在采样误差,方便判断点的拓扑关系,但寻找所有在物体上的点较为困难。

图3 构造实体几何法

3.2两种简单图形的符号距离函数推导

        符号距离函数的定义式为:

其中,\vec{x}是点的坐标向量,\Omega表示模型实体。首先对几何形式较为简单的长方形符号距离函数进行推导,将坐标系划分区域如图4所示。

图4 长方形符号距离函数推导

 根据蓝色边界线和红色虚线可以将第一象限划分为4个部分,对于每个部分直接上公式:

 上述公式过于复杂,为了方便编程,对上述四种情况进行形式上的统一,有:

 由于长方形的对称性,第二、三和四象限情况与第一象限情况相同,只需将坐标值分别取绝对值即可转换至第一象限的情况,MATLAB代码如下:

function [X,Y,Z]=myRoundBoxSDF(x,y,a,r)
%x,y为平面坐标向量,a为顶点坐标向量,r为倒角圆半径
[X,Y]=meshgrid(x,y);
b=a-r;
qx=abs(X)-b(1);
qy=abs(Y)-b(2);
Z1=sqrt(max(qx,0).^2+max(qy,0).^2);
Z2=min(max(qx,qy),0);
%直接在符号距离场上减掉倒角圆半径实现倒角操作
Z=Z1+Z2-r;
end

        之后再浅浅的推导一个十字形,同样地,对第一象限区域划分如图5所示。

图5 十字形符号距离函数推导

根据红色虚线和图形边界将第一象限划分为5个部分,其余部分利用对称性均可通过这5个部分得到,直接上公式:

实际上,1、2、3和4区域是以a为顶点的正方形的符号距离函数,对上述两个式子进行形式上的统一有:

 其中

 MATLAB代码如下:

function z=sdCross(x,y,b,r)
% x,y为单个点的坐标(与上文不同),b为顶点坐标,r为圆角半径
px=abs(x);
py=abs(y);
if py>px
    t=px;
    px=py;
    py=t;
end
qx=px-b(1);
qy=py-b(2);
k=max(qx,qy);
if k>0
    wx=qx;
    wy=qy;
else
    wx=b(2)-px;
    wy=-k;
end
wx=max(wx,0);
wy=max(wy,0);
z=r+sign(k)*sqrt(wx^2+wy^2);
end

3.3模型布尔运算及阵列操作

        利用符号距离场的性质定义运算:

其中D为模型的符号距离场,从上到下依次为模型的并、减、交三种布尔运算,具体过程如图6所示。

图6 正方体与圆球的布尔运算

        对于模型的线性阵列,只需要将符号距离值映射到平面内其他点即可,映射关系如下:

 其中c_1,c_2分别为x,y方向上的间隔尺寸。

4.MATLAB可视化与实现

        先上效果图。

图7 正方形符号距离场
图8 十字形符号距离场

分享一套绘制等值线图的模板,取自微信公众号阿昆的科研百宝箱,相关数据和设置大家根据自己需求来。

%% 数据准备
clc
clear
load("yuanzhujiemian.mat");
x=-20:0.2:20;
y=-10:0.2:70;
[X,Y]=meshgrid(x,y);
[m,n]=size(X);
Z=zeros(m,n);
for i=1:m
    for j=1:n
        Z(i,j)=CZGsdf(j,100,i);
    end
end
%% 颜色定义
map = addcolorplus(297);
%% 图片尺寸设置(单位:厘米)
figureUnits = 'centimeters';
figureWidth = 16;
figureHeight = 10;
%% 窗口设置
figureHandle = figure;
set(gcf, 'Units', figureUnits, 'Position', [0 0 figureWidth figureHeight]);
%% 绘制等高线填充图
[C,h] = contourf(X, Y, Z,8, 'LineWidth',1.2);
clabel(C,h,0,"FontSize",12);
hTitle = title('SDF of longitudinal-section');
hXLabel = xlabel('XAxis');
hYLabel = ylabel('ZAxis');
%% 细节优化
% 赋色
colormap(map)
colorbar
% 坐标轴美化
axis equal
set(gca, 'Box', 'off', ...                                        % 边框
         'LineWidth', 1,...                                       % 线宽
         'XGrid', 'off', 'YGrid', 'off', ...                      % 网格
         'TickDir', 'out', 'TickLength', [.015 .015], ...         % 刻度
         'XMinorTick', 'on', 'YMinorTick', 'on', ...              % 小刻度
         'XColor', [.1 .1 .1],  'YColor', [.1 .1 .1])             % 坐标轴颜色
% 添加上、右框线
hold on
XL = get(gca,'xlim'); XR = XL(2);
YL = get(gca,'ylim'); YT = YL(2);
xc = get(gca,'XColor');
yc = get(gca,'YColor');
plot(XL,YT*ones(size(XL)),'color', xc,'LineWidth',1)
plot(XR*ones(size(YL)),YL,'color', yc,'LineWidth',1)
% 字体和字号
set(gca, 'FontName', 'Helvetica')
set([hXLabel, hYLabel], 'FontName', 'AvantGarde')
set(gca, 'FontSize', 10)
set([hXLabel, hYLabel], 'FontSize', 11)
set(hTitle, 'FontSize', 11, 'FontWeight' , 'bold')
% 背景颜色
set(gcf,'Color',[1 1 1])
%% 图片输出
figW = figureWidth;
figH = figureHeight;
set(figureHandle,'PaperUnits',figureUnits);
set(figureHandle,'PaperPosition',[0 0 figW figH]);
fileout = 'test';
print(figureHandle,[fileout,'.png'],'-r300','-dpng');

5.小结

        因为后续可能会被抽检,上述为我论文中的一小部分,有些地方解释的还不太清楚(主要怕后续查重),第一次写肯定有很多纰漏,请大家多多包涵与指正。后续应该会先更新一些C++和数据结构的相关知识,祝各位心想事成,点点关注不迷路!

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Topom

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值