在 TikZ 中绘制一个框 - 一条边比其他边更靠近观察者 - 具有透视

在 TikZ 中绘制一个框 - 一条边比其他边更靠近观察者 - 具有透视

我正在改编几年前提供的回复中的代码Jan Hlavacek。以下命令如何将透视图放入绘图中?

\coordinate (front_right) at ($(top_front)!5!(top_right)$);
\coordinate (front_left) at ($(top_front)!5!(top_left)$);
\coordinate (front_bottom) at ($(top_front)!15!(bottom_front)$);

我该如何标记三条边,使标签位于中点、0.1cm从边缘开始且倾斜?如果要绘制框的一条对角线,该如何进行类似标记?

\documentclass{amsart}

\usepackage{tikz}
\usetikzlibrary{calc,intersections}



\begin{document}


\begin{tikzpicture}

%\clip (-3,-3) rectangle (3,3);
\coordinate (top_front) at (0,0);
\coordinate (bottom_front) at (0,-3);
\coordinate (top_right) at (15:2.5cm);
\coordinate (top_left) at (165:2.5cm);

%You can change the perspective by playing with the 5, 5, 15:
\coordinate (front_right) at ($(top_front)!5!(top_right)$);
\coordinate (front_left) at ($(top_front)!5!(top_left)$);
\coordinate (front_bottom) at ($(top_front)!15!(bottom_front)$);

\path[name path=bottom_right_path] (bottom_front) -- (front_right);   
\path[name path=right_back_path] (top_right) -- (front_bottom);
\path[name path=back_left_path] (bottom_front) -- (front_left);
\path[name path=left_back_path] (top_left) -- (front_bottom);
\path[name path=top_right_path] (top_left) -- (front_right);
\path[name path=top_left_path] (top_right) -- (front_left);



\coordinate[name intersections={of=bottom_right_path and right_back_path, by=back_right}];
\coordinate[name intersections={of=back_left_path and left_back_path, by=back_left}];
\coordinate[name intersections={of=top_right_path and top_left_path, by=top_back}];

%\shade[right color=gray!10, left color=black!50, shading angle=105] (top_front) -- (bottom_front) -- (back_left) -- (top_left) -- cycle;
%\shade[left color=gray!10, right color=black!50, shading angle=75] (top_front) -- (bottom_front) -- (back_right) -- (top_right) -- cycle;

\begin{scope}
\clip (top_front) -- (top_right) -- (top_back) -- (top_left) -- cycle;
\shade[inner color = gray!5, outer color=black!50, shading=radial] (top_front) ellipse (3cm and 1.5cm);
\end{scope}

\draw (top_front) -- (bottom_front);
\draw (top_front) -- (top_right);
\draw (top_front) -- (top_left);
\draw (top_right) -- (back_right);
\draw (bottom_front) -- (back_right);
\draw (top_left) -- (back_left);
\draw (bottom_front) -- (back_left);
\draw (top_back) -- (top_right);
\draw (top_back) -- (top_left);



\end{tikzpicture}

\end{document}

答案1

为了从编写者的角度回答这个问题,我首先通过绘制尚未绘制的路径并命名这些点来可视化用于构建的不同点,我们得到了这个减少了 0.4 的数字scale=.4

全能型

%\clip (-3,-3) rectangle (3,3);
\coordinate[label={[blue]left:top-front}] (top_front) at (0,0);
\coordinate[label={[blue]left:bottom-front}] (bottom_front) at (0,-3);
\coordinate[label={[blue]right:top-right}] (top_right) at (15:2.5cm);
\coordinate[label={[blue]left:top-left}] (top_left) at (165:2.5cm);

%You can change the perspective by playing with the 5, 5, 15:
\coordinate[label={right:front-right}]  (front_right) at ($(top_front)!5!(top_right)$);
\coordinate [label={left:front-left}] (front_left) at ($(top_front)!5!(top_left)$);
\coordinate [label={below:front-bottom}](front_bottom) at ($(top_front)!15!(bottom_front)$);

使用正常尺寸scale=1\clip (-6,-4) rectangle (6,4);,我们得到以下结果:

正常尺寸和夹子

\begin{tikzpicture}[scale=1]

\clip (-6,-4) rectangle (6,4);
\coordinate[label={[blue]left:top-front}] (top_front) at (0,0);
\coordinate[label={[blue]left:bottom-front}] (bottom_front) at (0,-3);
\coordinate[label={[blue]right:top-right}] (top_right) at (15:2.5cm);
\coordinate[label={[blue]left:top-left}] (top_left) at (165:2.5cm);

要在边缘上放置标签,只需在构建边缘情况时放置一个节点,即可获得以下内容:

边缘上的标签

\draw (top_front) -- (bottom_front)node[midway,above,sloped]{label 1};
\draw (top_front) -- (top_right)node[midway,above,sloped]{label 2};
\draw (top_front) -- (top_left)node[midway,above,sloped]{label 3};
\draw (top_right) -- (back_right)node[midway,above,sloped]{label 4};
\draw (bottom_front) -- (back_right)node[midway,above,sloped]{label 5};
\draw (top_left) -- (back_left)node[midway,above,sloped]{label 6};
\draw (bottom_front) -- (back_left)node[midway,above,sloped]{label 7};
\draw (top_back) -- (top_right)node[midway,above,sloped]{label 8};
\draw (top_back) -- (top_left)node[midway,above,sloped]{label 9};

对于对角线,在其两个顶点之间创建一条路径即可。例如,对于对角线(top_left)--(bottom_front),我们可以不绘制此对角线并标记文本,如下所示:

对角线

\path (top_left)--(bottom_front)node[midway,above,sloped]{diagonal 1};

通过用虚线绘制对角线:

对角线绘制

我们这样写:

\path[draw,dashed] (top_left)--(bottom_front)node[midway,above,sloped]{diagonal 1};

或者也可以这样:

\draw[dashed] (top_left)--(bottom_front)node[midway,above,sloped]{diagonal 1};

完整代码:

\documentclass{amsart}

\usepackage{tikz}
\usetikzlibrary{calc,intersections}

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

\clip (-6,-4) rectangle (6,4);
\coordinate[label={[blue]left:top-front}] (top_front) at (0,0);
\coordinate[label={[blue]left:bottom-front}] (bottom_front) at (0,-3);
\coordinate[label={[blue]right:top-right}] (top_right) at (15:2.5cm);
\coordinate[label={[blue]left:top-left}] (top_left) at (165:2.5cm);

%You can change the perspective by playing with the 5, 5, 15:
\coordinate (front_right) at ($(top_front)!5!(top_right)$);
\coordinate (front_left) at ($(top_front)!5!(top_left)$);
\coordinate (front_bottom) at ($(top_front)!15!(bottom_front)$);

\path[name path=bottom_right_path] (bottom_front) -- (front_right);   
\path[name path=right_back_path] (top_right) -- (front_bottom);
\path[name path=back_left_path] (bottom_front) -- (front_left);
\path[name path=left_back_path] (top_left) -- (front_bottom);
\path[name path=top_right_path] (top_left) -- (front_right);
\path[name path=top_left_path] (top_right) -- (front_left);

\coordinate[name intersections={of=bottom_right_path and right_back_path, by=back_right}];
\coordinate[name intersections={of=back_left_path and left_back_path, by=back_left}];
\coordinate[name intersections={of=top_right_path and top_left_path, by=top_back}];

%\shade[right color=gray!10, left color=black!50, shading angle=105] (top_front) -- (bottom_front) -- (back_left) -- (top_left) -- cycle;
%\shade[left color=gray!10, right color=black!50, shading angle=75] (top_front) -- (bottom_front) -- (back_right) -- (top_right) -- cycle;

\begin{scope}
\clip (top_front) -- (top_right) -- (top_back) -- (top_left) -- cycle;
\shade[inner color = gray!5, outer color=black!50, shading=radial] (top_front) ellipse (3cm and 1.5cm);
\end{scope}

\draw (top_front) -- (bottom_front)node[midway,above,sloped]{label 1};
\draw (top_front) -- (top_right)node[midway,above,sloped]{label 2};
\draw (top_front) -- (top_left)node[midway,above,sloped]{label 3};
\draw (top_right) -- (back_right)node[midway,above,sloped]{label 4};
\draw (bottom_front) -- (back_right)node[midway,above,sloped]{label 5};
\draw (top_left) -- (back_left)node[midway,above,sloped]{label 6};
\draw (bottom_front) -- (back_left)node[midway,above,sloped]{label 7};
\draw (top_back) -- (top_right)node[midway,above,sloped]{label 8};
\draw (top_back) -- (top_left)node[midway,above,sloped]{label 9};

\path (top_left)--(bottom_front)node[midway,above,sloped]{diagonal 1};

\end{tikzpicture}

\end{document}

更新:创建立方体的底部_背面顶点。

% Creation of the bottom_back vertex of the cube.
% definition of 2 new paths
\path[name path=bottom_left_path] (back_left) -- (front_right);
\path[name path=back_right_path] (back_right) -- (front_left);
% vertex bottom_back definition
\coordinate[name intersections={of=bottom_left_path and back_right_path, by=bottom_back}];

%\node[red] at (back_right){back-right};
%\node[red] at (back_left){back-left};
%\node[red] at (top_back){top-back};
%\node[red] at (bottom_back){bottom-back};

% hidden sides
\draw[dashed] (back_left) -- (bottom_back);
\draw [dashed](back_right) -- (bottom_back);
\draw[dashed] (top_back) -- (bottom_back);

\draw[dashed,blue] (back_right) -- (top_left)node[midway, sloped, above]{diagonal};

我用虚线画出了隐藏的边。

顶点

您会注意到顶点(top_back)(top_front)(bottom_back)(bottom_back)对齐的,对角线(bottom_back)--(top_front)将不可见。

要做到这一点,你必须改变观点。我会把它留给你去做

所以我画了可见的对角线 (back_right) -- (top_left)

对角线

完整代码更新:

\documentclass{amsart}

\usepackage{tikz}
\usetikzlibrary{calc,intersections}

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

\clip (-6,-4) rectangle (6,4);
\coordinate[label={[blue]left:top-front}] 
(top_front) at (0,0);
\coordinate[label={[blue]left:bottom-front}] 
(bottom_front) at (0,-3);
\coordinate[label={[blue]right:top-right}] 
(top_right) at (15:2.5cm);
\coordinate[label={[blue]left:top-left}]
 (top_left) at (165:2.5cm);

%You can change the perspective by playing with the 5, 5, 15:
\coordinate%[label={right:front-right}]  
(front_right) at ($(top_front)!5!(top_right)$);
\coordinate% [label={left:front-left}] 
(front_left) at ($(top_front)!5!(top_left)$);
\coordinate %[label={below:front-bottom}]
(front_bottom) at ($(top_front)!15!(bottom_front)$);

\path[name path=bottom_right_path] (bottom_front) -- (front_right);   
\path[name path=right_back_path] (top_right) -- (front_bottom);
\path[name path=back_left_path] (bottom_front) -- (front_left);
\path[name path=left_back_path] (top_left) -- (front_bottom);
\path[name path=top_right_path] (top_left) -- (front_right);
\path[name path=top_left_path] (top_right) -- (front_left);

\coordinate[name intersections={of=bottom_right_path and right_back_path, by=back_right}];
\coordinate[name intersections={of=back_left_path and left_back_path, by=back_left}];
\coordinate[name intersections={of=top_right_path and top_left_path, by=top_back}];

%\shade[right color=gray!10, left color=black!50, shading angle=105] (top_front) -- (bottom_front) -- (back_left) -- (top_left) -- cycle;
%\shade[left color=gray!10, right color=black!50, shading angle=75] (top_front) -- (bottom_front) -- (back_right) -- (top_right) -- cycle;

\begin{scope}
\clip (top_front) -- (top_right) -- (top_back) -- (top_left) -- cycle;
%\shade[inner color = gray!5, outer color=black!50, shading=radial] (top_front) ellipse (3cm and 1.5cm);
\end{scope}

\draw (top_front) -- (bottom_front);
\draw (top_front) -- (top_right);
\draw (top_front) -- (top_left);
\draw (top_right) -- (back_right);
\draw (bottom_front) -- (back_right);
\draw (top_left) -- (back_left);
\draw (bottom_front) -- (back_left);
\draw (top_back) -- (top_right);
\draw (top_back) -- (top_left);


\path[draw,dashed,red] (top_left)--(bottom_front)node[midway,above,sloped]{diagonal 1};

% Creation of the bottom_back vertex of the cube.
% definition of 2 new paths
\path[name path=bottom_left_path] (back_left) -- (front_right);
\path[name path=back_right_path] (back_right) -- (front_left);
% vertex bottom_back definition
\coordinate[name intersections={of=bottom_left_path and back_right_path, by=bottom_back}];

% vertex names
\node[red] at (back_right){back-right};
\node[red] at (back_left){back-left};
\node[red] at (top_back){top-back};
\node[red] at (bottom_back){bottom-back};

% hidden sides
\draw[dashed] (back_left) -- (bottom_back);
\draw [dashed](back_right) -- (bottom_back);
\draw[dashed] (top_back) -- (bottom_back);

\draw[dashed,blue] (back_right) -- (top_left)node[midway, sloped, above]{diagonal 2};
\end{tikzpicture}

\end{document}

答案2

如果你能试着重新措辞一下你的问题,那就太好了。与此同时,我想提请你注意这个很好的答案它允许您绘制具有透视的 3d 对象。我所做的只是使用此答案的序言绘制透视立方体,并添加一些元素。这里不需要交叉点等。

\documentclass[tikz,border=3.14mm]{standalone}
\usepackage{tikz-3dplot}
\usepgfmodule{nonlineartransformations}
% Max magic https://tex.stackexchange.com/a/447120/121799
\makeatletter 
% the first part is not in use here
\def\tikz@scan@transform@one@point#1{%
  \tikz@scan@one@point\pgf@process#1%
  \pgf@pos@transform{\pgf@x}{\pgf@y}}
\tikzset{%
  grid source opposite corners/.code args={#1and#2}{%
   \pgfextract@process\tikz@transform@source@southwest{%
     \tikz@scan@transform@one@point{#1}}%
   \pgfextract@process\tikz@transform@source@northeast{%
     \tikz@scan@transform@one@point{#2}}%
  },
  grid target corners/.code args={#1--#2--#3--#4}{%
   \pgfextract@process\tikz@transform@target@southwest{%
     \tikz@scan@transform@one@point{#1}}%
   \pgfextract@process\tikz@transform@target@southeast{%
     \tikz@scan@transform@one@point{#2}}%
   \pgfextract@process\tikz@transform@target@northeast{%
     \tikz@scan@transform@one@point{#3}}%
   \pgfextract@process\tikz@transform@target@northwest{%
     \tikz@scan@transform@one@point{#4}}%
  }
}

\def\tikzgridtransform{%
  \pgfextract@process\tikz@current@point{}%
  \pgf@process{%
    \pgfpointdiff{\tikz@transform@source@southwest}%
      {\tikz@transform@source@northeast}%
  }%
  \pgf@xc=\pgf@x\pgf@yc=\pgf@y%
  \pgf@process{%
    \pgfpointdiff{\tikz@transform@source@southwest}{\tikz@current@point}%
  }%
  \pgfmathparse{\pgf@x/\pgf@xc}\let\tikz@tx=\pgfmathresult%
  \pgfmathparse{\pgf@y/\pgf@yc}\let\tikz@ty=\pgfmathresult%
  %
  \pgfpointlineattime{\tikz@ty}{%
    \pgfpointlineattime{\tikz@tx}{\tikz@transform@target@southwest}%
      {\tikz@transform@target@southeast}}{%
    \pgfpointlineattime{\tikz@tx}{\tikz@transform@target@northwest}%
      {\tikz@transform@target@northeast}}%
}

% Initialize H matrix for perspective view
\pgfmathsetmacro\H@tpp@aa{1}\pgfmathsetmacro\H@tpp@ab{0}\pgfmathsetmacro\H@tpp@ac{0}%\pgfmathsetmacro\H@tpp@ad{0}
\pgfmathsetmacro\H@tpp@ba{0}\pgfmathsetmacro\H@tpp@bb{1}\pgfmathsetmacro\H@tpp@bc{0}%\pgfmathsetmacro\H@tpp@bd{0}
\pgfmathsetmacro\H@tpp@ca{0}\pgfmathsetmacro\H@tpp@cb{0}\pgfmathsetmacro\H@tpp@cc{1}%\pgfmathsetmacro\H@tpp@cd{0}
\pgfmathsetmacro\H@tpp@da{0}\pgfmathsetmacro\H@tpp@db{0}\pgfmathsetmacro\H@tpp@dc{0}%\pgfmathsetmacro\H@tpp@dd{1}

%Initialize H matrix for main rotation
\pgfmathsetmacro\H@rot@aa{1}\pgfmathsetmacro\H@rot@ab{0}\pgfmathsetmacro\H@rot@ac{0}%\pgfmathsetmacro\H@rot@ad{0}
\pgfmathsetmacro\H@rot@ba{0}\pgfmathsetmacro\H@rot@bb{1}\pgfmathsetmacro\H@rot@bc{0}%\pgfmathsetmacro\H@rot@bd{0}
\pgfmathsetmacro\H@rot@ca{0}\pgfmathsetmacro\H@rot@cb{0}\pgfmathsetmacro\H@rot@cc{1}%\pgfmathsetmacro\H@rot@cd{0}
%\pgfmathsetmacro\H@rot@da{0}\pgfmathsetmacro\H@rot@db{0}\pgfmathsetmacro\H@rot@dc{0}\pgfmathsetmacro\H@rot@dd{1}

\pgfkeys{
    /three point perspective/.cd,
        p/.code args={(#1,#2,#3)}{
            \pgfmathparse{int(round(#1))}
            \ifnum\pgfmathresult=0\else
                \pgfmathsetmacro\H@tpp@ba{#2/#1}
                \pgfmathsetmacro\H@tpp@ca{#3/#1}
                \pgfmathsetmacro\H@tpp@da{ 1/#1}
                \coordinate (vp-p) at (#1,#2,#3);
            \fi
        },
        q/.code args={(#1,#2,#3)}{
            \pgfmathparse{int(round(#2))}
            \ifnum\pgfmathresult=0\else
                \pgfmathsetmacro\H@tpp@ab{#1/#2}
                \pgfmathsetmacro\H@tpp@cb{#3/#2}
                \pgfmathsetmacro\H@tpp@db{ 1/#2}
                \coordinate (vp-q) at (#1,#2,#3);
            \fi
        },
        r/.code args={(#1,#2,#3)}{
            \pgfmathparse{int(round(#3))}
            \ifnum\pgfmathresult=0\else
                \pgfmathsetmacro\H@tpp@ac{#1/#3}
                \pgfmathsetmacro\H@tpp@bc{#2/#3}
                \pgfmathsetmacro\H@tpp@dc{ 1/#3}
                \coordinate (vp-r) at (#1,#2,#3);
            \fi
        },
        coordinate/.code args={#1,#2,#3}{
           \pgfmathsetmacro\tpp@x{#1} %<- Max' fix
            \pgfmathsetmacro\tpp@y{#2}
            \pgfmathsetmacro\tpp@z{#3}
        },
}

\tikzset{
    view/.code 2 args={
        \pgfmathsetmacro\rot@main@theta{#1}
        \pgfmathsetmacro\rot@main@phi{#2}
        % Row 1
        \pgfmathsetmacro\H@rot@aa{cos(\rot@main@phi)}
        \pgfmathsetmacro\H@rot@ab{sin(\rot@main@phi)}
        \pgfmathsetmacro\H@rot@ac{0}
        % Row 2
        \pgfmathsetmacro\H@rot@ba{-cos(\rot@main@theta)*sin(\rot@main@phi)}
        \pgfmathsetmacro\H@rot@bb{cos(\rot@main@phi)*cos(\rot@main@theta)}
        \pgfmathsetmacro\H@rot@bc{sin(\rot@main@theta)}
        % Row 3
        \pgfmathsetmacro\H@m@ca{sin(\rot@main@phi)*sin(\rot@main@theta)}
        \pgfmathsetmacro\H@m@cb{-cos(\rot@main@phi)*sin(\rot@main@theta)}
        \pgfmathsetmacro\H@m@cc{cos(\rot@main@theta)}
        % Set vector values
        \pgfmathsetmacro\vec@x@x{\H@rot@aa}
        \pgfmathsetmacro\vec@y@x{\H@rot@ab}
        \pgfmathsetmacro\vec@z@x{\H@rot@ac}
        \pgfmathsetmacro\vec@x@y{\H@rot@ba}
        \pgfmathsetmacro\vec@y@y{\H@rot@bb}
        \pgfmathsetmacro\vec@z@y{\H@rot@bc}
        % Set pgf vectors
        \pgfsetxvec{\pgfpoint{\vec@x@x cm}{\vec@x@y cm}}
        \pgfsetyvec{\pgfpoint{\vec@y@x cm}{\vec@y@y cm}}
        \pgfsetzvec{\pgfpoint{\vec@z@x cm}{\vec@z@y cm}}
    },
}

\tikzset{
    perspective/.code={\pgfkeys{/three point perspective/.cd,#1}},
    perspective/.default={p={(15,0,0)},q={(0,15,0)},r={(0,0,50)}},
}

\tikzdeclarecoordinatesystem{three point perspective}{
    \pgfkeys{/three point perspective/.cd,coordinate={#1}}
    \pgfmathsetmacro\temp@p@w{\H@tpp@da*\tpp@x + \H@tpp@db*\tpp@y + \H@tpp@dc*\tpp@z + 1}
    \pgfmathsetmacro\temp@p@x{(\H@tpp@aa*\tpp@x + \H@tpp@ab*\tpp@y + \H@tpp@ac*\tpp@z)/\temp@p@w}
    \pgfmathsetmacro\temp@p@y{(\H@tpp@ba*\tpp@x + \H@tpp@bb*\tpp@y + \H@tpp@bc*\tpp@z)/\temp@p@w}
    \pgfmathsetmacro\temp@p@z{(\H@tpp@ca*\tpp@x + \H@tpp@cb*\tpp@y + \H@tpp@cc*\tpp@z)/\temp@p@w}
    \pgfpointxyz{\temp@p@x}{\temp@p@y}{\temp@p@z}
}
\tikzaliascoordinatesystem{tpp}{three point perspective}

\makeatother

\begin{document}
  \tdplotsetmaincoords{70}{-22.5}
  \begin{tikzpicture}[scale=6,font=\sffamily,
  view={\tdplotmaintheta}{\tdplotmainphi},
            perspective={
                p = {(4,0,1.5)},
                q = {(0,4,1.5)},
            }
  ]
  \begin{scope} % top face
   \draw[clip]   (tpp cs:0,0,1) coordinate (top_front)
  -- (tpp cs:1,0,1) coordinate (top_right)
   -- (tpp cs:1,1,1) coordinate (top_back)
   -- (tpp cs:0,1,1) coordinate (top_left) --
    cycle;
    \shade[inner color = gray!5, outer color=black!50, shading=radial] (top_front) ellipse (3cm and 1.5cm);
  \end{scope}
  % right face  
  \draw   (top_front) -- (top_right) -- (tpp cs:1,0,0) coordinate (bottom_right)
  -- (tpp cs:0,0,0)  coordinate (bottom_front) --   cycle;
  % top face  
  \draw   (top_front) -- (top_left) -- (tpp cs:0,1,0) coordinate (bottom_left)
  -- (bottom_front) --  cycle;
  % your midway coordinates with Max perspective coordinate system
  \coordinate (front_right) at (tpp cs:0.5,0,1);
  \coordinate (front_left) at (tpp cs:0,0.5,1);
  \coordinate (front_bottom) at (tpp cs:0,0,0.5);
  \path (0,0,0.5) -- (1,0,0.5) node[pos=0.1,sloped] {a label};
  \draw (top_left) -- (bottom_front) node[midway,sloped,above] {a sloped label};
  \end{tikzpicture}
\end{document}

在此处输入图片描述

原则,这个很好的答案还提供了以透视方式编写文本的工具。这就是你在这里问的吗?

相关内容