![tikz中图片的对数缩放](https://linux22.com/image/293948/tikz%E4%B8%AD%E5%9B%BE%E7%89%87%E7%9A%84%E5%AF%B9%E6%95%B0%E7%BC%A9%E6%94%BE.png)
我正在寻找类似的东西
\begin{scope}[scaling=logarithmic]
...
\end{scope}
原因是,我试图可视化 R^2 中某些特定集合的 Minkowski 和(具有某种二元分区)与具有特定半径的球是否相交。问题是,通过这种二元(即指数)缩放,事情很快就会变得难以理解。我在下图中说明了该图的总体思路(该图使用了相对较小的尺度,并不代表我希望说明的内容)。
我想以对数方式缩小所有东西 - 包括弧线和所有东西(没有闵可夫斯基和,我可以手动完成此操作,但正确地变换壳似乎非常麻烦),但除了轴之外,我还没有发现任何关于对数缩放的内容。
[编辑]在对我所说的对数缩放的实际含义进行一些澄清之后,我更愿意将整个图像(在极坐标中)转换为(r,phi)->(log(r+1),phi)
,或者(在笛卡尔坐标中)转换为(x,y)->(log(|x|+1),log(|y|+1)
。[/编辑]
由于变换是非线性的,我怀疑可能必须进入 PGF?我也尝试朝这个方向寻找 - 不幸的是,也无济于事。
我的情节代码是:
\documentclass{article}
\usepackage{fullpage}
\usepackage[english]{babel}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}[scale=1/4]
\clip (-2.5,-2.5) rectangle (35,18);
\begin{scope}[very thin,<->]
\draw (-2.5,0) -- (35,0);
\draw (0,-2.5) -- (0,18);
\end{scope}
\foreach \j in {1,...,5} \draw[red] (0,0) circle (2^\j);
\foreach \r / \i [evaluate=\r as \ang using 90/\r] in {8/5,16/3} % radius and number of slice
{
\begin{scope}[rotate={(\i-1)*\ang}]
\draw (-\ang:\r/2) arc (-\ang:\ang:\r/2) -- (\ang:2*\r) arc (\ang:-\ang:2*\r) -- cycle;
\foreach \m in {2} % usually more
{% different code if \m>\r/2
\draw ($(-\ang:\r/2)+(-\ang-90:\m)$) arc (-\ang-90:-\ang-180:\m)
arc (-\ang:\ang:\r/2-\m) arc (\ang+180:\ang+90:\m)
-- ($(\ang:2*\r)+(\ang+90:\m)$) arc (\ang+90:\ang:\m)
arc (\ang:-\ang:2*\r+\m) arc (-\ang:-\ang-90:\m) -- cycle;
};
\end{scope}
};
\end{tikzpicture}
\end{document}
更新:@percusse 的回答向我展示了如何从原则上做到这一点,但仍然存在一些问题。我正在更新这篇文章,因为它太长了,无法发表评论。
最重要的是非线性变换会扰乱现有的坐标变换。这是令人担心的,但我希望有一种方法可以先执行所有可用的线性变换(或者更好的是,在范围内的线性变换),然后再执行非线性变换。这对于较长的路径尤其重要,因为变换会沿途更新(见下面的示例)。此外,线性变换外部包含非线性变换的范围仍然应该适用于结果(在理想世界中)。
pgfmanual
我在-中找到了一个命令\pgfpointtransformednonlinear{<point>}
,它
工作原理类似于 \pgfpointtransformed,但也应用当前的非线性变换;也就是说,它首先应用当前线性变换,然后应用当前非线性变换
这似乎做了必要的事情 - 但它只适用于点,并没有提到用于路径的类似命令......
由于我认为非线性变换在概念上是不同的,我尝试提取当前的线性变换并将其作为非线性变换提供给 tikz,但实际上并没有奏效。如果有人感兴趣,我可以发布代码 - 它基于使用 的\def\lintransformation#1#2#3#4#5#6{...
输出调用的代码\pgfgettransformentries
。
为了回答 percusse 的问题,即结果应该大致如何,我附上了以下两个图。在示例中,内部区域围绕半径 构建2^4
,这意味着(由于构造)其径向边界应由2^3
和界定,分别由对数图中的和2^5
对应的红线界定。如果违反以下任一条件,则表明某些东西不起作用的两个明显迹象:变换应保持沿构建支撑的射线的对称性(在下面未旋转的情况下,这是 - 轴)和3
5
x
不能引入新的交叉点与没有变换的情况相比!
图片代码:
\documentclass{article}
\usepackage[english]{babel}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepgfmodule{nonlineartransformations}
\makeatletter
\def\logtransformation{%
\pgfmathveclen{\pgf@x}{\pgf@y}%
\pgfmathparse{log2(\pgfmathresult/28.4+1)}% factor accounts for pt2cm conversion
%\pgfmathlogtwo{\pgfmathresult}% command not found although it's in the documentation?!
\pgf@xa=\pgfmathresult pt% somehow faster than using cm
\pgfmathatantwo{\pgf@y}{\pgf@x}%
\pgfmathsincos@{\pgfmathresult}%
\pgfmathmultiply{\pgf@xa}{\pgfmathresultx}\pgf@x=\pgfmathresult cm% USED CM AS UNITS TO SCALE UP !!!
\pgfmathmultiply{\pgf@xa}{\pgfmathresulty}\pgf@y=\pgfmathresult cm% USED CM AS UNITS TO SCALE UP !!!
}
\makeatother
\begin{document}
% complicated version - no long paths
\begin{tikzpicture} %[scale=1/2]
% try uncommenting scale - doesn't affect what is transformed by \logtransformation
\clip (-1,-3) rectangle (6,3);
\draw[<->] (-6,0) -- (6,0);
\draw[<->] (0,-6) -- (0,6);
% the reason I do this before the transformation is to see how it corresponds to the
% untransformed values - this is how I found the factor ~28, which I was able to guess
% had to do with a unit conversion, allowing me to find the exact value.
\foreach \j in {3,5} % dyadic scales below and above the given radius
{
\pgfmathparse{log2(2^\j+1)}% instead of radius \j, incorporates `+1` of \logtransformation
\draw[red] circle (\pgfmathresult); % strange: no coordinates! If given, takes y-value as radius!
}
\foreach \r / \i [evaluate=\r as \ang using 90/\r] in {2^4/5} % radius and number of slice
{
\begin{scope} %[rotate={(\i-1)*\ang}]
% try uncommenting rotation - works
\pgftransformnonlinear{\logtransformation}
\draw (-\ang:\r/2) arc (-\ang:\ang:\r/2);
\draw (\ang:\r/2) -- (\ang:2*\r);
\draw (\ang:2*\r) arc (\ang:-\ang:2*\r);
\draw (-\ang:2*\r) -- (-\ang:\r/2);
\foreach \m in {2} % also works for \m=\r/2!
{
\draw ($(-\ang:\r/2)+(-\ang- 90:\m)$) arc (-\ang- 90:-\ang-180: \m);
\draw ($(-\ang:\r/2)+(-\ang+180:\m)$) arc (-\ang : \ang :\r/2-\m);
\draw ($( \ang:\r/2)+( \ang+180:\m)$) arc ( \ang+180: \ang+ 90: \m);
\draw ($( \ang:\r/2)+( \ang+ 90:\m)$) -- ($( \ang:2*\r)+( \ang+90:\m)$);
\draw ($( \ang:2*\r)+( \ang+ 90:\m)$) arc ( \ang+ 90: \ang : \m);
\draw ($( \ang:2*\r)+( \ang :\m)$) arc ( \ang :-\ang :2*\r+\m);
\draw ($(-\ang:2*\r)+(-\ang :\m)$) arc (-\ang :-\ang- 90: \m);
\draw ($(-\ang:2*\r)+(-\ang- 90:\m)$) -- ($(-\ang:\r/2)+(-\ang-90:\m)$);
};
\end{scope}
}
\end{tikzpicture}~~~
\begin{tikzpicture} % how it should be tikz'd, but doesn't work
\clip (-1,-3) rectangle (6,3);
\draw[<->] (-6,0) -- (6,0);
\draw[<->] (0,-6) -- (0,6);
\foreach \j in {3,5} % dyadic scales below and above the given radius
{
\pgfmathparse{log2(2^\j+1)}% instead of radius \j, incorporates `+1` of \logtransformation
\draw[red] circle (\pgfmathresult); % strange: no coordinates! If given, takes y-value as radius!
}
\foreach \r / \i [evaluate=\r as \ang using 90/\r] in {2^4/5} % radius and number of slice
{
\begin{scope} %[rotate={(\i-1)*\ang}]
\pgftransformnonlinear{\logtransformation}
\draw (-\ang:\r/2) arc (-\ang:\ang:\r/2) -- (\ang:2*\r) arc (\ang:-\ang:2*\r) -- cycle;
\foreach \m in {2}
{
\draw ($(-\ang:\r/2)+(-\ang-90:\m)$) arc (-\ang-90:-\ang-180:\m)
arc (-\ang:\ang:\r/2-\m) arc (\ang+180:\ang+90:\m)
-- ($(\ang:2*\r)+(\ang+90:\m)$) arc (\ang+90:\ang:\m)
arc (\ang:-\ang:2*\r+\m) arc (-\ang:-\ang-90:\m) -- cycle;
};
\end{scope}
}
\end{tikzpicture}
\end{document}
更新 2:为了完整起见,下面是具有原始参数的图 - 使用不令人满意但(按比例缩放)可用的版本和短路径。正如我所提到的,比例最终会更高,这只是为了演示目的。红色圆圈代表 2 的幂 - 由于+1
-适应,它们不会完全等距分布,所以我想到了另一种适应性,基本上用 替换半径,r
如果1/4*r^2+1
。r<2
这个多项式是1@0
,2@2
并且导数是1@2
。剩下的一个缺点(除了缺乏路径)是,对于\m=\r/2
,一些内部参数超过了 tikz 的最大大小 - 我看到了图,但 latex 崩溃了。
对于情节,更新后代码的唯一变化是:
...
\pgfmathveclen{\pgf@x}{\pgf@y}%
\pgfmathparse{\pgfmathresult/28.4}% factor accounts for pt2cm conversion
\pgfmathparse{\pgfmathresult > 2 ? \pgfmathresult : 1/4*\pgfmathresult^2+1}
\pgfmathparse{log2(\pgfmathresult)}%
\pgf@xa=\pgfmathresult pt%
...
\foreach \j in {1,...,5} % dyadic scales below and above the given radius
{\node[below right] at (\j,0) {$2^\j$}; \draw[red] (0,0) circle (\j);}
...
答案1
我进行了一些非线性变换,但我不知道结果是否有意义。如果您可以显示前后结果,我可以尝试检查错误
需要考虑的一件事是,这r -> log(r)
是一个相当复杂的变换,所以我通过将单位转换为厘米来提高。我不知道这样做是否明智。
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}
\usepgfmodule{nonlineartransformations}
\makeatletter
\def\logtransformation{%
\pgfmathveclen{\pgf@x}{\pgf@y}\pgfmathln{\pgfmathresult}%
\pgf@xa=\pgfmathresult pt%
\pgfmathatantwo{\pgf@y}{\pgf@x}%
\pgfmathsincos@{\pgfmathresult}%
\pgfmathmultiply{\pgf@xa}{\pgfmathresultx}\pgf@x=\pgfmathresult cm% USED CM AS UNITS TO SCALE UP !!!
\pgfmathmultiply{\pgf@xa}{\pgfmathresulty}\pgf@y=\pgfmathresult cm% USED CM AS UNITS TO SCALE UP !!!
}
\makeatother
\begin{document}
\begin{tikzpicture}[scale=3]
\begin{scope}[xshift=1cm]
\pgftransformnonlinear{\logtransformation}
% What happens to vertical line
\draw[ultra thick, blue] (2,-10) -- (2,10);
% What happens to horizontal line
\draw[ultra thick,red] (-1,3) -- (7,3);
% What happens to circle
\draw[ultra thick,yellow] (2,2) circle (3cm);
\foreach \r / \i [evaluate=\r as \ang using 90/\r] in {8/7,16/3} % radius and number of slice
{
\begin{scope}[rotate={(\i-1)*\ang}]
\draw (-\ang:\r/2) arc (-\ang:\ang:\r/2) -- (\ang:2*\r) arc (\ang:-\ang:2*\r) -- cycle;
\foreach \m in {4} % usually more
{% different code if \m>\r/2
\draw ($(-\ang:\r/2)+(-\ang-90:\m)$) arc (-\ang-90:-\ang-180:\m)
arc (-\ang:\ang:\r/2-\m) arc (\ang+180:\ang+90:\m)
-- ($(\ang:2*\r)+(\ang+90:\m)$) arc (\ang+90:\ang:\m)
arc (\ang:-\ang:2*\r+\m) arc (-\ang:-\ang-90:\m) -- cycle;
};
\end{scope}
}
\end{scope}
\end{tikzpicture}
\end{document}
嗯,基本上就是这样的