Open AndreC75 opened 4 years ago
Please use the issue template and provide a minimal example.
Considering the following mwe:
Brief outline of the bug
In a scaled scope, name intersections={of=...}
used as coordinate/node option creates intersections with wrong coordinates.
Similar question: https://tex.stackexchange.com/questions/218210/rotating-tikzpicture-messes-up-intersections.
Minimal working example (MWE)
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{document}
Faux
\begin{tikzpicture}[scale=0.9]
\draw[name path=aa] (0, 0) -- ++(3, 3);
\draw[name path=bb] (0, 3) -- ++(3, -3);
\coordinate[name intersections={of=aa and bb}] (x);
% or one of
% \path coordinate[name intersections={of=aa and bb}] (x);
% \path node[name intersections={of=aa and bb}] (x) {};
% \node[name intersections={of=aa and bb}] (x) {};
\fill (intersection-1) circle (2pt);
\end{tikzpicture}
Correct
\begin{tikzpicture}[scale=0.9]
\draw[name path=aa] (0, 0) -- ++(3, 3);
\draw[name path=bb] (0, 3) -- ++(3, -3);
\path[name intersections={of=aa and bb}] coordinate (x);
\fill (intersection-1) circle (2pt);
\end{tikzpicture}
\end{document}
Looks like the intersection are calculated in the untransformed system (which makes a lot of sense) but then the transformation is not applied to the result again.
I don't know why but it seems the transformation is applied to intersection coordinates twice.
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage{tikz}
\usetikzlibrary{intersections, scopes}
\begin{document}
\makeatletter
Faux\par
\begin{tikzpicture}[scale=0.9]
\draw[name path=aa] (0, 0) -- ++(3, 3);
\draw[name path=bb] (0, 3) -- ++(3, -3);
\path { coordinate[name intersections={of=aa and bb}] (x)};
% print "macro:->{1.0}{0.0}{0.0}{1.0}{34.5696.pt}{34.5696.pt}"
\node {\expandafter\meaning\csname pgf@sh@nt@intersection-1\endcsname};
\fill (intersection-1) circle (2pt);
\end{tikzpicture}
Attempt\par
\begin{tikzpicture}[scale=0.9]
\draw[name path=aa] (0, 0) -- ++(3, 3);
\draw[name path=bb] (0, 3) -- ++(3, -3);
% added {[reset cm] ...}
\path {[reset cm] coordinate[name intersections={of=aa and bb}] (x)};
% print "macro:->{1.0}{0.0}{0.0}{1.0}{38.41093pt}{38.41093pt}"
\node {\expandafter\meaning\csname pgf@sh@nt@intersection-1\endcsname};
\fill (intersection-1) circle (2pt);
\end{tikzpicture}
Correct\par
\begin{tikzpicture}[scale=0.9]
\draw[name path =aa] (0, 0) -- ++(3, 3);
\draw[name path =bb] (0, 3) -- ++(3, -3);
\path[name intersections={of=aa and bb}] coordinate (x);
% print "macro:->{1.0}{0.0}{0.0}{1.0}{38.41093pt}{38.41093pt}"
\node {\expandafter\meaning\csname pgf@sh@nt@intersection-1\endcsname};
\fill (intersection-1) circle (2pt);
\end{tikzpicture}
\end{document}
Not sure if this is really a fix:
diff --git a/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex b/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex
index cf94f923..ca0e7a1c 100644
--- a/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex
+++ b/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex
@@ -104,7 +104,7 @@
\pgfmathloop%
\ifnum\pgfmathcounter>\pgfintersectionsolutions\relax%
\else%
- \path[reset cm]\pgfextra{\pgftransformshift{\pgfpointintersectionsolution{\pgfmathcounter}}}%
+ \path\pgfextra{\pgftransformshift{\pgfpointintersectionsolution{\pgfmathcounter}}}%
coordinate (\tikz@intersect@@name-\pgfmathcounter);
\repeatpgfmathloop%
\ifx\tikz@intersect@by\pgfutil@empty%
diff --git a/tex/generic/pgf/libraries/pgflibraryintersections.code.tex b/tex/generic/pgf/libraries/pgflibraryintersections.code.tex
index 24571576..c920dbae 100644
--- a/tex/generic/pgf/libraries/pgflibraryintersections.code.tex
+++ b/tex/generic/pgf/libraries/pgflibraryintersections.code.tex
@@ -352,7 +352,9 @@
\pgf@iflinesintersect{#1}{#2}{#3}{#4}%
{%
\pgfextract@process\pgf@intersect@solution@candidate{%
+ \pgftransforminvert
% pgf@x and pgf@y are already assigned by \pgf@iflinesintersect
+ \pgfpointtransformed{\pgfqpoint{\pgf@x}{\pgf@y}}%
}%
\pgf@ifsolution@duplicate{\pgf@intersect@solution@candidate}{%
% ah - we a duplicate. Apparently, we have a hit on an
However, this also fixes the following example:
\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{intersections}
\begin{document}
\def\pathA{%
\pgfpathmoveto{\pgfpointorigin}%
\pgfpathlineto{\pgfqpoint{30pt}{30pt}}%
}
\def\pathB{%
\pgfpathmoveto{\pgfqpoint{0pt}{30pt}}%
\pgfpathlineto{\pgfqpoint{30pt}{0pt}}%
}
\begin{pgfpicture}
\pgftransformscale{0.9}
\pgftransformrotate{30}
\pathA\pgfusepath{stroke}%
\pathB\pgfusepath{stroke}%
\pgfintersectionofpaths\pathA\pathB
\pgfpathcircle{\pgfpointintersectionsolution{1}}{2pt}
\pgfusepath{stroke}%
\end{pgfpicture}
\end{document}
Definitely a candidate for regression. Let's see.
Just a reminder, the corresponding commit https://github.com/hmenke/pgf/commit/5d5b9976fec17668b187d9375b33d1d93b0dc88d to hmenke/pgf has not been merged to pgf-tikz/pgf yet.
This change seems to have broken one of my figures.
Before 3.1.6:
After 3.1.6:
\usetikzlibrary{pgfplots.colorbrewer}
\pgfdeclarelayer{background}%
\pgfsetlayers{background,main}%
\begin{tikzpicture}
[
%rotate=22.5,
segment/.style={arrows={{Circle[length=4pt]}-{Circle[length=4pt]}},very thick},
segments/.style={very thick,mark=*,mark size=(4pt-\pgflinewidth)*0.5},
first/.style={Dark2-A},
second/.style={Dark2-B},
%scale=1.5,
every path/.style={scale=1.25},
declare function={
angle=22.5;
segment_anchor=angle+45;
},
]
\draw[densely dotted,Dark2-A] (0,0) -- +(angle:0.5) coordinate (A);
\draw[segment,first] (A)
node[anchor=-segment_anchor] {\(A\)}
--
%node[sloped,below] {\(l_1\)}
+(angle:1.2)
coordinate (B)
node[anchor=-segment_anchor] {\(B\)}
;
\draw[segment,second]
($(B)+(2.25,0)$) coordinate (C)
% Make sure prime does not produce additiona horizontal space such that the
% anchors of letters with and without a prime are exactly at the same
% position.
node[anchor=180+segment_anchor] {\(B\mathrlap{'}\)}
--
%node[sloped,below] {\(l_2\)}
+(-22.5:1) coordinate (D)
node[anchor=180+segment_anchor] {\(A\mathrlap{'}\)}
;
\draw[densely dotted,second] (D) -- +(-angle:.5) coordinate (E);
\path[name path=BC] (B) -- (angle:5) coordinate (AB ext);
\path[name path=CD] (C) -- +(-angle:-3) coordinate (CD ext);
\path[name intersections={of=BC and CD,by=inter}];
\draw[first,dashed] (B) -- (inter);
\draw[second,dashed] (inter) -- (C);
\colorlet{angle}{Dark2-E}
\draw (D)
let \p1 = ($(C)-(inter)$) in
pic
[
draw=Dark2-C,
pattern=north east lines,
pattern color=Dark2-C,
semithick,
angle radius={0.3*veclen(\x1,\y1)}
]
{angle=B--inter--C}
;
\begin{pgfonlayer}{background}
\draw (B)
let \p1 = ($(inter)-(C)$) in
pic [Dark2-B,draw=.,fill=.!25,angle radius={0.3*veclen(\x1,\y1)}]
{angle=B--C--D}
;
\draw (inter)
let \p1 = ($(inter)-(B)$) in
pic [Dark2-A,draw=.,fill=.!25,angle radius={0.3*veclen(\x1,\y1)}]
{angle=A--B--C}
;
\end{pgfonlayer}
\draw[dashed] (B) -- (C);
\begin{scope}[outer sep=.25ex]
\node[Dark2-A,anchor=90+angle/2] at (B) {\(\alpha_1\)};
\node[Dark2-B,anchor=90-angle/2] at (C) {\(\alpha_2\)};
\node[anchor=south,Dark2-C] at (inter) {\(\alpha_3\)};
\end{scope}
% The intersection of extended lines
\draw[mark=x,very thick,Dark2-H,scale=1.5] plot coordinates {(inter)};
\end{tikzpicture}
@sergiud Make a new issue. I'll revert and push a hotfix.
Also, even though in this case it is sort of clear what's the issue, please always provide a minimal working example.
@hmenke Done (#929).
There are actually two sub-issues: (transformation matrix is denoted by T
below and assuming T
is not the identity matrix)
\pgfintersectionofpaths
works as expected but every use of \pgfpointintersectionsolution{<num>}
gives wrong position (caused by T
applied twice).name intersections
is used as node options, the generated coordinates intersections-<num>
has wrong positions (caused by T
applied twice).When using pgf, the T
is firstly applied in \pgfintersectionofpaths
(implementation) and then in any path construction commands that process \pgfpointintersectionsolution{<num>}
as a point.
My proposal is to prefix \pgftransformreset
to \pgfpointintersectionsolution
:
diff --git a/tex/generic/pgf/libraries/pgflibraryintersections.code.tex b/tex/generic/pgf/libraries/pgflibraryintersections.code.tex
index 24571576..a398e063 100644
--- a/tex/generic/pgf/libraries/pgflibraryintersections.code.tex
+++ b/tex/generic/pgf/libraries/pgflibraryintersections.code.tex
@@ -37,6 +37,7 @@
\ifnum#1>\pgfintersectionsolutions\relax%
\pgfpoint@intersect@solution@orgin%
\else%
+ \pgftransformreset
\csname pgfpoint@intersect@solution@#1\endcsname%
\fi%
\fi%
In front layer (using tikz), name path=<name>
stores collected soft path to <name>
, hence the fix for pgf
doesn't work. In this case, T
is firstly applied when generating the soft path, and then in line \path[reset cm] \pgfextra{...} coordinate (...);
in the definition of use intersections
.
Since reset cm
will only reset T
immediately when \tikz@transform
is \relax
, and node sets \tikz@transform
to \pgfutil@empty
at beginning, when used as node options, the above reset cm
will not reset T
.
My proposal is to directly use \pgftransformreset
:
diff --git a/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex b/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex
index cf94f923..dfd38f03 100644
--- a/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex
+++ b/tex/generic/pgf/frontendlayer/tikz/libraries/tikzlibraryintersections.code.tex
@@ -104,7 +104,7 @@
\pgfmathloop%
\ifnum\pgfmathcounter>\pgfintersectionsolutions\relax%
\else%
- \path[reset cm]\pgfextra{\pgftransformshift{\pgfpointintersectionsolution{\pgfmathcounter}}}%
+ \path\pgfextra{\pgftransformreset\pgftransformshift{\pgfpointintersectionsolution{\pgfmathcounter}}}%
coordinate (\tikz@intersect@@name-\pgfmathcounter);
\repeatpgfmathloop%
\ifx\tikz@intersect@by\pgfutil@empty%
I will report the \tikz@transform
problem in another issue (see #963 ), and when it is fixed the tikz layer of current issue would be auto fixed.
The problem is explained here: How to make so that the calculation of an intersection is correct during a change of scale?