你能画一个带有尽可能多细节的 3D 圣诞礼物盒吗(领结、凸起的盖子/蝴蝶结、有图案的包装纸)?
当盒子打开时,通过动画展示盒子的打开状态,可以获得奖励积分(500 点赏金)。
MWE(由 HK 添加)
\documentclass[varwidth,tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\draw[fill=red] (0,0) rectangle (1,1);
\draw[fill=red] (1,0) -- ++(50:0.75cm) -- ++(90:1cm) -- (1,1) -- cycle;
\draw[fill=magenta] (0,1) -- ++(50:0.75cm) -- ++(0:1cm) -- (1,1) -- cycle;
\draw (0,0.8) -- (1,0.8) -- +(50:0.75cm);
\end{tikzpicture}
\end{document}
答案1
只是为了让事情进展顺利……
\documentclass[border=0.125cm]{standalone}
\usepackage{tikz}
\tikzset{gift box/.cd,
x/.store in=\gbx,
y/.store in=\gby,
z/.store in=\gbz,
x=0,y=0,z=0
}
\tikzdeclarecoordinatesystem{gift box}{%
\tikzset{x=(-20:1cm),y=(200:1cm),z=(90:1cm)}%
\tikzset{gift box/.cd, #1}%
\pgfpointxyz{\gbx*(.9+\gbz/20)}{\gby*(.9+\gbz/20)}{\gbz*(1+\gbx/10+\gby/10)}%
}
\tikzset{wrapping paper/.style={
bottom color=red!75!black, top color=red!50!black,
},
ribbon/.style={
bottom color=yellow!75!orange, top color=yellow!50!orange,
},
sheen/.style={
left color=black, right color=white, opacity=0.25
},
highlight/.style={
draw=white,
opacity=1/100,
line width=#1,
line cap=round
},
lowlight/.style={
draw=black,
opacity=1/80,
line width=#1,
line cap=round,
line join=round
}
}
\begin{document}
\begin{tikzpicture}
\foreach \l in {1,...,20}
\path [lowlight=\l/3]
(gift box cs:x=-1, y= 1, z=-1)
-- (gift box cs:x= 1, y= 1, z=-1)
-- (gift box cs:x= 1, y=-1, z=-1)
-- (gift box cs:x= 1, y=-1, z=-1)
-- cycle;
\path [wrapping paper]
(gift box cs:x=-1, y= 1, z=-1)
-- (gift box cs:x=-1, y= 1, z=1)
-- (gift box cs:x= 1, y= 1, z=1)
-- (gift box cs:x= 1, y=-1, z=1)
-- (gift box cs:x= 1, y=-1, z=-1)
-- (gift box cs:x= 1, y= 1, z=-1)
-- cycle;
\foreach \n/\o in {.25/1, .33/.5}
\path [ribbon, opacity=\o]
(gift box cs:x=1, y=-\n, z=-1)
-- (gift box cs:x=1, y=-\n, z=1)
-- (gift box cs:x=1, y= \n, z=1)
-- (gift box cs:x=1, y= \n, z=-1)
-- cycle
(gift box cs:x=-\n, y=1, z=-1)
-- (gift box cs:x=-\n, y=1, z=1)
-- (gift box cs:x= \n, y=1, z=1)
-- (gift box cs:x= \n, y=1, z=-1)
-- cycle;
\path [sheen]
(gift box cs:x=1,y=-1,z=-1)
-- (gift box cs:x=1,y=-1,z=1)
-- (gift box cs:x=1, y=1,z=1)
-- (gift box cs:x=1, y=1,z=-1)
-- cycle;
\path [sheen]
(gift box cs:x=-1,y=1,z=-1)
-- (gift box cs:x=-1,y=1,z=1)
-- (gift box cs:x=1, y=1,z=1)
-- (gift box cs:x=1, y=1,z=-1)
-- cycle;
\begin{scope}
\path [clip]
(gift box cs:x=-1, y= 1, z=-1)
-- (gift box cs:x=-1, y= 1, z= 1)
-- (gift box cs:x= 1, y= 1, z= 1)
-- (gift box cs:x= 1, y=-1, z= 1)
-- (gift box cs:x= 1, y=-1, z=-1)
-- (gift box cs:x= 1, y= 1, z=-1)
-- cycle;
\foreach \l in {1,...,10}{
\path [lowlight=\l/3]
(gift box cs:x=-1, y= 1, z=1)
-- (gift box cs:x=-1, y= 1, z=-1)
-- (gift box cs:x= 1, y= 1, z=-1)
-- (gift box cs:x= 1, y=-1, z=-1)
-- (gift box cs:x= 1, y=-1, z=1)
(gift box cs:x=1, y=1,z=-1)
-- (gift box cs:x=1, y=1,z= 1);
\path [lowlight=\l/2]
(gift box cs:x=-1.05, y= 1.05, z=1)
-- (gift box cs:x=-1.05, y= 1.05, z=.5)
-- (gift box cs:x= 1.05, y= 1.05, z=.5)
-- (gift box cs:x= 1.05, y=-1.05, z=.5)
-- (gift box cs:x= 1.05, y=-1.05, z=1);
}
\end{scope}
\path [wrapping paper]
(gift box cs:x=-1.05, y=-1.05, z=1)
-- (gift box cs:x=-1.05, y= 1.05, z=1)
-- (gift box cs:x=-1.05, y= 1.05, z=.5)
-- (gift box cs:x= 1.05, y= 1.05, z=.5)
-- (gift box cs:x= 1.05, y=-1.05, z=.5)
-- (gift box cs:x= 1.05, y=-1.05, z=1)
-- cycle;
\foreach \n/\o in {.33/.5, .25/1}{
\path [ribbon, opacity=\o]
(gift box cs:x= 1.05, y=-\n, z=0.5)
-- (gift box cs:x= 1.05, y=-\n, z=1)
-- (gift box cs:x=-1.05, y=-\n, z=1)
-- (gift box cs:x=-1.05, y= \n, z=1)
-- (gift box cs:x= 1.05, y= \n, z=1)
-- (gift box cs:x= 1.05, y= \n, z=.5)
-- cycle;
\path [ribbon, opacity=\o]
(gift box cs:y= 1.05, x=-\n, z=0.5)
-- (gift box cs:y= 1.05, x=-\n, z=1)
-- (gift box cs:y=-1.05, x=-\n, z=1)
-- (gift box cs:y=-1.05, x= \n, z=1)
-- (gift box cs:y= 1.05, x= \n, z=1)
-- (gift box cs:y= 1.05, x= \n, z=.5)
-- cycle;
}
\path [sheen]
(gift box cs:x=-1.05, y=1.05, z=1)
-- (gift box cs:x=-1.05, y=1.05, z=0.5)
-- (gift box cs:x= 1.05, y=1.05, z=0.5)
-- (gift box cs:x= 1.05, y=1.05, z=1)
-- cycle;
\path [sheen]
(gift box cs:x=1.05, y=-1.05, z=1)
-- (gift box cs:x=1.05, y=-1.05, z=0.5)
-- (gift box cs:x=1.05, y= 1.05, z=0.5)
-- (gift box cs:x=1.05, y= 1.05, z=1)
-- cycle;
\path [sheen]
(gift box cs:x=-1.05, y=-1.05, z=1)
-- (gift box cs:x=-1.05, y= 1.05, z=1)
-- (gift box cs:x= 1.05, y= 1.05, z=1)
-- (gift box cs:x= 1.05, y=-1.05, z=1)
-- cycle;
\begin{scope}
\path [clip]
(gift box cs:x=-1.05, y=-1.05, z=1)
-- (gift box cs:x=-1.05, y= 1.05, z=1)
-- (gift box cs:x=-1.05, y= 1.05, z=.5)
-- (gift box cs:x= 1.05, y= 1.05, z=.5)
-- (gift box cs:x= 1.05, y=-1.05, z=.5)
-- (gift box cs:x= 1.05, y=-1.05, z=1)
-- cycle;
\foreach \l in {1,...,10}{
\path [highlight=\l/3]
(gift box cs:x= 1.05, y= 1.05, z=1)
-- (gift box cs:x= 1.05, y=-1.05, z=1)
-- (gift box cs:x=-1.05, y=-1.05, z=1)
-- (gift box cs:x=-1.05, y= 1.05, z=1)
-- cycle
(gift box cs:x=1.05, y=1.05, z=1)
-- (gift box cs:x=1.05, y=1.05, z=0.5);
\path [lowlight=\l/3]
(gift box cs:x=-1.05, y= 1.05, z=1)
-- (gift box cs:x=-1.05, y= 1.05, z=.5)
-- (gift box cs:x= 1.05, y= 1.05, z=.5)
-- (gift box cs:x= 1.05, y=-1.05, z=.5)
-- (gift box cs:x= 1.05, y=-1.05, z=1);
}
\end{scope}
\end{tikzpicture}
\end{document}
而且,只需很少的额外工作:
不幸的是,这个礼盒是空的。满脸悲伤。
(除非它包含一些尚看不见的小东西)。
gif
包装似乎具有的(相当令人愉悦的)“纹理”是减小尺寸和优化上传色彩空间的结果。
代码(编译需要一些时间)如下所示。pdf
然后处理结果以gimp
生成上面的图像:
\documentclass[tikz,border=0.125cm]{standalone}
\tikzset{gift box/.cd,
x/.store in=\gbx,
y/.store in=\gby,
z/.store in=\gbz,
rotate around z axis/.store in=\gbzaxisrotate,
x=0,y=0,z=0,
rotate around z axis=0
}
\tikzdeclarecoordinatesystem{gift box}{%
\tikzset{x=(-20:1cm),y=(200:1cm),z=(90:1cm)}%
\tikzset{gift box/.cd, #1}%
\pgfmathsin{\gbzaxisrotate}\let\gbsin=\pgfmathresult%
\pgfmathcos{\gbzaxisrotate}\let\gbcos=\pgfmathresult%
\pgfmathparse{cos(\gbzaxisrotate)*(\gbx)-sin(\gbzaxisrotate)*(\gby)}\let\gbxa=\pgfmathresult%
\pgfmathparse{sin(\gbzaxisrotate)*(\gbx)+cos(\gbzaxisrotate)*(\gby)}\let\gbya=\pgfmathresult%
\pgfpointxyz{\gbxa*(.9+(\gbz)/20)}{\gbya*(.9+(\gbz)/20)}{(\gbz)*(1+\gbxa/10+\gbya/10)}%
}
\tikzset{wrapping paper/.style={
bottom color=red!75!black, top color=red!50!black,
},
ribbon/.style={
bottom color=yellow!75!orange, top color=yellow!50!orange,
},
sheen/.style={
left color=black, right color=white, opacity=0.25
},
sheen inside/.style={
left color=black, right color=black!50, opacity=0.25
},
highlight/.style={
draw=white,
opacity=1/100,
line width=#1,
line cap=round
},
lowlight/.style={
draw=black,
opacity=1/80,
line width=#1,
line cap=round,
line join=round
}
}
\begin{document}
\foreach \i [evaluate={\zangle=-45+mod(\i,18)*5; \lidz=1.25+min(\i,18)*.1;}] in {0,...,35}{
\begin{tikzpicture}[gift box/rotate around z axis=\zangle]
\useasboundingbox [gift box/rotate around z axis=0]
(gift box cs:x= 1, y= 1, z=-1)
-- (gift box cs:x=-1, y= 1, z=-1)
-- (gift box cs:x=-1, y= 1, z=3)
-- (gift box cs:x=-1, y=-1, z=3)
-- (gift box cs:x= 1, y=-1, z=3)
-- (gift box cs:x= 1, y=-1, z=-1)
-- cycle;
\foreach \l in {1,...,20}
\path [lowlight=\l/3]
(gift box cs:x=-1, y= 1, z=-1)
-- (gift box cs:x= 1, y= 1, z=-1)
-- (gift box cs:x= 1, y=-1, z=-1)
-- (gift box cs:x= 1, y=-1, z=-1)
-- cycle;
\path [wrapping paper]
(gift box cs:x= 1, y= 1, z=-1)
-- (gift box cs:x=-1, y= 1, z=-1)
-- (gift box cs:x=-1, y= 1, z=1)
-- (gift box cs:x=-1, y=-1, z=1)
-- (gift box cs:x= 1, y=-1, z=1)
-- (gift box cs:x= 1, y=-1, z=-1)
-- cycle;
\path [sheen inside]
(gift box cs:x= 1, y=-1, z=-1)
-- (gift box cs:x= 1, y=-1, z=1)
-- (gift box cs:x=-1, y=-1, z=1)
-- (gift box cs:x=-1, y=-1, z=-1)
-- cycle;
\path [sheen inside]
(gift box cs:x=-1, y= 1, z=-1)
-- (gift box cs:x=-1, y= 1, z=1)
-- (gift box cs:x=-1, y=-1, z=1)
-- (gift box cs:x=-1, y=-1, z=-1)
-- cycle;
\begin{scope}
\path [clip]
(gift box cs:x= 1, y= 1, z=-1)
-- (gift box cs:x=-1, y= 1, z=-1)
-- (gift box cs:x=-1, y= 1, z=1)
-- (gift box cs:x=-1, y=-1, z=1)
-- (gift box cs:x= 1, y=-1, z=1)
-- (gift box cs:x= 1, y=-1, z=-1)
-- cycle;
\foreach \l in {1,...,20}
\path [lowlight=\l/3]
(gift box cs:x=-1, y= 1, z=1)
-- (gift box cs:x=-1, y=-1, z=1)
-- (gift box cs:x= 1, y=-1, z=1);
\end{scope}
\path [wrapping paper]
(gift box cs:x=-1, y= 1, z=-1)
-- (gift box cs:x=-1, y= 1, z=1)
-- (gift box cs:x= 1, y= 1, z=1)
-- (gift box cs:x= 1, y=-1, z=1)
-- (gift box cs:x= 1, y=-1, z=-1)
-- (gift box cs:x= 1, y= 1, z=-1)
-- cycle;
\foreach \n/\o in {.25/1, .33/.5}
\path [ribbon, opacity=\o]
(gift box cs:x=1, y=-\n, z=-1)
-- (gift box cs:x=1, y=-\n, z=1)
-- (gift box cs:x=1, y= \n, z=1)
-- (gift box cs:x=1, y= \n, z=-1)
-- cycle
(gift box cs:x=-\n, y=1, z=-1)
-- (gift box cs:x=-\n, y=1, z=1)
-- (gift box cs:x= \n, y=1, z=1)
-- (gift box cs:x= \n, y=1, z=-1)
-- cycle;
\path [sheen]
(gift box cs:x=1, y=-1, z=-1)
-- (gift box cs:x=1, y=-1, z=1)
-- (gift box cs:x=1, y= 1, z=1)
-- (gift box cs:x=1, y= 1, z=-1)
-- cycle;
\path [sheen]
(gift box cs:x=-1,y=1,z=-1)
-- (gift box cs:x=-1,y=1,z=1)
-- (gift box cs:x=1, y=1,z=1)
-- (gift box cs:x=1, y=1,z=-1)
-- cycle;
\begin{scope}
\path [clip]
(gift box cs:x=-1, y= 1, z=-1)
-- (gift box cs:x=-1, y= 1, z= 1)
-- (gift box cs:x= 1, y= 1, z= 1)
-- (gift box cs:x= 1, y=-1, z= 1)
-- (gift box cs:x= 1, y=-1, z=-1)
-- (gift box cs:x= 1, y= 1, z=-1)
-- cycle;
\foreach \l in {1,...,10}{
\path [lowlight=\l/3]
(gift box cs:x=-1, y= 1, z=1)
-- (gift box cs:x=-1, y= 1, z=-1)
-- (gift box cs:x= 1, y= 1, z=-1)
-- (gift box cs:x= 1, y=-1, z=-1)
-- (gift box cs:x= 1, y=-1, z=1)
(gift box cs:x=1, y=1,z=-1)
-- (gift box cs:x=1, y=1,z= 1);
\path [highlight=\l/3]
(gift box cs:x=-1, y= 1, z=1)
-- (gift box cs:x= 1, y= 1, z=1)
-- (gift box cs:x= 1, y=-1, z=1);
\path [lowlight=\l/2]
(gift box cs:x=-1.05, y= 1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y= 1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y=-1.05, z=\lidz-.5);
}
\end{scope}
\path [wrapping paper]
(gift box cs:x=-1.05, y=-1.05, z=\lidz)
-- (gift box cs:x=-1.05, y= 1.05, z=\lidz)
-- (gift box cs:x=-1.05, y= 1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y= 1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y=-1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y=-1.05, z=\lidz)
-- cycle;
\foreach \n/\o in {.33/.5, .25/1}{
\path [ribbon, opacity=\o]
(gift box cs:x= 1.05, y=-\n, z=\lidz-.5)
-- (gift box cs:x= 1.05, y=-\n, z=\lidz)
-- (gift box cs:x=-1.05, y=-\n, z=\lidz)
-- (gift box cs:x=-1.05, y= \n, z=\lidz)
-- (gift box cs:x= 1.05, y= \n, z=\lidz)
-- (gift box cs:x= 1.05, y= \n, z=\lidz-.5)
-- cycle;
\path [ribbon, opacity=\o]
(gift box cs:y= 1.05, x=-\n, z=\lidz-.5)
-- (gift box cs:y= 1.05, x=-\n, z=\lidz)
-- (gift box cs:y=-1.05, x=-\n, z=\lidz)
-- (gift box cs:y=-1.05, x= \n, z=\lidz)
-- (gift box cs:y= 1.05, x= \n, z=\lidz)
-- (gift box cs:y= 1.05, x= \n, z=\lidz-.5)
-- cycle;
}
\path [sheen]
(gift box cs:x=-1.05, y=1.05, z=\lidz)
-- (gift box cs:x=-1.05, y=1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y=1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y=1.05, z=\lidz)
-- cycle;
\path [sheen]
(gift box cs:x=1.05, y=-1.05, z=\lidz)
-- (gift box cs:x=1.05, y=-1.05, z=\lidz-.5)
-- (gift box cs:x=1.05, y= 1.05, z=\lidz-.5)
-- (gift box cs:x=1.05, y= 1.05, z=\lidz)
-- cycle;
\path [sheen]
(gift box cs:x=-1.05, y=-1.05, z=\lidz)
-- (gift box cs:x=-1.05, y= 1.05, z=\lidz)
-- (gift box cs:x= 1.05, y= 1.05, z=\lidz)
-- (gift box cs:x= 1.05, y=-1.05, z=\lidz)
-- cycle;
\begin{scope}
\path [clip]
(gift box cs:x=-1.05, y=-1.05, z=\lidz)
-- (gift box cs:x=-1.05, y= 1.05, z=\lidz)
-- (gift box cs:x=-1.05, y= 1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y= 1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y=-1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y=-1.05, z=\lidz)
-- cycle;
\foreach \l in {1,...,10}{
\path [highlight=\l/3]
(gift box cs:x= 1.05, y= 1.05, z=\lidz)
-- (gift box cs:x= 1.05, y=-1.05, z=\lidz)
-- (gift box cs:x=-1.05, y=-1.05, z=\lidz)
-- (gift box cs:x=-1.05, y= 1.05, z=\lidz)
-- cycle
(gift box cs:x=1.05, y=1.05, z=\lidz)
-- (gift box cs:x=1.05, y=1.05, z=\lidz-.5);
\path [lowlight=\l/3]
(gift box cs:x=-1.05, y= 1.05, z=\lidz)
-- (gift box cs:x=-1.05, y= 1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y= 1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y=-1.05, z=\lidz-.5)
-- (gift box cs:x= 1.05, y=-1.05, z=\lidz);
}
\end{scope}
\ifnum\i>17
\path [fill=white,opacity=(\i-17)/7]
(gift box cs:x=-1.1, y=-1.1, z=\lidz)
-- (gift box cs:x=-1.1, y= 1.1, z=\lidz)
-- (gift box cs:x=-1.1, y= 1.1, z=\lidz-.5)
-- (gift box cs:x= 1.1, y= 1.1, z=\lidz-.5)
-- (gift box cs:x= 1.1, y=-1.1, z=\lidz-.5)
-- (gift box cs:x= 1.1, y=-1.1, z=\lidz)
-- cycle;
\fi
\end{tikzpicture}
}
\end{document}
答案2
这与其他答案中的 3D 努力完全不同,但这里有一个数学努力元帖子。
它是半规则平铺以圣诞色彩绘制(来自metapost-colorbrewer),以及其双重平铺叠加在一起,看起来有点像金色丝带缠绕在方形包裹上。
圣诞节快乐!
\documentclass{standalone}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
input colorbrewer-cmyk
% a polygon of n sides on a given path
vardef poly expr n of p =
save x, y;
z0 = point 0 of p;
z1 = point 1 of p;
for i=2 upto n-1:
z[i] = z[i-2] rotatedabout(z[i-1], 180(2/n-1));
endfor
for i=0 upto n-1: z[i] -- endfor cycle
enddef;
vardef median(expr P) =
(origin for i=1 upto length P: + point i of P endfor) / length P
enddef;
beginfig(1);
path t[], s[];
s1 = poly 4 of (origin -- 42 dir 15);
t1 = poly 3 of subpath (2, 1) of s1;
t2 = poly 3 of subpath (3, 2) of s1;
t3 = poly 3 of subpath (2, 1) of t1;
t4 = poly 3 of subpath (2, 1) of t2;
s2 = poly 4 of subpath (2, 1) of t4;
picture unit;
unit = image(
fill s1 withcolor Oranges 8 5;
fill t1 withcolor Blues 8 4;
fill t4 withcolor Blues 8 3;
fill t3 withcolor Greens 8 4;
fill t2 withcolor Greens 8 3;
fill s2 withcolor Reds 8 5;
forsuffixes $=s1, t1, s2, t2, t3, t4:
pair m; m = median($);
for i=1 upto length $:
draw point i - 1/2 of $ -- m
withpen pencircle scaled 3/2 withcolor Spectral 3 2;
endfor
endfor
);
pair u, v;
u = point 2 of t2 - point 0 of s1;
v = point 2 of t3 - point 0 of s1;
for i=0 upto 6:
for j=0 upto 9:
draw unit shifted (i*u + j*v);
endfor
endfor
endfig;
\end{mplibcode}
\end{document}
您将需要使用它来编译它lualatex
。