![tikz,定位库:缩放图片中的节点距离](https://linux22.com/image/280764/tikz%EF%BC%8C%E5%AE%9A%E4%BD%8D%E5%BA%93%EF%BC%9A%E7%BC%A9%E6%94%BE%E5%9B%BE%E7%89%87%E4%B8%AD%E7%9A%84%E8%8A%82%E7%82%B9%E8%B7%9D%E7%A6%BB.png)
我确实发现定位库中键移位部分中没有维度的数字没有缩放,这很尴尬。我可以检索单位向量并将其用于值中,但我确实发现语法对用户不友好。有没有好的方法告诉 tikz 将“右下方=3 和 3”解释为 3*scaled xvector 而不是 3*xvector?
\documentclass[]{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{tikz}
\usetikzlibrary{positioning}
\usetikzlibrary{backgrounds}
\begin{document}
\begin{tikzpicture}[show background rectangle]
\pgfpointtransformed{\pgfpointxy{1}{1}};
\pgfgetlastxy{\xvec}{\yvec}
\tikzset{node distance=\xvec*1 and \yvec*1}
\coordinate (C) at (1,1);
\draw[red,fill] (C) circle (5pt);
\node[below=of C] {no shifting part};
\node[below right=3 and 3,anchor=base west] (A) at (C) {no cm};
\node[below right=3cm and 3cm,anchor=base east] (D) at (C) {cm};
\node[below right=\xvec*3 and \yvec*3,anchor=south] (B) at (C) {scaled};
\draw[red](C)--(A.base west);
\end{tikzpicture}
\begin{tikzpicture}[scale=0.3,show background rectangle]
\pgfpointtransformed{\pgfpointxy{1}{1}};
\pgfgetlastxy{\xvec}{\yvec}
\tikzset{node distance=\xvec*1 and \yvec*1}
\coordinate (C) at (1,1);
\draw[red,fill] (C) circle (5pt);
\node[below=of C] {no shifting part}; %ok
%This should work like in the last node:
\node[below right=3 and 3,anchor=base west] (A) at (C) {no cm}; %not ok
\node[below right=3cm and 3cm,anchor=base east] (D) at (C) {cm}; %ok
\node[below right=\xvec*3 and \yvec*3,anchor=south] (B) at (C) {scaled}; %ok
\draw[red](C)--(A.base west);
\end{tikzpicture}
\end{document}
答案1
我和我的positioning-plus
node distance
该库已经包含一种方法来分解通过存储的值
<direction>=<y-factor> and <x-factor>:of <reference>
node distance=1 and 1
对于你的例子来说已经适用了
below right=3 and 3:of C
或
below right=3:of C
我添加了一个小修复,以便它在没有参考的情况下也可以工作,即below right=3 and 3:
。
冒号:
用作比例因子的分隔符。从技术上讲,可以说2 and 3:2cm and 3cm of <reference>
,这是否比有优势4cm and 9cm of <reference>
,我不这么认为。
带有前缀的语法s
似乎很难解析。
还有一个键node distance transformation
(默认值true
:),用于激活定位键的变换(类似于transform shape
节点)。当然,任何变换都会应用(rotate
等等)。
我对 PGF 转换不太有经验,有时觉得它们相当令人困惑,所以我不知道这是否是正确/最佳的方法。
顺便说一句,如果你只想扩展坐标坐标系,您也可以使用默认坐标系x=.3cm, y=.3cm
的比例.3
。但是,这取决于您的用例以及您首先应用缩放的原因。
代码
\documentclass[tikz]{standalone}
\usetikzlibrary{positioning-plus,backgrounds}
\tikzset{l/.style={
label={[fill,circle,inner sep=+0pt,minimum size=+2pt,label=right:{#1}]center:}}}
\begin{document}
\begin{tikzpicture}[gridded, node distance=1 and 1]
\draw (0,0) circle[radius=2pt];
\coordinate[l=ref] (C) at (1,1);
\coordinate[below right=1 and 1:,l={1 and 1}] (f1) at (C);
\coordinate[below right=3 and 2:,l={3 and 2}] (f2) at (C);
\end{tikzpicture}
\makeatletter
\begin{tikzpicture}[scale=.3, gridded, node distance=1 and 1,
node distance transformation=true]
\draw (0,0) circle[radius=2pt];
\coordinate[l=ref] (C) at (1,1);
\coordinate[below right=1 and 1:,l={1 and 1}] (f1) at (C);
\coordinate[below right=3 and 2:,l={3 and 2}] (f2) at (C);
\end{tikzpicture}
\end{document}
输出(不按比例)
答案2
不确定这个答案有多么可取,因为它涉及内部内容,但本质上scale positioning
提供了一个关键,如果true
中断通常的定位机制,则从变换矩阵中提取缩放并将其应用于定位值,然后继续照常进行。
然而,如果应用缩放以外的变换,可能会发生奇怪的事情。
\documentclass[border=0.125cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{positioning}
\makeatletter
\let\tikz@lib@place@handle@original=\tikz@lib@place@handle@
\def\tikz@lib@place@handle@alternative#1#2#3#4#5#6{%
% Get transform entries
\pgfgettransformentries\tikz@a\tikz@b\tikz@c\tikz@d\tikz@e\tikz@f%
% Get scale
\pgfpoint{sqrt(\tikz@a*\tikz@a+\tikz@b*\tikz@b)*(\tikz@a<0 ? -1 : 1)}%
{sqrt(\tikz@c*\tikz@c+\tikz@d*\tikz@d)*(\tikz@d<0 ? -1 : 1)}%
\pgf@x=#3\pgf@x%
\pgf@y=#4\pgf@y%
\edef\tikz@lib@x{\pgfmath@tonumber\pgf@x}%
\edef\tikz@lib@y{\pgfmath@tonumber\pgf@y}%
\tikz@lib@place@handle@original{#1}{#2}{\tikz@lib@x}{\tikz@lib@y}{#5}{#6}%
}
\newif\iftikz@lib@place@scale@positioning
\tikzset{%
scale positioning/.code={%
\csname tikz@lib@place@scale@positioning#1\endcsname%
\iftikz@lib@place@scale@positioning%
\let\tikz@lib@place@handle@=\tikz@lib@place@handle@alternative%
\else%
\let\tikz@lib@place@handle@=\tikz@lib@place@handle@original%
\fi%
},
scale positioning/.default=true,
% Define special keys...
below right'/.style={scale positioning, below right={#1}}%
% ...more needed
}
\begin{document}
\begin{tikzpicture}[scale=1,
every node/.style={shape=circle},
every pin edge/.style={<-},
every pin/.style={shape=rectangle},
mark/.style args={#1 at #2 with #3}{
draw=#3, dotted,
pin={[pin edge=#3, #3]#2:#1}
}]
\fill [blue, opacity=0.25] (0,0) rectangle(5,3);
\coordinate [label=above:$C$] (C) at (0,3);
\draw [blue, <->] (3,0) -- (C);
\node [below right=3cm and 3cm of C, mark=cm at 260 with blue] {};
\node [below right=3 and 3 of C, mark=vec at 280 with blue] {};
\begin{scope}[scale=0.3]
\coordinate [label=left:$C^\prime$] (C') at (0,3);
\draw [red, <->] (3,0) -- (C');
\fill [red, opacity=0.25] (0,0) rectangle (5,3);
\node [below right=3cm and 3cm of C', mark=cm at 260 with red] {};
\node [below right=3 and 3 of C', mark=vec at 280 with red] {};
\node [below right=3cm and 3cm of C', dash phase=3.75pt, mark=cm at 220 with green] {};
% Scale one positioning using special key.
\node [below right'=3 and 3 of C', dash phase=3.75pt, mark=vec at 320 with green] {};
% Scale everything in a scope.
%
% NB. scale positioning can be used in path options
% but *must* come before the positioning specification.
\begin{scope}[scale positioning]
\node [below right=3cm and 3cm of C', mark=cm at 280 with orange] {};
\node [below right=3 and 3 of C', mark=vec at 260 with orange] {};
\end{scope}
\end{scope}
\end{tikzpicture}
\end{document}