考虑以下 (-2, -1) -- (3, 9) 线段的图:
我想要应用一个变换,使得水平轴是某个点的极角,而垂直轴是该点与原点之间的距离。
它看起来应该是这样的:
我看过了这个问题所以我相信这应该是可能的,但我不太了解里面的代码\def\polartransformation
。
pgfmath
任何关于如何执行此操作的提示或有关这些功能的文档链接都pgftransformnonlinear
将不胜感激。
答案1
首先,我认为 pgfmanual 并不完全正确。手册第 107.4.2 节指出
% \pgf@x will contain the
radiusangle % \pgf@y will contain the distance \pgfmathsincos@{\pgf@sys@tonumber\pgf@x}% % pgfmathresultx is now the cosine ofradiusangle and % pgfmathresulty is the sine ofradiusangle \pgf@x=\pgfmathresultx\pgf@y% \pgf@y=\pgfmathresulty\pgf@y%
pgfmanual 中的代码可能正在做的是以x
pt 表示坐标,然后取 cos 和 sin x/pt
(即,如果 x=50pt,则它将返回 cos(50)),并将结果乘以坐标y
,即
(x_new,y_new)=(y_old cos(x_old/pt),y_old sin(x_old/pt))
这导致了代码:
\documentclass{article}
\usepackage{tikz}
\usepgfmodule{nonlineartransformations}
\tikzset{declare function={mymod(\x)=\x-int(\x);}}
\makeatletter
\def\slowtransformation{% modified version of the manual 103.4.2 Installing Nonlinear Transformation
\typeout{before:\space\the\pgf@x\space\the\pgf@y}%
\edef\oriX{\the\pgf@x}%
\edef\oriY{\the\pgf@y}%
\pgfmathsetmacro{\myAngle}{mod(360+atan2(\oriY,\oriX),360)}
\pgfmathsetmacro{\myRadius}{veclen(\oriX,\oriY)}
\typeout{original\space x=\oriX\space y=\oriY}
\typeout{radius=\myRadius\space angle=\myAngle}
\setlength{\pgf@x}{\myAngle pt}
\setlength{\pgf@y}{\myRadius pt}
}
\def\fastertransformation{% modified version of the manual 103.4.2 Installing Nonlinear Transformation
\pgfmathsetmacro{\myAngle}{mod(720+atan2(\pgf@y,\pgf@x),360)}
\pgfmathsetmacro{\myRadius}{veclen(\pgf@x,\pgf@y)}
\setlength{\pgf@x}{\myAngle pt}
\setlength{\pgf@y}{\myRadius pt}
}
\makeatother
\begin{document}
\begin{tikzpicture}
\draw[-latex] (-2.3,-2) -- (3.5,-2) node[below]{$x$};
\draw[-latex] (0,-2.3) -- (0,4.5) node[left]{$y$};
\draw[blue] (-2, -1) -- (3, 4);
\end{tikzpicture}\\
\begin{tikzpicture}
\draw[-latex] (-0.3,0) -- (7.5,0) node[below]{$\varphi$};
\draw[-latex] (0,-0.3) -- (0,4.5) node[left]{$r$};
\pgftransformnonlinear{\slowtransformation}
\draw[blue] (-2, -1) -- (3, 4);
\end{tikzpicture}
\begin{tikzpicture}
\draw[-latex] (-0.3,0) -- (7.5,0) node[below]{$\varphi$};
\draw[-latex] (0,-0.3) -- (0,4.5) node[left]{$r$};
\pgftransformnonlinear{\fastertransformation}
\draw[blue] (-2, -1) -- (3, 4);
\end{tikzpicture}
\end{document}
有两个相同的转换,第一个转换(\slowtransformation
)更明确,并且问题\typeout
更容易理解,而第二个转换(\fastertransformation
)则更快一些。
笔记:
必须谨慎使用诸如
scale=...
和 之类的选项。毕竟,这种变换将采用坐标scale
和 等变换,并且然后将它们映射到极坐标。因此,如果有人[yscale=0.5]
在原点周围画一个圆,那么坐标就是椭圆的坐标,那么变换不是将它们映射到一条水平线(无需任何额外的变换即可完成)。当前代码将产生 0 到 360 度之间的角度,这由 控制
mod(360+atan2(\oriY,\oriX),360)
。如果您使用不同的约定,则需要相应地调整这段代码。
更新atan2(y,x)
:修复了角度( vs )计算中的两个愚蠢错误,atan2(x,y)
并使轴标签更加合适。我还删除了所有scale
指令并添加了更多解释。