答案1
我是初学者tikz
,刚刚开发了这个,所以它不是很漂亮。我还添加了很多诊断文本,以帮助您理解我的逻辑。
它需要一个提供节点编号及其坐标的节点文件。
元素文件给出了元素编号和构成元素连通性的节点。无论它们是三角形、四边形还是其他形状,都没关系。
\drawmesh
在 a 内部使用的宏tikzpicture
创建 s 字符串\draw
以制定网格。注意数字、坐标、元素连接都存储在可访问、可扩展的数组\noddat[row,col]
和 中\eledat[row,col]
。
已编辑以添加宏\labelnodes
。
已编辑以添加宏\labelelements
。
已编辑以允许任何一个文件输入或手动输入节点和元素数据。文件输入方法如下:
\begin{filecontents*}{nodedata.dat}
1 0.000 0.000
2 1.000 0.000
3 2.000 0.500
4 0.000 1.000
5 1.000 1.000
6 1.750 1.300
7 2.700 0.800
8 2.300 1.700
\end{filecontents*}
\begin{filecontents*}{elementdata.dat}
1 1 2 5
2 5 4 1
3 2 3 6
4 6 5 2
5 3 7 8 6
\end{filecontents*}
\readmesh{nodedata.dat}{elementdata.dat}
手动输入的方法如下:
\def\nodedata{1 0.000 0.000,2 1.000 0.000,3 2.000 0.500,
4 0.000 1.000,5 1.000 1.000,6 1.750 1.300,7 2.700 0.800,8 2.300 1.700}
\def\elementdata{1 1 2 5,2 5 4 1,3 2 3 6,4 6 5 2,5 3 7 8 6}
\readmesh{}{}
编辑以允许多种外观\labelnode
选择
已编辑,允许节点和元素使用 LaTeX 样式标签,而不仅仅是数字。
妇女权利委员会:
\documentclass{article}
\usepackage{tikz,listofitems,readarray,filecontents}
\usetikzlibrary{calc}
\begin{filecontents*}{nodedata.dat}
1 0.000 0.000
2 1.000 0.000
3 2.000 0.500
4 0.000 1.000
5 1.000 1.000
6 1.750 1.300
7 2.700 0.800
n_8 2.300 1.700
\end{filecontents*}
\begin{filecontents*}{elementdata.dat}
E_1 1 2 5
2 5 4 1
3 2 3 6
4 6 5 2
5 3 7 n_8 6
\end{filecontents*}
\newcommand\coord[2][]{%
\edef\comparenode{#2}%
\foreachitem\zzz\in\noddat[]{%
\edef\testnode{\noddat[\zzzcnt,1]}%
\ifx\testnode\comparenode
\xaddtomacro\tmp{(\noddat[\zzzcnt,2]#1,\noddat[\zzzcnt,3]#1)}\fi
}%
}
\makeatletter\let\addtomacro\g@addto@macro\makeatother
\newcommand\xaddtomacro[2]{%
\edef\xtmp{#2}%
\expandafter\addtomacro\expandafter#1\expandafter{\xtmp}%
}
\newcommand\drawmesh[1][\draw]{%
\def\tmp{}%
\foreachitem\z\in\eledat[]{%
\addtomacro\tmp{#1}%
\foreachitem\zz\in\eledat[\zcnt]{%
\ifnum\zzcnt=1\relax\else
\ifnum\zzcnt<\listlen\eledat[\zcnt]\relax
\ifnum\zzcnt=2\relax\coord{\zz}\fi
\addtomacro\tmp{--}%
\coord{\eledat[\zcnt,\the\numexpr\zzcnt+1\relax]}%
\else
\addtomacro\tmp{--}%
\coord{\eledat[\zcnt,2]}%
\fi
\fi
}%
\addtomacro\tmp{;}%
}%
\tmp%
}
\newcommand\labelnodes[1][\node at]{%
\foreachitem\z\in\noddat[]{%
#1 (\noddat[\zcnt,2],\noddat[\zcnt,3]){%
%% ALTERNATIVE 1
% \textcolor{red}{$\noddat[\zcnt,1]$}};
%% ALTERNATIVE 2
\fboxsep=0pt\relax
\colorbox{white}{\color{red}$\noddat[\zcnt,1]$}};
%%
}%
}
\newcommand\labelelements[1][\node at]{%
\foreachitem\z\in\eledat[]{%
\def\tmp{#1 }%
\addtomacro\tmp{($}
\foreachitem\zz\in\eledat[\zcnt]{%
\ifnum\zzcnt=1\relax\else
\ifnum\zzcnt=2\relax\else\addtomacro\tmp{ + }\fi%
\coord[{/\the\numexpr\listlen\eledat[\zcnt]-1\relax}]{%
\eledat[\zcnt,\zzcnt]}%
\fi
}%
\addtomacro\tmp{$)}%
\xaddtomacro\tmp{{\noexpand\textcolor{blue!70!green}{$\eledat[\zcnt,1]$}};}%
\tmp
}%
}
\newcommand\readmesh[2]{%
\ignoreemptyitems%
\readarraysepchar{,}%
\ifx\relax#1\relax\else\readdef{#1}\nodedata\fi
\ifx\relax#2\relax\else\readdef{#2}\elementdata\fi
\setsepchar{,/ }%
\readlist*\noddat{\nodedata}%
\readlist*\eledat{\elementdata}%
}
\begin{document}
%% FILE INPUT
\readmesh{nodedata.dat}{elementdata.dat}
%% OR MANUAL INPUT
%\def\nodedata{1 0.000 0.000,2 1.000 0.000,3 2.000 0.500,
%4 0.000 1.000,5 1.000 1.000,6 1.750 1.300,7 2.700 0.800,n_8 2.300 1.700}
%\def\elementdata{E_1 1 2 5,2 5 4 1,3 2 3 6,4 6 5 2,5 3 7 n_8 6}
%\readmesh{}{}
Selected data extracts: \eledat[3,3], \noddat[3,3]
Segment list in terms of node numbers:\\
\foreachitem\z\in\eledat[]{%
Element $\eledat[\zcnt,1]$:
\foreachitem\zz\in\eledat[\zcnt]{%
\ifnum\zzcnt=1\relax\else
\ifnum\zzcnt<\listlen\eledat[\zcnt]\relax
$\zz$--$\eledat[\zcnt,\the\numexpr\zzcnt+1\relax]$,
\else
$\zz$--$\eledat[\zcnt,2]$
\fi
\fi
}%
\\
}
Segment list in terms of node coordinates:\\
\drawmesh[draw]
\begin{figure}[ht]
\centering
\begin{tikzpicture}[scale=1.5]
\drawmesh
\labelnodes
\labelelements
\end{tikzpicture}
\caption{A finite element mesh}
\end{figure}
\end{document}
如果不包含所有诊断内容,并选择手动输入文件作为输入模式,代码会更加精简
\documentclass{article}
\usepackage{tikz,listofitems,readarray}
\usetikzlibrary{calc}
\newcommand\coord[2][]{%
\edef\comparenode{#2}%
\foreachitem\zzz\in\noddat[]{%
\edef\testnode{\noddat[\zzzcnt,1]}%
\ifx\testnode\comparenode
\xaddtomacro\tmp{(\noddat[\zzzcnt,2]#1,\noddat[\zzzcnt,3]#1)}\fi
}%
}
\makeatletter\let\addtomacro\g@addto@macro\makeatother
\newcommand\xaddtomacro[2]{%
\edef\xtmp{#2}%
\expandafter\addtomacro\expandafter#1\expandafter{\xtmp}%
}
\newcommand\drawmesh[1][\draw]{%
\def\tmp{}%
\foreachitem\z\in\eledat[]{%
\addtomacro\tmp{#1}%
\foreachitem\zz\in\eledat[\zcnt]{%
\ifnum\zzcnt=1\relax\else
\ifnum\zzcnt<\listlen\eledat[\zcnt]\relax
\ifnum\zzcnt=2\relax\coord{\zz}\fi
\addtomacro\tmp{--}%
\coord{\eledat[\zcnt,\the\numexpr\zzcnt+1\relax]}%
\else
\addtomacro\tmp{--}%
\coord{\eledat[\zcnt,2]}%
\fi
\fi
}%
\addtomacro\tmp{;}%
}%
\tmp%
}
\newcommand\labelnodes[1][\node at]{%
\foreachitem\z\in\noddat[]{%
#1 (\noddat[\zcnt,2],\noddat[\zcnt,3]){%
\fboxsep=0pt\relax
\colorbox{white}{\color{red}$\noddat[\zcnt,1]$}};
}%
}
\newcommand\labelelements[1][\node at]{%
\foreachitem\z\in\eledat[]{%
\def\tmp{#1 }%
\addtomacro\tmp{($}
\foreachitem\zz\in\eledat[\zcnt]{%
\ifnum\zzcnt=1\relax\else
\ifnum\zzcnt=2\relax\else\addtomacro\tmp{ + }\fi%
\coord[{/\the\numexpr\listlen\eledat[\zcnt]-1\relax}]{%
\eledat[\zcnt,\zzcnt]}%
\fi
}%
\addtomacro\tmp{$)}%
\xaddtomacro\tmp{{\noexpand\textcolor{blue!70!green}{$\eledat[\zcnt,1]$}};}%
\tmp
}%
}
\newcommand\readmesh[2]{%
\ignoreemptyitems%
\readarraysepchar{,}%
\ifx\relax#1\relax\else\readdef{#1}\nodedata\fi
\ifx\relax#2\relax\else\readdef{#2}\elementdata\fi
\setsepchar{,/ }%
\readlist*\noddat{\nodedata}%
\readlist*\eledat{\elementdata}%
}
\begin{document}
\def\nodedata{1 0.000 0.000,2 1.000 0.000,3 2.000 0.500,
4 0.000 1.000,5 1.000 1.000,6 1.750 1.300,7 2.700 0.800,n_8 2.300 1.700}
\def\elementdata{E_1 1 2 5,2 5 4 1,3 2 3 6,4 6 5 2,5 3 7 n_8 6}
\readmesh{}{}
\begin{figure}[ht]
\centering
\begin{tikzpicture}[scale=1.5]
\drawmesh
\labelnodes
\labelelements
\end{tikzpicture}
\caption{A finite element mesh}
\end{figure}
\end{document}