Как вычислить повернутые ограничивающие рамки?

Как вычислить повернутые ограничивающие рамки?

Редактировать:Как предполагает ответ percusse, я могу использовать transform shapeoption. Мой первый вопрос теперь решен. Но хотя второй ограничивающий прямоугольник теперь локально выровнен, это не правильно. Фактически, local bounding boxвсегда вычисляетглобальновыровненный ограничивающий прямоугольник (зеленые точки) и fitвключает в себя north, east, south, и westякоря этого ограничивающего прямоугольника.

Мой вопрос теперь: как вычислитьlocal bounding box локальновыровнены?

Новый пример (синий прямоугольник справа не вписывается в красную дорожку):

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\tikzset{
  pt/.style={circle,minimum size=3pt,fill=#1,inner sep=0},
  red pt/.style={pt=red},
  green pt/.style={pt=green},
  every picture/.style={line width=1pt,inner sep=0pt},
}
\begin{document}
\begin{tikzpicture}[rotate=20]
  \draw[gray,line width=.4pt] (0,0) grid (6.5,2.5);
  % first case: fitting some nodes
  \node[red pt] (a) at (.5,.5){};
  \node[red pt] (b) at (.5,2){};
  \node[red pt] (c) at (3,.5){};
  \node[red pt] (d) at (2,2.2){};
  \begin{scope}[transform shape]
    \node[fit=(a)(b)(c)(d),draw=blue]{};
  \end{scope}

  % second case: fitting arbitrary path
  \begin{scope}[local bounding box=bb]
    \draw[red] (4,1) to[bend right] (6,1) -- (5,2);
  \end{scope}
  \node[green pt] at (bb.north west){};
  \node[green pt] at (bb.north east){};
  \node[green pt] at (bb.south west){};
  \node[green pt] at (bb.south east){};
  % how to find correct bounding box locally aligned ?
  \begin{scope}[transform shape]
    \node[fit=(bb),draw=blue]{};
  \end{scope}
\end{tikzpicture}
\end{document}

введите описание изображения здесь

Исходный вопрос:

Я хочу вычислить некоторые ограничивающие рамки. Вот мои два случая:

  1. Чтобы подогнать некоторые узлы (или координаты), я могу использовать fitбиблиотеку.
  2. Чтобы подогнать произвольные пути, я могу использовать область действия с local bounding box=bb.

Следующий код демонстрирует эти два случая:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\tikzset{
  red pt/.style={circle,minimum size=3pt,fill=red,inner sep=0},
  every picture/.style={line width=1pt,inner sep=0pt},
}
\begin{document}
\begin{tikzpicture}
  \draw[gray,line width=.4pt] (0,0) grid (6.5,2.5);
  % first case: fitting some nodes
  \node[red pt] (a) at (.5,.5){};
  \node[red pt] (b) at (.5,2){};
  \node[red pt] (c) at (3,.5){};
  \node[red pt] (d) at (2,2.2){};
  \node[fit=(a)(b)(c)(d),draw=blue]{};

  % second case: fitting arbitrary path
  \begin{scope}[local bounding box=bb]
    \draw[red] (4,1) to[bend right] (6,1) -- (5,2);
  \end{scope}
  \node[fit=(bb),draw=blue]{};
\end{tikzpicture}

введите описание изображения здесь

Теперь я хочу сделать то же самое.внутри повернутого изображения!

У меня два вопроса:

  1. В моем первом случае (некоторые узлы) мне нужно добавить rotateопцию к моему узлу подгонки (так как rotateопция не вращает узлы).Как автоматически найти правильное значение для этой опции (например, угол между текущей системой координат и системой координат холста)?

  2. Во втором случае (произвольные пути) я могу вычислить локальный ограничивающий прямоугольник, но выровненный глобально.Как вычислить локальный ограничивающий прямоугольник, локально выровненный по произвольному пути?

Вот моя попытка:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}
\tikzset{
  red pt/.style={circle,minimum size=3pt,fill=red,inner sep=0},
  every picture/.style={line width=1pt,inner sep=0pt},
}
\begin{document}
\begin{tikzpicture}[rotate=20]
  \draw[gray,line width=.4pt] (0,0) grid (6.5,2.5);
  % first case: fitting some nodes
  \node[red pt] (a) at (.5,.5){};
  \node[red pt] (b) at (.5,2){};
  \node[red pt] (c) at (3,.5){};
  \node[red pt] (d) at (2,2.2){};
  % how to find the good value for rotate (here 20)?
  \node[rotate=20,fit=(a)(b)(c)(d),draw=blue]{};

  % second case: fitting arbitrary path
  \begin{scope}[local bounding box=bb]
    \draw[red] (4,1) to[bend right] (6,1) -- (5,2);
  \end{scope}
  % how to find bounding box locally aligned ?
  \node[rotate=20,rotate fit=-20,fit=(bb),draw=blue]{};
\end{tikzpicture}
\end{document}

введите описание изображения здесь

решение1

Я упускаю суть? transform shapeИ сброс ротации кажется решением.


EDIT: Надеюсь, на этот раз я понял вашу точку зрения. Если нет, я был бы очень признателен, если бы вы объяснили это в терминах повернутых прямоугольников и фигур, а неместныйиГлобальныйкоторые являются относительной терминологией по отношению к повернутой среде изображения Tikz.

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit}

\tikzset{
  pt/.style={circle,minimum size=3pt,fill=#1,inner sep=0},
  red pt/.style={pt=red},
  green pt/.style={pt=green},
  every picture/.style={line width=1pt,inner sep=0pt},
}
\begin{document}
\begin{tikzpicture}[rotate=20]
  \draw[gray,line width=.4pt] (0,0) grid (6.5,2.5);
  % first case: fitting some nodes
  \node[red pt] (a) at (.5,.5){};
  \node[red pt] (b) at (.5,2){};
  \node[red pt] (c) at (3,.5){};
  \node[red pt] (d) at (2,2.2){};
  \begin{scope}[transform shape]
    \node[fit=(a)(b)(c)(d),draw=blue]{};
  \end{scope}
\pgfgettransform{\currtrafo}     %Save the current trafo 

  % second case: fitting arbitrary path
\begin{scope}[local bounding box=bb]
\pgftransformresetnontranslations % Now there is no rotation and it doesn't know 
                                  % things are going to be rotated
\begin{scope}                     % We open a new scope and restore the outer trafo
\pgfsettransform{\currtrafo}      % inside the scope

\draw[red] (4,1) to[bend right] (6,1) -- (5,2);  % Draw anything
\end{scope}                                      % Now the trafo is reset again

\node[fit=(bb),draw=blue]{};     % Externally it doesn't know the content is
                                 % rotated or not

  \end{scope}                    % Back to original trafo.
\end{tikzpicture}
\end{document}

введите описание изображения здесь

решение2

Примечание:Я наконец-то сам нашел решение... но я не могу дать себе свою собственную награду. ;-)

Я выделяю три стиля:

  1. memoize pointsприсваивает имя каждой точке пути (с помощью memoizepointsсчетчика) и объединяет эти имена в глобальный макрос (его аргумент).

  2. cont memoize pointsто же самое, что и memoize points, но без сброса глобального макроса (его аргумента).

  3. init memoize pointsсбрасывает глобальный макрос (его аргумент) и memoizepointsсчетчик.

Вот преамбула:

\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit,intersections,decorations.pathreplacing,decorations.markings}

Счетчик memoizepointsи три стиля:

\newcounter{memoizepoints}
\tikzset{
  init memoize points/.code={\xdef#1{}\setcounter{memoizepoints}{0}},  
  cont memoize points/.style={postaction={
      decorate,decoration={show path construction,
        moveto code={},
        lineto code={
          \foreach \coord in {\tikzinputsegmentfirst,\tikzinputsegmentlast}{
            \addtocounter{memoizepoints}{1}
            \coordinate(memoizepoints-\arabic{memoizepoints}) at (\coord);
            \xdef#1{#1 (memoizepoints-\arabic{memoizepoints})}
          }
        },
        curveto code={
          \foreach \coord in {\tikzinputsegmentfirst,\tikzinputsegmentsupporta,%
            \tikzinputsegmentsupportb,\tikzinputsegmentlast}{
            \addtocounter{memoizepoints}{1}
            \coordinate(memoizepoints-\arabic{memoizepoints}) at (\coord);
            \xdef#1{#1 (memoizepoints-\arabic{memoizepoints})}
          }
        },
        closepath code={
          \foreach \coord in {\tikzinputsegmentfirst,\tikzinputsegmentlast}{
            \addtocounter{memoizepoints}{1}
            \coordinate(memoizepoints-\arabic{memoizepoints}) at (\coord);
            \xdef#1{#1 (memoizepoints-\arabic{memoizepoints})}
          }
        },
      },
    },
  },
  memoize points/.style={init memoize points=#1,cont memoize points=#1},
}

Затем следует пример с его кодом:

введите описание изображения здесь

\begin{document}
\begin{tikzpicture}[rotate=30,inner sep=0pt,line width=1pt]
  \tikzset{
    pt/.style={circle,minimum size=3pt,fill=#1,inner sep=0},
    red pt/.style={pt=red},
  }
  \draw[gray,line width=.4pt] (0,0) grid (9.5,5.5);
  % first case: fitting some nodes
  \node[red pt] (a) at (.5,.5){};
  \node[red pt] (b) at (.5,2){};
  \node[red pt] (c) at (3,.5){};
  \node[red pt] (d) at (2,2.2){};
  \begin{scope}[transform shape]
    \node[fit=(a)(b)(c)(d),draw=blue]{};
  \end{scope}

  % second case: fitting arbitrary path
  \draw[red,memoize points=\allpoints] (4,1) to[bend right] (6,1) -- (5,2);
  \begin{scope}[transform shape]
    \node[fit=\allpoints,draw=blue]{};
  \end{scope}

  % another example of fitting arbitrary path
  \draw[red,memoize points=\allpoints] (8,1.2) circle ();
  \begin{scope}[transform shape]
    \node[fit=\allpoints,draw=blue]{};
  \end{scope}

  % another example of fitting arbitrary paths
  \begin{scope}[yshift=2cm]
    \draw[red,memoize points=\allpoints]
    plot[domain=4:8,samples=100] (\x,{2+sin(3 * \x r)});
    \draw[red,cont memoize points=\allpoints]
    plot[domain=4:8,samples=100] (\x,{2.1+cos(3 * \x r)});
  \end{scope}
  \begin{scope}[transform shape]
    \node[fit=\allpoints,draw=blue]{};
  \end{scope}
\end{tikzpicture}

Связанный контент