Bearbeiten:Wie in der Antwort von percusse vorgeschlagen, kann ich transform shape
die Option verwenden. Meine erste Frage ist jetzt gelöst. Aber obwohl der zweite Begrenzungsrahmen jetzt lokal ausgerichtet ist, ist dies nicht korrekt. Tatsächlich local bounding box
berechnet immer einglobalausgerichteter Begrenzungsrahmen (grüne Punkte) und fit
umschließt north
, east
, south
, und west
Anker dieses Begrenzungsrahmens.
Meine Frage ist nun: Wie berechnet man einelocal bounding box
örtlichausgerichtet?
Neues Beispiel (das blaue Rechteck rechts passt nicht zum roten Pfad):
\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}
Ursprüngliche Frage:
Ich möchte einige Begrenzungsrahmen berechnen. Hier sind meine beiden Fälle:
- um einige Knoten (oder Koordinaten) anzupassen, kann ich
fit
die Bibliothek verwenden. - Um beliebige Pfade anzupassen, kann ich einen Bereich mit verwenden
local bounding box=bb
.
Der folgende Code zeigt diese beiden Fälle:
\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}
Jetzt möchte ich die gleichen Dinge macheninnerhalb eines gedrehten Bildes!
Meine zwei Fragen:
In meinem ersten Fall (einige Knoten) muss ich
rotate
meinem passenden Knoten eine Option hinzufügen (darotate
die Option die Knoten nicht rotiert).Wie findet man automatisch den richtigen Wert für diese Option (z. B. den Winkel zwischen dem aktuellen Koordinatensystem und dem Canvas-Koordinatensystem)?In meinem zweiten Fall (beliebige Pfade) kann ich lokale, aber global ausgerichtete Begrenzungsrahmen berechnen.Wie berechnet man eine lokale Begrenzungsbox, die lokal an einem beliebigen Pfad ausgerichtet ist?
Hier ist mein Versuch:
\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}
Antwort1
Habe ich den Punkt nicht verstanden? transform shape
Das Zurücksetzen der Rotation scheint eine Lösung zu sein.
EDIT: Ich hoffe, ich habe Ihren Standpunkt diesmal verstanden. Wenn nicht, wäre ich Ihnen sehr dankbar, wenn Sie es anhand von gedrehten Rechtecken und Formen erklären könnten, anstattlokalUndweltweitDabei handelt es sich um eine relative Terminologie in Bezug auf die gedrehte Tikz-Bildumgebung.
\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}
Antwort2
Notiz:Ich habe schließlich selbst eine Lösung gefunden ... aber ich kann mir nicht selbst eine Prämie geben. ;-)
Ich definiere drei Stile:
memoize points
benennt jeden Punkt eines Pfades (mithilfe einesmemoizepoints
Zählers) und kumuliert diese Namen in einem globalen Makro (seinem Argument).cont memoize points
ist dasselbe wiememoize points
, aber ohne das globale Makro (sein Argument) zurückzusetzen.init memoize points
setzt das globale Makro (sein Argument) und denmemoizepoints
Zähler zurück.
Hier ist die Präambel:
\documentclass{standalone}
\usepackage{tikz}
\usetikzlibrary{fit,intersections,decorations.pathreplacing,decorations.markings}
Der memoizepoints
Zähler und die drei Stile:
\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},
}
Anschließend ein Beispiel mit nachfolgendem Code:
\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}