在 TikZ 中按矢量方向缩放坐标

在 TikZ 中按矢量方向缩放坐标

xscale与通常的和沿标准向量方向缩放不同yscale,我正在考虑沿固定向量方向缩放,但我在手动选项中没有看到这一点,可以这样做吗?

编辑:我将解释一下变换。如果你在平面上有一个集合,则缩放n在...方向X扩大X坐标为n,即维度X乘以n,而维度保持完整。

同样,按照以下方向扩展乘以n乘以经过n,并保持垂直尺寸不变。

一般来说,你可以想象通过取向量来实现这一点并将其完成为空间的一个正交基,然后在这个新基中,仅缩放对应于。这就是 xscaling 或 yscaling 时所做的事情。

如下图所示,一般来说,你可以取一个超平面n维空间垂直于,以及n-1位于该超平面的维度保持不变,而垂直于该超平面的维度则被缩放。

在此处输入图片描述

在这个例子中,我按比例缩放了2垂直于平面。

编辑2:根据要求,我展示了形状的最小代码。

\coordinate (A) at (-4,3);
\coordinate (B) at (4,3);
\coordinate (C) at (4,-3);
\coordinate (D) at (-4,-3);
\draw (A) to (B) to [bend left] (C) to (D) to [bend left] cycle;

答案1

好的,我们开始吧。我当然同意@samcarter 的观点。

\documentclass{article}
\usepackage{amsmath}
\usepackage{tikz}
\begin{document}
The pgfmanual provides \verb|\pgftransformcm|, see e.g.\ section~103.2.2. All
one has to do is to cook up the transformation matrix. Assume we want to scale
by a factor $\xi$ in $y$--direction. The transformation matrix is then given by
\begin{align}
 T_y&~=~\begin{pmatrix}
  1 & 0\\ 0 & \xi
 \end{pmatrix}\;.
\end{align}
If one is to choose a different direction, one only has to sandwich $T$ between
a rotation matrix $\Omega$ and its inverse,
\begin{align}
 T_\theta&~=~\Omega\cdot T_y\cdot \Omega^{-1}\;,
\end{align}
where
\begin{align}
 \Omega~=~
 \begin{pmatrix}
  \cos\theta & \sin\theta\\ -\sin\theta & \cos\theta
 \end{pmatrix}\;.
\end{align}
The result of this exercise is 
\begin{align}
 T_\theta&~=~\begin{pmatrix}
 \frac{1}{2} (\xi-(\xi-1)\, \cos (2 \theta
   )+1) & (\xi-1) \cos (\theta ) \sin
   (\theta ) \\
 (\xi-1) \cos (\theta ) \sin (\theta )
   & \frac{1}{2} (\xi+(\xi-1) \cos (2
   \theta )+1)\end{pmatrix}\;.
\end{align}
Below is an example in which $\xi=2$ and $\theta=30^\circ$.

\def\myx{3}
\def\myTheta{30}
\begin{tikzpicture}
\draw (0,0) rectangle (2,2);
\begin{scope}
\pgftransformcm{(1 + \myx - (-1 + \myx)*cos(2*\myTheta))/2}{% 
(-1 + \myx)*cos(\myTheta)*sin(\myTheta)}{%
(-1 + \myx)*cos(\myTheta)*sin(\myTheta)}{% 
(1 + \myx + (-1 + \myx)*cos(2*\myTheta))/2}{\pgfpoint{0cm}{0cm}} 
\draw (0,0 ) rectangle (2,2);
\end{scope}
\end{tikzpicture}
\end{document}

在此处输入图片描述

附录:受到@percusse 的评论和 Kpym 的回答的启发,我编写了一种快速样式,它也使用了“主动变换”,即对旋转角度的解释可以说更直观。

\documentclass{article}
\usepackage{tikz}
\tikzset{rotostretch/.style 2 args={cm={(1 + #1 - (-1 + #1)*cos(2*#2))/2, 
-(-1 + #1)*cos(-#2)*sin(#2),
-(-1 + #1)*cos(-#2)*sin(#2), 
(1 + #1 + (-1 + #1)*cos(2*#2))/2,(0,0)}}}
\begin{document}
\begin{tikzpicture}
\draw[red] (0,0) rectangle (2,2);
\draw[rotostretch={2}{-30}] (0,0 ) rectangle (2,2);
\end{tikzpicture}
\end{document}

在此处输入图片描述

另一附录: 基于Kpym 的旧答案。类似于 Kpym 的新答案,但没有\makeatletter。(我并不是说使用 不好\makeatletter。)这是一个指令stretch along,类似于Kpym 的回答,谁先有这个。

\documentclass[tikz,border=3.14pt]{standalone}
\usetikzlibrary{calc}
\tikzset{rotostretch/.style 2 args={cm={(1 + #1 - (-1 + #1)*cos(2*#2))/2, 
-(-1 + #1)*cos(-#2)*sin(#2),
-(-1 + #1)*cos(-#2)*sin(#2), 
(1 + #1 + (-1 + #1)*cos(2*#2))/2,(0,0)}}}
\tikzset{stretch along/.code={\path let \p1=#1 in \pgfextra{%
\pgfmathsetmacro{\RotostretchAngle}{-atan2(\y1,\x1)}
\pgfmathsetmacro{\RotostretchRadius}{veclen(\y1,\x1)/28.3465}
\typeout{\RotostretchAngle,\RotostretchRadius}
\xdef\RotostretchRadius{\RotostretchRadius}
\xdef\RotostretchAngle{\RotostretchAngle}};
\pgfkeysalso{/tikz/rotostretch={\RotostretchRadius}{\RotostretchAngle}}}}

\begin{document}
\begin{tikzpicture}
\draw[red] (0,0) rectangle (2,2);
\draw[stretch along={(2,1)}] (0,0 ) rectangle (2,2);
\end{tikzpicture}
\end{document}

答案2

要按方向缩放,alpha我们可以简单地旋转,然后按 x 方向缩放,然后旋转回来。例如,要按 45° 方向缩放 2,我们可以简单地应用[rotate=45,xscale=2,rotate=-45] (最右边的操作最先执行)

我定义了两种样式scale angle direction = <angle><ratio>scale vector direction = <vector point><ratio>。第二种样式只是计算向量的角度参数,然后调用第一种样式。

\documentclass[tikz,border=7pt]{standalone}
\makeatletter
\tikzset{
  scale angle direction/.style 2 args ={
    % scale in direction #1 by #2
    rotate={#1},
    xscale=#2,
    rotate={#1*(-1)}
  },
  scale vector direction/.code 2 args={
    % get the angle argument of point #1
    \tikz@scan@one@point\pgfutil@firstofone#1\relax
    \pgfmathatantwo{\the\pgf@y}{\the\pgf@x}
    \let\tempangle=\pgfmathresult
    % scale in direction \tempangle by #2
    \pgfkeysalso{scale angle direction={\tempangle}{#2}}
  }
}
\makeatother
\begin{document}
  \begin{tikzpicture}
    \draw[red] rectangle (1,1) coordinate (A);
    \draw[scale vector direction={(A)}{2}] rectangle (1,1);
  \end{tikzpicture}
\end{document}

在此处输入图片描述

相关内容