如题,请问如何使用TiKZ绘制这样的图片呀,我试了问GPT-4o,但是给出的结果好像不还合理。
GPT4给出的结果如下:
\documentclass{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\begin{document}
\newcommand{\crystalCell}[5]{ % #1: 晶胞类型, #2: 晶格参数, #3: 特殊晶格点, #4: x 偏移, #5: y 偏移
\begin{scope}[shift={(#4,#5)}]
\tdplotsetmaincoords{70}{110}
\begin{scope}[tdplot_main_coords]
% 晶格向量
\draw[red,thick,->] (0,0,0) -- (1,0,0) node[below] {$\vec{a}_1$};
\draw[red,thick,->] (0,0,0) -- (0,1,0) node[left] {$\vec{a}_2$};
\draw[red,thick,->] (0,0,0) -- (0,0,1) node[above] {$\vec{a}_3$};
% 晶胞
\draw (0,0,0) -- (1,0,0) -- (1,1,0) -- (0,1,0) -- cycle;
\draw (0,0,1) -- (1,0,1) -- (1,1,1) -- (0,1,1) -- cycle;
\draw (0,0,0) -- (0,0,1);
\draw (1,0,0) -- (1,0,1);
\draw (1,1,0) -- (1,1,1);
\draw (0,1,0) -- (0,1,1);
% 晶格点
\foreach \x in {0,1} {
\foreach \y in {0,1} {
\foreach \z in {0,1} {
\filldraw[blue] (\x,\y,\z) circle (2pt);
}
}
}
% 特殊晶格点
#3
% 晶胞参数
\node[above right] at (1,0,0) {#2};
% 晶胞类型
\node[font=\bfseries, below right] at (0,0,0) {#1};
\end{scope}
\end{scope}
}
\begin{tikzpicture}
% Triclinic
\crystalCell{Primitive}{}{}{0}{0}
% Monoclinic
\crystalCell{Primitive}{}{(1,0,1)}{3}{0}
\crystalCell{Base-centered}{}{(0.5,0.5,0)}{3}{-3}
% Orthorhombic
\crystalCell{Primitive}{}{}{6}{0}
\crystalCell{Base-centered}{}{(0.5,0.5,0)}{6}{-3}
% Tetragonal
\crystalCell{Primitive}{}{}{9}{0}
\crystalCell{Base-centered}{}{(0.5,0.5,0)}{9}{-3}
% Cubic
\crystalCell{Primitive}{}{}{0}{-6}
% Trigonal
\crystalCell{Primitive}{
\draw (0,0,0) -- (1,1,0);
\draw (0,0,1) -- (1,1,1);
\filldraw[blue] (0.5,0.5,0) circle (2pt);
\filldraw[blue] (0.5,0.5,1) circle (2pt);
}{(0.5,0.5,0)}{3}{-6}
% Hexagonal
\crystalCell{Primitive}{
\draw[gray!50] (0.5,0,0) -- (1.5,0,0) -- (1.5,0,1) -- (0.5,0,1) -- cycle;
\draw[gray!50] (0.5,0,0) -- (0,0.866,0) -- (1,0.866,0) -- (1.5,0,0);
\draw[gray!50] (0.5,0,1) -- (0,0.866,1) -- (1,0.866,1) -- (1.5,0,1);
\filldraw[blue!50] (0.5,0,0) circle (2pt);
\filldraw[blue!50] (1.5,0,0) circle (2pt);
\filldraw[blue!50] (1.5,0,1) circle (2pt);
\filldraw[blue!50] (0.5,0,1) circle (2pt);
\filldraw[blue!50] (0,0.866,0) circle (2pt);
\filldraw[blue!50] (1,0.866,0) circle (2pt);
\filldraw[blue!50] (0,0.866,1) circle (2pt);
\filldraw[blue!50] (1,0.866,1) circle (2pt);
}{}{6}{-6}
% 添加晶系名称和参数
\foreach \x/\name/\params in {
0/Triclinic/{
$|\vec{a}_1| \neq |\vec{a}_2| \neq |\vec{a}_3|$,
$\alpha \neq \beta \neq \gamma$
},
3/Monoclinic/{
$|\vec{a}_1| \neq |\vec{a}_2| \neq |\vec{a}_3|$,
$\alpha \neq 90^\circ = \beta = \gamma$
},
6/Orthorhombic/{
$|\vec{a}_1| \neq |\vec{a}_2| \neq |\vec{a}_3|$,
$\alpha = \beta = \gamma = 90^\circ$
},
9/Tetragonal/{
$|\vec{a}_1| = |\vec{a}_2| \neq |\vec{a}_3|$,
$\alpha = \beta = \gamma = 90^\circ$
},
0/Cubic/{
$|\vec{a}_1| = |\vec{a}_2| = |\vec{a}_3|$,
$\alpha = \beta = \gamma = 90^\circ$
},
3/Trigonal/{
$|\vec{a}_1| = |\vec{a}_2| = |\vec{a}_3|$,
$\alpha = \beta = \gamma < 120^\circ \neq 90^\circ$
},
6/Hexagonal/{
$|\vec{a}_1| = |\vec{a}_2| \neq |\vec{a}_3|$,
$\alpha = \beta = 90^\circ, \gamma = 120^\circ$
}
} {
\node[font=\bfseries, above] at (\x+1.5,0.5) {\name};
\node[below, align=center] at (\x+1.5,0) {\params};
}
\end{tikzpicture}
\end{document}但是需要将以下部分注释才能正常编译:
% Trigonal
\crystalCell{Primitive}{
\draw (0,0,0) -- (1,1,0);
\draw (0,0,1) -- (1,1,1);
\filldraw[blue] (0.5,0.5,0) circle (2pt);
\filldraw[blue] (0.5,0.5,1) circle (2pt);
}{(0.5,0.5,0)}{3}{-6}
% Hexagonal
\crystalCell{Primitive}{
\draw[gray!50] (0.5,0,0) -- (1.5,0,0) -- (1.5,0,1) -- (0.5,0,1) -- cycle;
\draw[gray!50] (0.5,0,0) -- (0,0.866,0) -- (1,0.866,0) -- (1.5,0,0);
\draw[gray!50] (0.5,0,1) -- (0,0.866,1) -- (1,0.866,1) -- (1.5,0,1);
\filldraw[blue!50] (0.5,0,0) circle (2pt);
\filldraw[blue!50] (1.5,0,0) circle (2pt);
\filldraw[blue!50] (1.5,0,1) circle (2pt);
\filldraw[blue!50] (0.5,0,1) circle (2pt);
\filldraw[blue!50] (0,0.866,0) circle (2pt);
\filldraw[blue!50] (1,0.866,0) circle (2pt);
\filldraw[blue!50] (0,0.866,1) circle (2pt);
\filldraw[blue!50] (1,0.866,1) circle (2pt);
}{}{6}{-6}得到的结果如下:
希望各位大佬指点
Here below is the proposal of luadraw package:
\documentclass[multi=luadraw]{standalone}
\usepackage[svgnames]{xcolor}
\usepackage[3d]{luadraw}
\usepackage{fourier}
\begin{document}
\begin{luadraw}{name=AAA}
local g = graph3d:new{
window3d={-2,5,-2,5,-1,8},
window={-1.5,3,-0.5,5},
viewdir={-120,75}, size={5,5}
}
g:Linewidth(8)
local v1, v2, v3 = M(3, 0, 0), M(0, 2, 0), M(0, 0, 4)
local p = parallelep(Origin, v1, v2, v3)
local ctr = (v1 + v2 + v3) / 2
for _, pt in ipairs(p.vertices) do
g:Dpolyline3d({ctr, pt}, "dashed")
end
g:Dpoly(p, {mode=mWireframe, hiddenstyle="solid"})
g:Dpolyline3d(
{{Origin, v1},{Origin, v2},{Origin, v3}}, "-latex, red, line width=1.2pt"
)
g:Dballdots3d(p.vertices, "blue", 0.6)
g:Dballdots3d(ctr, "blue", 0.6)
g:Dlabel3d(
"$\\vec{a}_1$", v1, {pos="S", node_options="red"},
"$\\vec{a}_2$", v2, {pos="W"},
"$\\vec{a}_3$", v3, {pos="N"}
)
g:Show()
\end{luadraw}
\begin{luadraw}{name=BBB}
local g = graph3d:new{
window3d={-2,5,-2,5,-1,8},
window={-1.5,3,-0.5,6.5},
viewdir={-120,75}, size={5,5}
}
g:Linewidth(8)
local v1, v2, v3 = M(3, 0, 0), M(0, 2, 0), M(0, 0, 5.5)
local p = parallelep(Origin, v1, v2, v3)
local ctr = (v1 + v2 + v3) / 2
for _, pt in ipairs(p.vertices) do
g:Dpolyline3d({ctr, pt}, "dashed")
end
g:Dpoly(p, {mode=mWireframe, hiddenstyle="solid"})
g:Dpolyline3d(
{{Origin, v1},{Origin, v2},{Origin, v3}}, "-latex, red, line width=1.2pt"
)
g:Dballdots3d(p.vertices, "blue", 0.6)
g:Dballdots3d(ctr, "blue", 0.6)
g:Dlabel3d(
"$\\vec{a}_1$", v1, {pos="S", node_options="red"},
"$\\vec{a}_2$", v2, {pos="W"},
"$\\vec{a}_3$", v3, {pos="N"}
)
g:Show()
\end{luadraw}
\begin{luadraw}{name=CCC}
local g = graph3d:new{
window3d={-4,4,-4,4,-4,4},
window={-2.5,4,-1,5.5},
viewdir={-120,75}, size={5,5}
}
g:Linewidth(8)
local v1, v2, v3 = M(4, 0, 0), M(0, 4, 0), M(0, 0, 4)
local p = parallelep(Origin, v1, v2, v3)
local centers = {}
for idx, f in ipairs(getfacet(p)) do
local c = isobar3d(f)
table.insert(centers, c)
for _, vertex in ipairs(f) do
if idx % 2 == 0 then
g:Dpolyline3d({c, vertex}, "densely dotted,line width=0.6pt")
else
g:Dpolyline3d({c, vertex}, "dashed")
end
end
end
g:Dpoly(p, {mode=mWireframe, hiddenstyle="solid"})
g:Dpolyline3d(
{{Origin, v1},{Origin, v2},{Origin, v3}}, "-latex, red, line width=1.2pt"
)
g:Dballdots3d(p.vertices, "blue", 0.6)
g:Dballdots3d(centers, "blue", 0.6)
g:Dlabel3d(
"$\\vec{a}_1$", v1, {pos="S", node_options="red"},
"$\\vec{a}_2$", v2, {pos="W"},
"$\\vec{a}_3$", v3, {pos="N"}
)
g:Show()
\end{luadraw}
\begin{luadraw}{name=DDD}
local g = graph3d:new{
window3d={-6,6,-6,6,-6,6},
window={-4,4,-1,6},
viewdir={-50,75}, size={5,5}
}
local pi, cos, sin = math.pi, math.cos, math.sin
g:Linewidth(8)
local v1, v2, v3 = M(3, 0, 0), M(-3*cos(pi/3), 3*sin(pi/3), 0), M(0, 0, 5)
local cell1 = parallelep(Origin, v1, v2, v3)
local cell2 = rotate3d(cell1, 120, {Origin, vecK})
local cell3 = rotate3d(cell1, -120, {Origin, vecK})
local bg_opt = {mode=mWireframe, edgecolor="gray!50", hiddenstyle="dashed"}
g:Dpoly(cell2, bg_opt)
g:Dpoly(cell3, bg_opt)
g:Dpoly(cell1, {mode=mWireframe, edgewidth=10, hiddenstyle="solid"})
g:Dpolyline3d({{Origin, v1}, {Origin, v2}, {Origin, v3}}, "-latex, red, line width=1pt")
g:Dballdots3d(cell2.vertices, "blue!50")
g:Dballdots3d(cell3.vertices, "blue!50")
g:Dballdots3d(cell1.vertices, "blue")
g:Dlabel3d(
"$\\vec{a}_1$", v1, {pos="S", node_options="red"},
"$\\vec{a}_2$", v2, {pos="NE",dist=0},
"$\\vec{a}_3$", v3, {pos="W"}
)
g:Show()
\end{luadraw}
\end{document}
I don't think what matters here is how to arrange the image into the tabular environment(you could have better control with tabualrray package), thus, the code above just show how to plot them in an elegant appraoch, and I only randomly choose and post four in your whole figure.
Noted that LLM is not sophisticated enough if you have high-quality requirement if the image(TikZ are always used to produced extremely high-quality ones), also, you only show what GPT gives you, you pay too less endeavour on it, from a hacker's view, I don't think you are deserved to get high-quality answer, only provide ugly and less-tweaked code. Please, pay enough time to plot the figure, if you really need high-qualitied ones.