该问题与我之前的问题解释的相同:如何填充圆圈外面的区域?。唯一的区别是现在我需要填充绿色区域三维空间,即两个球体外部、立方体内部的区域。
目前我有:
\documentclass[tikz,margin=15pt]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.10}
\usetikzlibrary{pgfplots.fillbetween,backgrounds}
\begin{tikzpicture}
\begin{axis}[
width=8cm, height=8cm,
xmin=-0.2, xmax=1.2, ymin=-0.2, ymax=1.2, zmin=-0.2, zmax=1.2,
every tick label/.append style={font=\tiny},
xlabel = {$ x_1 $}, ylabel = {$ x_2 $}, zlabel = {$ x_3 $},
xtick={0,0.167,0.33,0.5,0.66,0.833,1.0},
xticklabels={$0$,$\frac{1}{6}$,$\frac{1}{3}$,$\frac{1}{2}$,$\frac{2}{3}$,$\frac{5}{6}$,$1$},
ytick={0,0.167,0.33,0.5,0.66,0.833,1.0},
yticklabels={$0$,$\frac{1}{6}$,$\frac{1}{3}$,$\frac{1}{2}$,$\frac{2}{3}$,$\frac{5}{6}$,$1$},
ztick={0,0.167,0.33,0.5,0.66,0.833,1.0},
zticklabels={$0$,$\frac{1}{6}$,$\frac{1}{3}$,$\frac{1}{2}$,$\frac{2}{3}$,$\frac{5}{6}$,$1$},
enlargelimits=0.05,
view={15}{10},
]
% Draw hyper-rectangle (cube)
\addplot3[style=very thick,mark=none,color=blue] coordinates {
(0,0,0) (1,0,0) (1,1,0)
(0,0,1) (1,0,1) (1,1,1) (0,1,1) (0,0,1)
(0,0,0) (0,0,1)
(1,0,0) (1,0,1)
(1,1,0) (1,1,1)
};
% Draw imaginary edges
\addplot3[style=dashed,style=thick,mark=none,color=blue] coordinates {
(1,1,0) (0,1,0) (0,0,0)
(0,1,0) (0,1,1)
};
% Draw sampling points
\addplot3[only marks,mark=*,nodes near coords,point meta=explicit symbolic, color=blue, opacity=0.75,font=\scriptsize] coordinates {
(1/3,1/3,1/3) [(1)]
(2/3,2/3,2/3) [(2)]
};
% Draw the first sphere, based on:
% https://tex.stackexchange.com/questions/124916/draw-sphere-pgfplots-with-axis-at-center
\addplot3[%
opacity = 0.3,
mesh,
red,
z buffer = sort,
samples = 21,
variable = \u,
variable y = \v,
domain = 0:180,
y domain = 0:360,
] ({0.33 + 0.58*cos(u)*sin(v)}, {0.33 + 0.58*sin(u)*sin(v)}, {0.33 + 0.58*cos(v)});
% Draw the second sphere
\addplot3[%
opacity = 0.3,
mesh,
red,
z buffer = sort,
samples = 21,
variable = \u,
variable y = \v,
domain = 0:180,
y domain = 0:360,
] ({0.66 + 0.58*cos(u)*sin(v)}, {0.66 + 0.58*sin(u)*sin(v)}, {0.66 + 0.58*cos(v)});
% Draw diameter
\addplot3[color=black,very thick] coordinates { (1/3,1/3,1/3) (0,0,0) } node[pos=0.5, yshift=8pt, sloped] { $\delta$};
% TODO: Fill the area outside both spheres but inside the cube
\end{axis}
\end{tikzpicture}
\end{document}
我想知道是否有与@Alenanno 提出的类似的方法二维情况的解决方案。
答案1
使用的方法安德鲁·史黛西的spath3钛钾Z 库。我只画一个球体作为例子。
我们需要创建四条路径:球体和球体与立方体面之间的三条相交圆弧。然后计算所有相交点,并仔细观察顺序将它们焊接在一起(拆分后会有很多路径)。
像这样:
\documentclass[border=2mm,tikz]{standalone}
\usetikzlibrary{3d,intersections,perspective,spath3}
\tikzset
{% styles
xy/.style={canvas is xy plane at z=1},
xz/.style={canvas is xz plane at y=1},
yz/.style={canvas is yz plane at x=1},
sphere/.style={red,ball color=red,shading=ball,fill opacity=#1},
cube/.style 2 args={draw,fill=gray!#1,fill opacity=#2}
}
\begin{document}
\begin{tikzpicture}[line cap=round,line join=round,
3d view={125}{30},scale=2]
% radii
\pgfmathsetmacro\br{sqrt(1/3)} % sphere radius
\pgfmathsetmacro\lr{sqrt(\br*\br-1/9)} % intersection circles radius
% paths
\path[spath/save=S] % sphere
(2/3,2/3,2/3) circle [radius=\br cm];
\path[xy,spath/save=Ixy] % intersection xy plane
(1,1/3) arc (315:135:\lr);
\path[xz,spath/save=Ixz] % intersection xz plane
(1,1/3) arc (315:135:\lr);
\path[yz,spath/save=Iyz] % intersection yz plane
(1,1/3) arc (315:135:\lr);
\tikzset
{% spath3 operatios
spath/remove empty components={S},
spath/split at intersections={S}{Ixy},
spath/split at intersections={S}{Ixz},
spath/split at intersections={S}{Iyz},
spath/get components of={S}\SPcpts,
spath/get components of={Ixy}\XYcpts,
spath/get components of={Ixz}\XZcpts,
spath/get components of={Iyz}\YZcpts,
}
% axes
\draw[-latex](0,0,0) -- (2,0,0) node[below] {$x$};
\draw[-latex](0,0,0) -- (0,2,0) node[below] {$y$};
\draw[-latex](0,0,0) -- (0,0,2) node[above] {$z$};
% sphere, non-visible parts
\draw[sphere=0.8,%
spath/use= \getComponentOf\SPcpts{5} ,
spath/use={\getComponentOf\SPcpts{6} ,weld},
spath/use={\getComponentOf\YZcpts{9} ,weld},
spath/use={\getComponentOf\XYcpts{1} ,weld},
];
\draw[sphere=0.8,%
spath/use= \getComponentOf\SPcpts{18} ,
spath/use={\getComponentOf\XYcpts{6} ,weld},
spath/use={\getComponentOf\XZcpts{7} ,weld,reverse},
];
\draw[sphere=0.8,%
spath/use= \getComponentOf\SPcpts{13} ,
spath/use={\getComponentOf\XZcpts{1} ,weld,reverse},
spath/use={\getComponentOf\YZcpts{1} ,weld},
];
% center
\fill[red] (2/3,2/3,2/3) circle (0.15mm);
% cube
\draw[cube={50}{0.8},xy] (1/3,1) arc (135:315:\lr) |- (0,0) |- cycle;
\draw[cube={80}{0.8},xz] (1/3,1) arc (135:315:\lr) |- (0,0) |- cycle;
\draw[cube={65}{0.8},yz] (1/3,1) arc (135:315:\lr) |- (0,0) |- cycle;
\draw (1,1,1) -- (1/3,1,1);
\draw (1,1,1) -- (1,1/3,1);
\draw (1,1,1) -- (1,1,1/3);
% sphere, visible part
\draw[sphere=0.8,%
spath/use= \getComponentOf\SPcpts{1} ,
spath/use={\getComponentOf\SPcpts{2} ,weld},
spath/use={\getComponentOf\SPcpts{3} ,weld},
spath/use={\getComponentOf\SPcpts{4} ,weld},
spath/use={\getComponentOf\SPcpts{5} ,weld},
spath/use={\getComponentOf\XYcpts{1} ,weld,reverse},
spath/use={\getComponentOf\YZcpts{9} ,weld,reverse},
spath/use={\getComponentOf\SPcpts{7} ,weld},
spath/use={\getComponentOf\SPcpts{8} ,weld},
spath/use={\getComponentOf\SPcpts{9} ,weld},
spath/use={\getComponentOf\SPcpts{10},weld},
spath/use={\getComponentOf\SPcpts{11},weld},
spath/use={\getComponentOf\SPcpts{12},weld},
spath/use={\getComponentOf\YZcpts{1} ,weld,reverse},
spath/use={\getComponentOf\XZcpts{1} ,weld},
spath/use={\getComponentOf\SPcpts{14},weld},
spath/use={\getComponentOf\SPcpts{15},weld},
spath/use={\getComponentOf\SPcpts{16},weld},
spath/use={\getComponentOf\SPcpts{17},weld},
spath/use={\getComponentOf\XZcpts{7} ,weld},
spath/use={\getComponentOf\XYcpts{6} ,weld,reverse},
];
% tangent point
\fill (1,1,1) circle (0.15mm);
\end{tikzpicture}
\end{document}
输出为:
或者,将所有表面的不透明度全部改为 1: