# Uniform line thickness in plot

I have written a very minimal plotting code which take a function $$f$$ and a domain $$[a,b]$$ and plots its graph. (It's here, if relevant.)

Now, I query $$f$$ at the sides of each pixel, and then every vertical pixel in the line gets marked. But this makes an incredibly thin graph unless the pixel density is low. So I want to support variable line thickness.

When the function is constant, this is easy: Just add the requisite number of pixels above and below the correct pixel. However, as $$f'(x) \to \infty$$, that gets weird. You still mark above and below the correct pixel, but then the graph appears thin. Here's an example, which I've made comically thick for emphasis: The function $$\sin(x)$$ is pretty much uniformly thick, but $$1/x$$ gets really thin as $$x\to 0$$, and so does $$\sin(1/x)$$.

What can I do to get these graphs uniformly thick?

If I assume I can use automatic differentiation on $$f$$, does the problem have a more interesting solution?

Note: I tried setting the line thickness at point $$x$$ to $$t(x) = t_{\mathrm{user}}\max(1, |f'(x)|)$$ where $$t_{\mathrm{user}}$$ is the user requested thickness. But of course $$|f'|$$ can diverge, so this did horrible things to the graph. So I did: $$t(x) = t_{\mathrm{user}}\min(\max(1, |f'(x)|), 8)$$ which also looked terrible, though admittedly less terrible than before. But it's just too arbitrary, so asking the hive-mind it is.

Edit: I'm now thinking that the width should be marked along the normal to the tangent, i.e. the line $$y - f(x_i) = -\frac{1}{f'(x_i)} (x-x_i),$$ not along a vertical. So automatic differentiation is required?

Edit 2: You can get the derivative in pixel space via finite differences; that's just fine, and I image cheaper. Then it's Bresenham's line algorithm + some alpha decay with distance from the curve?

• The function sin(x) is pretty much uniformly thick it's not uniform at all, you would notice this better if you used a higher frequency – zoran404 Apr 18 '20 at 14:18
• If I used a higher frequency, I would amplify the derivative, which is precisely the point of the question. – user14717 Apr 18 '20 at 14:39
• I was talking about sin(x) in your screenshot, it's not uniform. The thickness around 0 is around 25% thinner. – zoran404 Apr 18 '20 at 15:07

## 1 Answer

You should separate your line drawing logic from your calculation logic.
In general you should try to have a generic line drawing function that would accept any number of points and draw a line from one point to the next.
The simplest implementation for this would be to have dense points and draw a circle at each point.

If you however absolutely have to calculate the color of a pixel as a function of the X coordinate you'll have to calculate the value multiple times.
Lets say you want thickness of 3 pixels, you will have to calculate this for [X-1, X, X+1] and then check if the current pixel is close to any of the values.
A big downside to this is that you have many duplicate calculations.