我正在尝试计算\newcommand
\documentclass[tikz]{standalone}
\usepackage{tikz}
\def\spradius{1}
\newcommand*{\projectToSphere}[2]{%
% calculate a reverse projection point of (#1, #2, 0) on the sphere centered at (0,0,\spradius) of \spradius (radius)
\pgfmathsetmacro{\XYTwo}{(#1)^2 + (#2)^2}
\pgfmathsetmacro{\zvalue}{(2 * \XYTwo) / (\XYTwo / \spradius + 4 * \spradius)}
\pgfmathsetmacro{\xvalue}{(2 * \spradius - \zvalue) / (2 * \spradius) * #1}
\pgfmathsetmacro{\yvalue}{(2 * \spradius - \zvalue) / (2 * \spradius) * #2}
{\xvalue}, {\yvalue}, {\zvalue}
}%
\begin{document}
\begin{tikzpicture}
\draw[fill=green] (\projectToSphere{3}{4}) circle (0.5pt);
\end{tikzpicture}
\end{document}
我不断得到! Incomplete \iffalse;
我已尝试过:
- 移至
\newcommand
tikzpicture
- 移出
\newcommand
文档 - 添加
*
到\newcommand
- 直接计算是可行的,但是我的实际计算更复杂,因此很难在里面进行直接计算。
有可能制作
\pgfmathsetmacro
或\pgfmathparse
在里面工作吗\newcommand
?
答案1
\pgfmathparse
并\pgfmathsetmacro
在 中工作\newcommand
,只是以tikz
一种在大多数情况下都很好但在这里却不行的方式解析坐标。您可以定义一个函数,但不幸的是,您需要逐个组件地插入它。
\documentclass[tikz]{standalone}
\def\spradius{1} %<- maybe not a good practice
\pgfmathdeclarefunction{projectToSphereX}{2}{%
\begingroup%
\pgfmathparse{{projectToSphere(#1,#2)}[0]}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\pgfmathdeclarefunction{projectToSphereY}{2}{%
\begingroup%
\pgfmathparse{{projectToSphere(#1,#2)}[1]}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\pgfmathdeclarefunction{projectToSphereZ}{2}{%
\begingroup%
\pgfmathparse{{projectToSphere(#1,#2)}[2]}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\pgfmathdeclarefunction{projectToSphere}{2}{%
\begingroup%
\pgfmathsetmacro{\XYTwo}{(#1)^2 + (#2)^2}%
\pgfmathsetmacro{\zvalue}{(2 * \XYTwo) / (\XYTwo / \spradius + 4 * \spradius)}%
\pgfmathsetmacro{\xvalue}{(2 * \spradius - \zvalue) / (2 * \spradius) * #1}%
\pgfmathsetmacro{\yvalue}{(2 * \spradius - \zvalue) / (2 * \spradius) * #2}%
\edef\pgfmathresult{\xvalue,\yvalue,\zvalue}%
\pgfmathsmuggle\pgfmathresult\endgroup%
}%
\begin{document}
\pgfmathparse{projectToSphere(3,4)}
\begin{tikzpicture}
\draw[fill=green]
({projectToSphereX(3,4)},{projectToSphereY(3,4)},{projectToSphereZ(3,4)})
circle[radius=0.5pt];
\end{tikzpicture}
\end{document}
在我看来,您可能正在寻找非线性变换。
\documentclass[tikz,border=3mm]{standalone}
\usepackage{tikz-3dplot}
\usepgflibrary{fpu}
\usepgfmodule{nonlineartransformations}
\newcommand{\PgfmathsetmacroFPU}[2]{\begingroup% https://tex.stackexchange.com/a/503835
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
\pgfmathsetmacro{#1}{#2}%
\pgfmathsmuggle#1\endgroup}%
\makeatletter
\def\fancyspheretransformation{% similar to the pgfmanual section 103.4.2
\PgfmathsetmacroFPU{\XYTwo}{\pgf@x*\pgf@x+\pgf@y*\pgf@y}%
\PgfmathsetmacroFPU{\zvalue}{-(2*\XYTwo)/(\XYTwo/\spradius+4*\spradius)}%
\PgfmathsetmacroFPU{\xvalue}{(2*\spradius-\zvalue)/(2*\spradius)*\pgf@x}%
\PgfmathsetmacroFPU{\yvalue}{(2*\spradius-\zvalue)/(2*\spradius)*\pgf@y}%
\PgfmathsetmacroFPU{\myx}{cos(\tdplotmainphi)*\xvalue+sin(\tdplotmainphi)*\yvalue}%
\PgfmathsetmacroFPU{\myy}{-cos(\tdplotmaintheta)*sin(\tdplotmainphi)*\xvalue+cos(\tdplotmaintheta)*cos(\tdplotmainphi)*\yvalue-sin(\tdplotmaintheta)*\zvalue}%
\pgf@y=\myy pt% \typeout{z=\zvalue,x=\xvalue,y=\yvalue}%
\pgf@x=\myx pt%
}
\makeatother
\begin{document}
\begin{tikzpicture}
\def\spradius{4cm} %<- maybe not a good practice
\tdplotsetmaincoords{70}{110}
\begin{scope}[tdplot_main_coords,canvas is xy plane at z=-2]
\foreach \Color [count=\X starting from -3] in {blue,cyan,green,yellow,orange,red}
{\foreach \Y in {-3,...,2}
{\draw[fill=\Color] (\X,\Y) rectangle (\X+1,\Y+1);}}
\end{scope}
\begin{scope}[transform shape nonlinear=true,]
\pgftransformnonlinear{\fancyspheretransformation}
\foreach \Color [count=\X starting from -3] in {blue,cyan,green,yellow,orange,red}
{\foreach \Y in {-3,...,2}
{\draw[fill=\Color] (\X,\Y) rectangle (\X+1,\Y+1);}}
\end{scope}
\end{tikzpicture}
\end{document}