-
Notifications
You must be signed in to change notification settings - Fork 109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
bbox's bounding box too small and arrow tips cut off #856
Comments
Thanks for the report! Yes, there is a problem due to the fact that arrow heads are also curves. One has to switch off the Bezier bounding box for them. I am on it. |
@hmenke Do you know a way to find out whether or not a given path is a path inside an arrow head? (Or, alternatively, is there a way to tell all arrow head paths to set the |
@MdAyquassar The bounding box becomes correct if you just load the
However, the arrow head problem remains a problem, (And I wanted to rewrite the library anyway to make it cleaner and more accurate.) |
@tallmarmot Thanks for letting me know. Do you mean loading bending before loading bbox, after it, instead of it, or do you mean something else? Yes, I'd welcome bug-fixing, thank you for being on it. (Each time I include one more library or one more package, the chances, that something else breaks inside the huge book I'm editing, get higher.) |
@MdAyquassar You need to load both, the order does not matter. I agree that the current version of |
@MdAyquassar Add the following file to the directory you are compiling in: \usepgflibrary{fpu}
\global\let\pgf@bbox@lt@curveto@normal\pgf@lt@curveto
\global\let\pgf@bbox@nlt@curveto@normal\pgf@nlt@curveto
\pgfqkeys{/pgf}{bezier bounding box/.is if=pgf@bbox@switch@}
\def\pgf@bbox@switch@false{%
\let\pgf@lt@curveto \pgf@bbox@lt@curveto@normal
\let\pgf@nlt@curveto\pgf@bbox@nlt@curveto@normal
}
\def\pgf@bbox@switch@true{%
\let\pgf@lt@curveto \pgf@bbox@curveto
\let\pgf@nlt@curveto\pgf@bbox@curveto
}
\def\pgf@bbox@curveto#1#2#3#4#5#6{%
\begingroup
\pgfkeys{/pgf/fpu,/pgf/fpu/output format=fixed}%
% extrema in x
% first discriminant d1, must be \ne 0
%\typeout{x0=\the\pgf@path@lastx,xa=\the#1,xb=\the#3,x1=\the#5}%
\pgfmathsetmacro{\pgf@temp@a}{(\pgf@path@lastx)-(#5)-3*(#1)+3*(#3)}%
%\typeout{d1=\pgf@temp@a}%
\pgfmathtruncatemacro{\pgf@temp@c}{(abs(\pgf@temp@a)>0.1?1:0)}%
\ifnum\pgf@temp@c=1\relax
% second discriminant d2, must be \ge 0
\pgfmathsetmacro{\pgf@temp@b}{(\pgf@path@lastx)*(#5)-(#5)*(#1)+(#1)*(#1)-(\pgf@path@lastx)*(#3)-(#1)*(#3)+(#3)*(#3)}%
\pgfmathtruncatemacro{\pgf@temp@c}{sign(\pgf@temp@b)}%
%\typeout{d2=\pgf@temp@b}%
\ifnum\pgf@temp@c<0
\else
\pgfmathsetmacro{\pgf@temp@b}{sqrt(abs(\pgf@temp@b))}%
\pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((\pgf@path@lastx)-2*(#1)+(#3)-\pgf@temp@b)/\pgf@temp@a))}%
%\typeout{t1=\pgf@temp@c}%
\pgfmathparse{(\pgf@path@lastx)*pow((1-\pgf@temp@c),3)+3*(#1)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#3)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#5)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
\pgfutil@tempdimb=\pgfmathresult pt\relax%
\pgf@protocolsizes{\pgfutil@tempdimb}{\pgf@path@lasty}%
\pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((\pgf@path@lastx)-2*(#1)+(#3)+\pgf@temp@b)/\pgf@temp@a))}%
%\typeout{t2=\pgf@temp@c}%
\pgfmathparse{(\pgf@path@lastx)*pow((1-\pgf@temp@c),3)+3*(#1)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#3)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#5)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
\pgfutil@tempdimb=\pgfmathresult pt\relax%
\pgf@protocolsizes{\pgfutil@tempdimb}{\pgf@path@lasty}%
\fi
\else
% third discriminant d3, must be \ne 0
\pgfmathsetmacro{\pgf@temp@b}{abs((#5)+(#1)-2*(#3))}%
\ifdim\pgf@temp@b pt<0.1pt\relax
\else
\pgfmathsetmacro{\pgf@temp@c}{((#5)+2*(#1)-3*(#3))/((#5)+(#1)-2*(#3))}%
%\typeout{t3=\pgf@temp@c}%
\pgfmathparse{(\pgf@path@lastx)*pow((1-\pgf@temp@c),3)+3*(#1)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#3)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#5)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
\pgfutil@tempdimb=\pgfmathresult pt\relax%
\pgf@protocolsizes{\pgfutil@tempdimb}{\pgf@path@lasty}%
\fi
\fi
%
% y code
% first discriminant d1, must be \ne 0
%\typeout{y0=\the\pgf@path@lasty,ya=\the#2,yb=\the#4,y1=\the#6}%
\pgfmathsetmacro{\pgf@temp@a}{(\pgf@path@lasty)-(#6)-3*(#2)+3*(#4)}%
%\typeout{d1=\pgf@temp@a}%
\pgfmathtruncatemacro{\pgf@temp@c}{(abs(\pgf@temp@a)>0.1?1:0)}%
\ifnum\pgf@temp@c=1\relax
% second discriminant d2, must be \ge 0
\pgfmathsetmacro{\pgf@temp@b}{(\pgf@path@lasty)*(#6)-(#6)*(#2)+(#2)*(#2)-(\pgf@path@lasty)*(#4)-(#2)*(#4)+(#4)*(#4)}%
\pgfmathtruncatemacro{\pgf@temp@c}{sign(\pgf@temp@b)}%
%\typeout{d2=\pgf@temp@b}%
\ifnum\pgf@temp@c<0
\else
\pgfmathsetmacro{\pgf@temp@b}{sqrt(abs(\pgf@temp@b))}%
\pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((\pgf@path@lasty)-2*(#2)+(#4)-\pgf@temp@b)/\pgf@temp@a))}%
%\typeout{t1=\pgf@temp@c}%
\pgfmathparse{(\pgf@path@lasty)*pow((1-\pgf@temp@c),3)+3*(#2)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#4)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#6)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
\pgfutil@tempdimb=\pgfmathresult pt\relax%
\pgf@protocolsizes{\pgf@path@lastx}{\pgfutil@tempdimb}%
\pgfmathsetmacro{\pgf@temp@c}{max(0,min(1,((\pgf@path@lasty)-2*(#2)+(#4)+\pgf@temp@b)/\pgf@temp@a))}%
%\typeout{t2=\pgf@temp@c}%
\pgfmathparse{(\pgf@path@lasty)*pow((1-\pgf@temp@c),3)+3*(#2)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#4)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#6)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
\pgfutil@tempdimb=\pgfmathresult pt\relax%
\pgf@protocolsizes{\pgf@path@lastx}{\pgfutil@tempdimb}%
\fi
\else
% third discriminant d3, must be \ne 0
\pgfmathsetmacro{\pgf@temp@b}{abs((#6)+(#2)-2*(#4))}%
\ifdim\pgf@temp@b pt<0.1pt\relax
\else
\pgfmathsetmacro{\pgf@temp@c}{((#6)+2*(#2)-3*(#4))/((#6)+(#2)-2*(#4))}%
%\typeout{t3=\pgf@temp@c}%
\pgfmathparse{(\pgf@path@lasty)*pow((1-\pgf@temp@c),3)+3*(#2)*pow((1-\pgf@temp@c),2)*\pgf@temp@c+3*(#4)*(1-\pgf@temp@c)*\pgf@temp@c*\pgf@temp@c+(#6)*\pgf@temp@c*\pgf@temp@c*\pgf@temp@c}%
\pgfutil@tempdimb=\pgfmathresult pt\relax%
\pgf@protocolsizes{\pgf@path@lastx}{\pgfutil@tempdimb}%
\fi
\fi
%
\pgf@protocolsizes{\pgf@path@lastx}{\pgf@path@lasty}%
\pgf@protocolsizes{#5}{#6}%
\endgroup
\pgfsyssoftpath@curveto{\the#1}{\the#2}{\the#3}{\the#4}{\the#5}{\the#6}%
}
\endinput and call it \documentclass{article}
\pagestyle{empty}
\usepackage{tikz}
\usetikzlibrary{bbox,positioning,calc,bending}
\begin{document}
\noindent
\begin{tikzpicture}[%
atomicNode/.style={rectangle,draw,minimum width=4em,minimum height=4em}]
\node[atomicNode] (upper) {};
\node[atomicNode,below=of upper] (lower) {};
\coordinate (zUpper) at ($(upper.north west)!.75!(upper.south west)$);
\coordinate (yUpper) at (upper.east);
\coordinate (zLower) at ($(lower.north east)!.25!(lower.south east)$);
\coordinate (yLower) at (lower.west);
\begin{scope}[bezier bounding box=true]
\draw[-latex] (yUpper) .. controls ($(yUpper)+(13em,0)$) and ($(yLower)-(13em,0)$) .. (yLower);
\draw[-latex] (zLower) .. controls ($(zLower)+(13em,0)$) and ($(zUpper)-(13em,0)$) .. (zUpper);
\end{scope}
\draw (current bounding box.north west) rectangle (current bounding box.south east);
\end{tikzpicture}
\end{document} should give you |
@tallmarmot You are the hero of the day. Thanks a lot! |
This is not yet fixed upstream. |
@hmenke Of course not. The most important question before changing the code in the actual pgf distribution is what one should do with the |
In the example, I don't understand what restricting the scope is good for. I don't see any difference between turning bezier bounding box on only locally and for the whole TikZ picture. |
@MdAyquassar In a perfect world one should be able to set the |
Just like in any other programming language you have to handle 0/0 cases manually, like if numerator == 0 and denominator == 0 then
perform l'Hospital's rule
else
numerator / denominator It is not possible to handle this in, say |
@MdAyquassar @hmenke The current version of the library is at https://github.com/tallmarmot/pgf/tree/master/experiments/Marmot/bbox. I ran a rather large sample of tests. So far so good. There can be |
You haven't really changed the entire library code, haven't you? I would be much happier if you could submit a sane patch as a pull request or via email. |
@hmenke At this point I have changed the whole library in the local experiments folder. I have not touched the "real" library in the pgf system, also because I do not know how to do that, but more importantly because I wanted to do more tests and see if anyone finds issues. Sadly, I do not know what a "sane patch" is. To me the whole GitHub saga is extremely counter intuitive and I know barely the commands that allow me to update the stuff in the experiment folder. (I have accepted the fact that I have to "add" a file to update it, but I find it extremely counter intuitive, so it is very hard for me to do more than that.) |
I think it is easier to communicate patches by email. I've sent you a message. |
@hmenke I have not received any patch via my main e-mail address, so, I think you wanted this to go to tallmarmot only (use the symbol @ ) . Or should I search in any of a dozen or so mailboxes of mine? |
@hmenke , @Mo-Gul : I see @tallmarmot gone. Sigh. The latest version of pgflibrarybbox.code.tex in TeXLive is from 2019 according to http://www.tug.org/texlive/Contents/live/texmf-dist/tex/generic/pgf/libraries/. With that old version, the arrow tips are still cut off. So, purely technically, this bug is not fixed (at least, not fully fixed) yet in TeXLive, somewhat contradicting to the "closed-fixed" status. Would it be possible to push any better version into TeXLive? (Yes, I read that the code is imperfect.) |
@MdAyquassar Check |
@muzimuzhi Oh, thanks, I completely missed all these developments! Will check it out in short. |
Feeding the code
to
pdflatex
results inBUGS:
Bugfixing would be very much appreciated.
The text was updated successfully, but these errors were encountered: