pgf-tikz / pgf

A Portable Graphic Format for TeX
https://pgf-tikz.github.io/
1.15k stars 109 forks source link

The `smooth` algorithm uses incorrect proportionate constant `0.2775` #1150

Open RuixiZhang42 opened 2 years ago

RuixiZhang42 commented 2 years ago

Brief outline of the bug

The smooth algorithm for plot uses a proportionate constant for the distance between control points, so that—when tension=1—four evenly spaced points on a circle will produce a closed path approximating the circle.

According to pgflibraryplothandlers.code.tex, this proportionate constant is 0.2775. But this is the wrong value. The correct value should be half of 4*(sqrt(2)-1)/3, or 0.27614.

Also, the manual says the default tension is 0.55. This is also wrong. The default is tension=0.5.

Reference:

Minimal working example (MWE)

\documentclass{article}
\usepackage{tikz}
\begin{document}

\begin{tikzpicture}
\draw[thick,red] (0,0) circle (1);
\draw plot[smooth cycle,tension=1] coordinates {(1,0) (0,1) (-1,0) (0,-1)};
\end{tikzpicture}

\makeatletter
\def\pgfsetplottension#1{%
  \pgf@x=#1pt\relax%
%  \pgf@x=0.2775\pgf@x\relax% <- This should not be 0.2775
  \pgf@x=0.27614\pgf@x\relax%
  \edef\pgf@plottension{\pgf@sys@tonumber\pgf@x}}%
\makeatother

\begin{tikzpicture}
\draw[thick,red] (0,0) circle (1);
\draw plot[smooth cycle,tension=1] coordinates {(1,0) (0,1) (-1,0) (0,-1)};
\end{tikzpicture}

\end{document}
RuixiZhang42 commented 2 years ago

Outputs at 1708.59% zoom:

wrongconst Wrong constant 0.2775

correctconst Correct constant 0.27614

hmenke commented 2 years ago

Outputs at 1708.59% zoom:

TeX documents are intended for print publishing. I doubt that this is visible in print.

Possibly related: https://github.com/pgf-tikz/pgf/issues/817

RuixiZhang42 commented 2 years ago

TeX documents are intended for print publishing.

Well, the largest circle TeX can handle has a radius of 8191.99999pt (or about 113.353in, 287.916cm). The circle in the MWE has a radius of 1cm. The “zoom” can theoretically go up to 28791.6% (thus, the 1708.59% zoom is only 6% of the largest theoretical zoom).

Besides, we use TeX to produce posters for presenting our scholar projects. These posters easily measure 1.5m–2m wide. A 1cm-radius circle at 1708.59% zoom is just a 17cm-radius circle, which is of reasonable size in a poster.

I doubt that this is visible in print.

The point here is about the out-of-no-where (and wrong) constant 0.2775.

If the difference is barely visible, would you rather leave an uncommented wrong value in the code? Or, because the difference is barely visible, we can take this opportunity to correct the value to 0.27614.

ilayn commented 2 years ago

It's not out-of-nowhere. You are basically using the wrong tool for circles. The idea for smooth is to soften jagged lines not drawing circles. This is made very clear in the manual. For circles, PDF specification has already a solution and ellipses are native objects.

This is only one obscure use case. The option smooth is 100% for visually pleasing drawings not technically accurate transformations. This is especially true for plotting. If you need a smooth plot use parametric expressions.

You don't need to scale the picture to print on a poster. That's the whole idea behind vector graphics.

RuixiZhang42 commented 2 years ago

@ilayn

This is made very clear in the manual.

Oh, the manual. The manual describes the key /tikz/tension as follows (highlights are mine):

The value 0.2775 is in direct conflict with what is “very clear” in the manual, which is the reason for me to open this issue. Furthermore, there are no comments on why 0.2775 was hard-coded there, where the value 0.27614 should have been used.

Moreover, as shown in https://github.com/pgf-tikz/pgf/issues/817, in another place of the TikZ code you are using 0.55228475, which is twice of 0.27614. So why 0.2775 in the first place, and why sticking with it?

You can are welcome to argue to keep 0.2775 for the sake of backward compatibility, but please at least acknowledge that 0.2775 does not give a good approximation (especially when you are using the equivalent of 0.27614 somewhere else in the core code).

ilayn commented 2 years ago

I already gave you an explanation and I am not trying to be right, frankly the difference is so tiny I don't even get why you are passionate about it. If you don't want to have an open discussion and already made up your mind then fine modify your values in the preamble and carry on.

Otherwise try on some jagged lines and get a feeling what the differences are. And then MAYBE! the author of that code decided to tweak the values to make it more pleasing instead of being correct. But instead we are discussing some circle is not fitting. Yes it is not fitting. Why are you drawing circles with smooth in the first place?

ilayn commented 2 years ago

What part of this sentence is not clear

image

RuixiZhang42 commented 2 years ago

@ilayn But you didn’t give an explanation on the number 0.2775 and why it’s not out-of-nowhere. Instead, you give an explanation why smooth is not quite the right tool to draw circles (which I didn’t oppose). You then explain that the manual is clear and one should try to follow the advise of the manual.

My counter argument points out that the manual is not a reliable source, because the manual says “a [tension] value of 1 results in a circle”.

Your screenshot with the big pointy arrow reflects my counter argument precisely. In order to generate a circle (aka, “depends on the details of plot”), I have to say tension=0.995099 (aka, “the ‘correct’ value”). But this directly contradicts the manual itself where it says tension=1 is for such task.

Do you see the problem now? Which part of my last paragraph is not clear? And why accusing me of not wanting an open discussion, where I merely presented a counter argument about the problematic conflicting 0.2775+tension=0.995099 versus 0.27614+tension=1? The rest of my counter argument points out that 0.27614 (or rather, it’s doubled value) is already in use in other pieces of the core code. This makes the uncommented 0.2775 more questionable.

And there is no need for all caps (I think we’d agree that there’s no need to shout).

ilayn commented 2 years ago

I already asked twice try it on ragged line. That's one thing you don't do. Second, I am trying to tell you a tweak does not require an explanation. If the number is wrong up-to-uselessness then we fix it. Ask yourself the same question, why is it the "correct" values elsewhere but only here it is different. Otherwise you are just geeking out on a detail that I really don't care. You made up your mind so this is not going anywhere. I'll leave it to others to handle this.

RuixiZhang42 commented 2 years ago

@ilayn

Otherwise you are just geeking out on a detail that I really don't care. You made up your mind so this is not going anywhere.

Maybe I’m reading too much into all of your comments and maybe I’m wrong. But I get the vibe that it is you who have made up your mind, that you don’t care about conflicting manual descriptions and code implementations. Yet you are the one accusing me “[not] want to have an open discussion and already made up [my] mind”.

This issue opens with “manual says tension=1 gives a circle; but due to 0.2775 the output deviates from the circle”. This issue is never about using the smooth key on jagged lines, so I genuinely don’t understand your insistence here. I agree that it is pointless to continue this off-topic discussion of yours.

In hindsight, I should’ve provided a more “realistic use” to illustrate the deviation, instead of a simple “~1700% zoom”. So when @hmenke comments on “TeX used for prints”, I responded with “such deviation can appear in prints (e.g., in posters) with a reasonably large radius”. For some reasons, the conversation then drifted into something else.