这个问题导致了 TikZ 中出现了一个新库:
perspective
(PGF 手册,第 63 章)
我有一个 3d 对象,inkscape
如下所示:
现在我尝试将文本放置在与浅蓝色区域相同的方向。但是,我想使用 插入文本,而latex
不是直接将其嵌入(因此,我使用中的选项pdf
保存它)。pdf+Latex
inkscape
但是当我尝试在 3d 区域插入文本时,我得到:
我怎样才能OMEAG
与浅蓝色区域平行对齐。
我无法附加它的 pdf,但是MWE
如下所示:
%&lualatex
% !TeX program = lualatex
\documentclass[11pt,a4paper]{article}
%\usepackage[latin1]{inputenc}
\usepackage{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{graphicx}
\usepackage{xcolor}
\usepackage{pgfplots}
\usepackage{pstricks} %for embedding pspicture.
\pgfplotsset{compat=newest}
\usepackage{tikz}
\begin{document}
\begin{figure}[h]
\centering{
\input{drawing4.pdf_tex}
\caption{Top view.}
\label{fig:aktomnpView}
}
\end{figure}
\end{document}
如下\input{drawing4.pdf_tex}
:
\begingroup%
\makeatletter%
\providecommand\color[2][]{%
\errmessage{(Inkscape) Color is used for the text in Inkscape, but the package 'color.sty' is not loaded}%
\renewcommand\color[2][]{}%
}%
\providecommand\transparent[1]{%
\errmessage{(Inkscape) Transparency is used (non-zero) for the text in Inkscape, but the package 'transparent.sty' is not loaded}%
\renewcommand\transparent[1]{}%
}%
\providecommand\rotatebox[2]{#2}%
\newcommand*\fsize{\dimexpr\f@size pt\relax}%
\newcommand*\lineheight[1]{\fontsize{\fsize}{#1\fsize}\selectfont}%
\ifx\svgwidth\undefined%
\setlength{\unitlength}{303.69978591bp}%
\ifx\svgscale\undefined%
\relax%
\else%
\setlength{\unitlength}{\unitlength * \real{\svgscale}}%
\fi%
\else%
\setlength{\unitlength}{\svgwidth}%
\fi%
\global\let\svgwidth\undefined%
\global\let\svgscale\undefined%
\makeatother%
\begin{picture}(1,1.35089637)%
\lineheight{1}%
\setlength\tabcolsep{0pt}%
\put(0,0){\includegraphics[width=\unitlength,page=1]{drawing4.pdf}}%
\put(0.54334545,0.71256022){\color[rgb]{0,0,0}\makebox(0,0)[lt]{\lineheight{1.25}\smash{\begin{tabular}[t]{l}OMEAG\end{tabular}}}}%
\end{picture}%
\endgroup%
答案1
编辑3
我很高兴地宣布,这个答案的部分代码现在作为perspective
库包含在 Tikz 包(v3.1.2)中。
编辑2
使用这个很棒的答案结合我的tpp
坐标系,我设法对块的侧面进行了非线性映射的近似。
或者没有帮助热线:
静止图像:
梅威瑟:
\documentclass[tikz]{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usepgfmodule{nonlineartransformations}
\usepackage{mathtools}
\makeatletter
\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}{
\def\tpp@x{#1}
\def\tpp@y{#2}
\def\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
\definecolor{mydarkbluishgray}{RGB}{134 134 191}
\definecolor{mylightbluishgray}{RGB}{215 215 255}
\begin{document}
\foreach \vp in {10,12.5,...,50}{
% \foreach \vp in {10}{
\begin{tikzpicture}[line join=round]
\clip (-12,0) rectangle (12,10);
\begin{scope}[
view={85}{-40},
perspective={
p = {(\vp,0,5.5)},
q = {(0,\vp,5.5)},
}
]
\fill[mydarkbluishgray] (tpp cs:0,0,0) -- (tpp cs:0,0,10) -- (tpp cs:0,5,10) -- (tpp cs:0,5,0) -- cycle;
\fill[mylightbluishgray] (tpp cs:0,0,0) -- (tpp cs:0,0,10) -- (tpp cs:15,0,10) -- (tpp cs:15,0,0) -- cycle;
\begin{scope}[
grid source opposite corners={(0cm,0cm) and (15cm,10cm)},
grid target corners={(tpp cs:0,0,0)--(tpp cs:15,0,0)--(tpp cs:15,0,10)--(tpp cs:0,0,10)}
]
\pgftransformnonlinear\tikzgridtransform
% \draw[dotted] (0cm,4.75cm) -- (15cm,4.75cm);
% \draw[red] (0cm,5.00cm) -- (15cm,5.00cm);
% \draw[dotted] (0cm,5.25cm) -- (15cm,5.25cm);
%
% \draw[dotted] (6.1cm,0cm) -- (6.1cm,10cm);
% \draw[red] (7.5cm,0cm) -- (7.5cm,10cm);
% \draw[dotted] (8.9cm,0cm) -- (8.9cm,10cm);
\foreach \char [count=\i from -2] in {O,M,E,A,G}{
\pgftransformshift{\pgfpointadd{\pgfpoint{7.5cm}{5cm}}{\pgfpoint{\i *0.6cm}{0cm}}}
\pgftransformscale{2}
\pgfnode{rectangle}{center}{\char}{}{}
}
\end{scope}
% \begin{scope}[dotted,line width=0.2pt]
% \node[label=right:p,fill,circle,inner sep = 2pt] (p) at (vp-p){};
%
% \draw (tpp cs:0,0,10) -- (p.center);
% \draw (tpp cs:0,0,0) -- (p.center);
% \draw (tpp cs:0,5,10) -- (p.center);
% \draw (tpp cs:0,5,0) -- (p.center);
%
% \node[label=left:q,fill,circle,inner sep = 2pt] (q) at (vp-q){};
%
% \draw (tpp cs:0,0,10) -- (q.center);
% \draw (tpp cs:0,0,0) -- (q.center);
% \draw (tpp cs:15,0,10) -- (q.center);
% \draw (tpp cs:15,0,0) -- (q.center);
% \end{scope}
\end{scope}
\end{tikzpicture}
}
\end{document}
编辑请参阅我之前的回答的先前编辑
我定义了一个新的坐标系three point perspective
。它可以用作
\draw (three point perspective cs:0,0,0) -- (three point perspective cs:5,5,5);
或者稍微方便一点
\draw (tpp cs:0,0,0) -- (tpp cs:5,5,5);
要打开透视视图,您可以调用perspective={<options>}
Tikz 键。选项包括:
p={(p_x,p_y,p_z)}
设置消失点的x
方向,将其设置p_x
为 0。q={(q_x,q_y,q_z)}
设置消失点的y
方向,将其设置q_y
为 0。r={(r_x,r_y,r_z)}
设置消失点的z
方向,将其设置r_z
为 0。
默认视角设置为p={(15,0,0)},q={(0,15,0)},r={(0,0,50)}
。
为了改变视角,我还添加了一个view={<rotate about x>}{<rotate about z>}
键。后者确保我不再需要它tikz-3dplot
。
结果类似,但更易于使用。
\documentclass[tikz]{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usepackage{mathtools}
\makeatletter
% 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}{
\def\tpp@x{#1}
\def\tpp@y{#2}
\def\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)}
\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}
\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
\definecolor{mydarkbluishgray}{RGB}{134 134 191}
\definecolor{mylightbluishgray}{RGB}{215 215 255}
\begin{document}
\begin{tikzpicture}[line join=round]
\begin{scope}[
scale=10,
view={85}{-40},
perspective={
p = {(1,0,0.55)},
q = {(0,1,0.55)},
}
]
\fill[mydarkbluishgray] (tpp cs:0,0,0) -- (tpp cs:0,0,1) -- (tpp cs:0,0.5,1) -- (tpp cs:0,0.5,0) -- cycle;
\fill[mylightbluishgray] (tpp cs:0,0,0) -- (tpp cs:0,0,1) -- (tpp cs:1.5,0,1) -- (tpp cs:1.5,0,0) -- cycle;
\path (tpp cs:0,0,0.5) -- node[sloped]{OMEAG} (tpp cs:1.5,0,0.5);
\begin{scope}[dotted,line width=0.2pt]
\node[label=right:p,fill,circle,inner sep = 2pt] (p) at (vp-p){};
\draw (tpp cs:0,0,1) -- (p.center);
\draw (tpp cs:0,0,0) -- (p.center);
\draw (tpp cs:0,0.5,1) -- (p.center);
\draw (tpp cs:0,0.5,0) -- (p.center);
\node[label=left:q,fill,circle,inner sep = 2pt] (q) at (vp-q){};
\draw (tpp cs:0,0,1) -- (q.center);
\draw (tpp cs:0,0,0) -- (q.center);
\draw (tpp cs:1.5,0,1) -- (q.center);
\draw (tpp cs:1.5,0,0) -- (q.center);
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}
当然我必须制作一个动画来显示不同的消失点距离:
MWE动画:
\documentclass[tikz]{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usepackage{mathtools}
\makeatletter
% 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}{
\def\tpp@x{#1}
\def\tpp@y{#2}
\def\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
\definecolor{mydarkbluishgray}{RGB}{134 134 191}
\definecolor{mylightbluishgray}{RGB}{215 215 255}
\begin{document}
\foreach \vp in {1,1.1,...,5}{
% \foreach \vp in {1}{
\begin{tikzpicture}[line join=round]
\clip (-12,0) rectangle (12,10);
\begin{scope}[
scale=10,
view={85}{-40},
perspective={
p = {(\vp,0,0.55)},
q = {(0,\vp,0.55)},
}
]
\fill[mydarkbluishgray] (tpp cs:0,0,0) -- (tpp cs:0,0,1) -- (tpp cs:0,0.5,1) -- (tpp cs:0,0.5,0) -- cycle;
\fill[mylightbluishgray] (tpp cs:0,0,0) -- (tpp cs:0,0,1) -- (tpp cs:1.5,0,1) -- (tpp cs:1.5,0,0) -- cycle;
\path[dotted] (tpp cs:0,0,0.5) -- node[sloped]{OMEAG} (tpp cs:1.5,0,0.5);
\begin{scope}[dotted,line width=0.2pt]
\node[label=right:p,fill,circle,inner sep = 2pt] (p) at (vp-p){};
\draw (tpp cs:0,0,1) -- (p.center);
\draw (tpp cs:0,0,0) -- (p.center);
\draw (tpp cs:0,0.5,1) -- (p.center);
\draw (tpp cs:0,0.5,0) -- (p.center);
\node[label=left:q,fill,circle,inner sep = 2pt] (q) at (vp-q){};
\draw (tpp cs:0,0,1) -- (q.center);
\draw (tpp cs:0,0,0) -- (q.center);
\draw (tpp cs:1.5,0,1) -- (q.center);
\draw (tpp cs:1.5,0,0) -- (q.center);
\end{scope}
\end{scope}
\end{tikzpicture}
}
\end{document}
附录:二点透视理论
p_x <> 0
具有两个消失点的透视变换可以用四乘四的变换矩阵 H 来描述,该矩阵 H 是两个消失点 p 和以及 和 的 r的函数r_y <> 0
。
您可以按如下方式构建 H
为了能够用 H 变换三维表示的点 x,必须在投影空间中表示它,可以写成
投影空间中的向量与非零标量 alpha 的任何乘积(四维向量的延伸)仍会映射到三维空间中的同一点。例如,以下两点映射到三维空间中的同一点:
因此,要获得 3D 点的三个坐标,您可以将所有条目除以第四个条目(我们需要将其与变换矩阵 H 相乘后得到)。
答案2
当我看到Max 的回答很棒我忍不住要添加一些decorations.text
效果。@Max:如果你想把这个添加到你的答案中,我很乐意删除它。结果也不是很完美,因为单个角色确实被重新缩放了,但角色的不同侧面没有。
编辑:虽然在我之前的版本中高度的重新缩放是可以的(我认为),但我没有正确拉伸字符的宽度。因此,效果比应有的要弱。非常感谢 AndreC 让我走上正确的轨道!
\documentclass[tikz]{standalone}
\usepackage{tikz}
\usepackage{tikz-3dplot}
\usetikzlibrary{decorations.text,calc,math}
\usepackage{mathtools}
\makeatletter
% 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}{
\def\tpp@x{#1}
\def\tpp@y{#2}
\def\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
\definecolor{mydarkbluishgray}{RGB}{134 134 191}
\definecolor{mylightbluishgray}{RGB}{215 215 255}
\begin{document}
\foreach \vp in {1,1.1,...,5}{
% \foreach \vp in {1}{
\begin{tikzpicture}[line join=round]
\clip (-12,0) rectangle (12,10);
\begin{scope}[
scale=10,
view={85}{-40},
perspective={
p = {(\vp,0,0.55)},
q = {(0,\vp,0.55)},
}
]
\fill[mydarkbluishgray] (tpp cs:0,0,0) -- (tpp cs:0,0,1) -- (tpp cs:0,0.5,1) -- (tpp cs:0,0.5,0) -- cycle;
\fill[mylightbluishgray] (tpp cs:0,0,0) -- (tpp cs:0,0,1) -- (tpp cs:1.5,0,1) -- (tpp cs:1.5,0,0) -- cycle;
\path[dotted] (tpp cs:0,0,0.5) -- (tpp cs:1.5,0,0.5)
node[sloped,midway,opacity=0](TEXT){~~Ducks, marmots and koala bears!~} ;
% text effects1
\draw let \p1=($(tpp cs:1.5,0,0.5)-(tpp cs:0,0,0.5)$), % x
\p2=($(tpp cs:0,0,1)-(tpp cs:0,0,0)$), % z @ x=0
\p3=($(tpp cs:1.5,0,1)-(tpp cs:1.5,0,0)$), % z @ x=1.5
\n1={\y3/\y2},\n2={\x1/\y2} % n1 : decrease in z
in
\pgfextra{\pgfmathsetmacro{\RatioOne}{\n1}\xdef\RatioOne{\RatioOne}
\pgfmathsetmacro{\RatioTwo}{\n2}\xdef\RatioTwo{\RatioTwo}
\typeout{\RatioOne,\RatioTwo}}
[decorate,decoration={text effects along path, text={Ducks, marmots and koala bears!},raise=-3pt,
text effects/.cd,
character count=\i, character total=\n,
characters={text along path,
xscale=\RatioOne*1.15,
yscale=1.15*((1.5-0.5*\RatioTwo)-(\i/\n)*(1-\RatioTwo))}}]
(tpp cs:0.2,0,0.5) -- (tpp cs:1.5,0,0.5);
\draw (tpp cs:1,0,1) -- (tpp cs:1,0,0);
%
\begin{scope}[dotted,line width=0.2pt]
\node[label=right:p,fill,circle,inner sep = 2pt] (p) at (vp-p){};
\draw (tpp cs:0,0,1) -- (p.center);
\draw (tpp cs:0,0,0) -- (p.center);
\draw (tpp cs:0,0.5,1) -- (p.center);
\draw (tpp cs:0,0.5,0) -- (p.center);
\node[label=left:q,fill,circle,inner sep = 2pt] (q) at (vp-q){};
\draw (tpp cs:0,0,1) -- (q.center);
\draw (tpp cs:0,0,0) -- (q.center);
\draw (tpp cs:1.5,0,1) -- (q.center);
\draw (tpp cs:1.5,0,0) -- (q.center);
\end{scope}
\end{scope}
\end{tikzpicture}
}
\end{document}
答案3
\documentclass{article}
\usepackage{pst-solides3d}
\begin{document}
\psset{viewpoint=50 20 30 rtp2xyz,Decran=50}
\begin{pspicture}(-4,-4)(4,5)
\psset{unit=0.5,solidmemory,lightsrc=viewpoint}
\psSolid[object=cube,a=8,action=draw**,name=A,linecolor=red]%
\psset{fontsize=80}
\psSolid[object=plan,action=none, definition=solidface,args=A 0,name=P0]
\psProjection[object=texte,linecolor=red,text=Side A,plan=P0]%
\psSolid[object=plan,action=none,definition=solidface,args=A 1,name=P1]
\psProjection[object=texte,linecolor=red,text=Side B,plan=P1]%
\psSolid[object=plan,action=none,definition=solidface,args=A 4,name=P4]
\psProjection[object=texte,linecolor=red,text=Side E,plan=P4]%
\axesIIID(4,4,4)(6,6,6)
\end{pspicture}
\end{document}