完整代码

完整代码

我对在 3D 空间中表示的 2D 表面上的反向剪辑存在问题。

虽然反向剪切有效,但剪切部分并未投影在平面上。

在此处输入图片描述

以下是 MWE:

\documentclass{standalone}

\usepackage{amsmath, amssymb}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.pathmorphing}
\usepackage{tikz-3dplot}
\usetikzlibrary{arrows}
\usetikzlibrary{calc}
\usetikzlibrary{shadings}

\tikzset{>=latex}
\tdplotsetmaincoords{70}{120}

%Cavity
\def \xcav {5}
\def \zcav {5}
\def \ycav {2}

\tikzset{
    invclip/.style={clip,insert path={{[reset cm]
    (-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)
    }}}
    }

\begin{document}
    \begin{tikzpicture}
         [
         scale=1,
         tdplot_main_coords
         ]

    % Cavity
    \draw (-\xcav/2,-\ycav,-\zcav/2) --++ (\xcav,0,0) --++ (0,0,\zcav) --++ (-\xcav,0,0) -- cycle;
    \draw (-\xcav/2,-\ycav,-\zcav/2) --++ (0,\ycav,0) --++ (0,0,\zcav) --++ (0,-\ycav,0) -- cycle;
    \draw (-\xcav/2,-\ycav,-\zcav/2) --++ (0,\ycav,0) --++ (\xcav,0,0) --++ (0,-\ycav,0) -- cycle;

    \begin{scope}[canvas is xz plane at y=0]
        \begin{pgfinterruptboundingbox} % useful to avoid the rectangle in the bounding box
            \path[invclip](0,0) circle (0.25);
        \end{pgfinterruptboundingbox} 
       \shadedraw[clip] (-\xcav/2,-\zcav/2) --++ (\xcav,0) --++ (0,\zcav) --++ (-\xcav,0) -- cycle;
    \end{scope} 

    \draw (\xcav/2,-\ycav,-\zcav/2) --++ (0,\ycav,0) --++ (0,0,\zcav) --++ (0,-\ycav,0) -- cycle;
    \draw (-\xcav/2,-\ycav,+\zcav/2) --++ (0,\ycav,0) --++ (\xcav,0,0) --++ (0,-\ycav,0) -- cycle;

    \end{tikzpicture}
\end{document}

有什么想法吗 ?

答案1

一些含糊不清的话:

反转裁剪的显著解决方案是插入尽可能大的路径。目前限制与 TeX 的尺寸有关:大约 2 14 pt。但是,用户可能进行了一些转换,因此勉强有效的路径(例如(-16383pt,16383pt)rectangle(16383pt,16383pt))肯定会超出限制。

这就是它reset cm出现的原因:它会重置所有变换并保证有效路径仍然有效。然而,缺点也很明显。重置后,用户要么需要重建变换,要么在没有变换的情况下更加努力。

因此,解决剪切反转的一个好办法应该是限制 的范围reset cm,这就是为什么您会在 处看到双括号insert path={{。但它不起作用,可能是因为该值在宏之间传递了太多次,最终 TeX 会“剥去”所有括号。

解决这个问题的方法是添加更多括号。实验表明四个括号就足够了。所谓足够,我的意思是结果确实发生了变化:圆圈不会被投影的圆圈取代,而是消失。

事实证明,范围会影响绕数的计算。由于非零规则默认为clip,因此大路径内的所有内容都会被保留,使得裁剪毫无意义。

解决方案是添加预定义选项

clip even odd rule/.code={\pgfseteorule}, % Credit to Andrew Stacey`

insert path实验表明

invclip/.style={
    clip,insert path=
        [clip even odd rule]{
            [reset cm](-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)
        }
}

神奇的是,现在不再需要牙套了。

完整代码

\documentclass{standalone}

\usepackage{amsmath, amssymb}
\usepackage{graphicx}
\usepackage{tikz}
\usetikzlibrary{arrows,decorations.pathmorphing}
\usepackage{tikz-3dplot}
\usetikzlibrary{arrows}
\usetikzlibrary{calc}
\usetikzlibrary{shadings}

\tikzset{>=latex}
\tdplotsetmaincoords{70}{120}

%Cavity
\def \xcav {5}
\def \zcav {5}
\def \ycav {2}

\tikzset{
    clip even odd rule/.code={\pgfseteorule},
    invclip/.style={clip,insert path=[clip even odd rule]{[reset cm]
    (-16383.99999pt,-16383.99999pt) rectangle (16383.99999pt,16383.99999pt)
}}}

\begin{document}
    \begin{tikzpicture}
         [
         scale=1,
         tdplot_main_coords
         ]

    % Cavity
    \draw (-\xcav/2,-\ycav,-\zcav/2) --++ (\xcav,0,0) --++ (0,0,\zcav) --++ (-\xcav,0,0) -- cycle;
    \draw (-\xcav/2,-\ycav,-\zcav/2) --++ (0,\ycav,0) --++ (0,0,\zcav) --++ (0,-\ycav,0) -- cycle;
    \draw (-\xcav/2,-\ycav,-\zcav/2) --++ (0,\ycav,0) --++ (\xcav,0,0) --++ (0,-\ycav,0) -- cycle;

    \begin{scope}[canvas is xz plane at y=0]
        \begin{pgfinterruptboundingbox} % useful to avoid the rectangle in the bounding box
            \path[invclip](0,0) circle (0.25);
        \end{pgfinterruptboundingbox} 
       \shadedraw[clip] (-\xcav/2,-\zcav/2) --++ (\xcav,0) --++ (0,\zcav) --++ (-\xcav,0) -- cycle;
    \end{scope} 

    \draw (\xcav/2,-\ycav,-\zcav/2) --++ (0,\ycav,0) --++ (0,0,\zcav) --++ (0,-\ycav,0) -- cycle;
    \draw (-\xcav/2,-\ycav,+\zcav/2) --++ (0,\ycav,0) --++ (\xcav,0,0) --++ (0,-\ycav,0) -- cycle;

    \end{tikzpicture}
\end{document}

相关内容