Is it possible to create vector graphics with latex or an external program that allows the usage of more or less arbitrary functions (other than beziers and standard shapes like circles etc) to define shapes?

It would, for example, to actually use the function Y=sin(1/x) instead of having to use piecewise linear functions with finite steps. Of course the functions has to be evaluated for presentation on screen/printer, but then the steps could be adjusted to the given resolution.

If its impossible, is there a limitation in the PDF/PostScript specification that prevents it or why isn't it possible?

  • 1
    For arbitrary functions, I am unaware of such a feature in pdf. Perhaps in postscript? Why is it insufficient to interpolate your shape using (lots of!) cubic polynomials (the highest degree of smoothness which is supported by pdf)? Note that x^2 can be represented exactly by a cubic polynomial without interpolation errors. – Christian Feuersänger Mar 3 '13 at 16:04
  • @ChristianFeuersänger Perhaps x^2 was a poorly chosen example. I'll edit it to sin(1/x). That function will always be represented poorly if one uses piecewise linear functions of you look close enough. – Hugo Mar 3 '13 at 16:14
  • Either you use Bézier curves or plot points; I don't think that any software that represents curves uses linear functions, but rather approximates them with Bézier curves. As far as the function sin(1/x) is concerned, it's impossible to represent it in the vicinity of 0, for any software in whatsoever fashion. – egreg Mar 3 '13 at 16:56
  • 1
    With the current PDF specifications you don't need a holistic representation. Vector graphics inherently assumes a certain detail negligence down to pixel size. For general purposes, sin(1/x) is certainly possible to draw sufficiently realistic. Otherwise you need to use a CAS which TeX is certainly not. Try this \begin{tikzpicture}\begin{axis}\addplot[domain=-0.01:0.01,samples=6000] {sin(1/x)};\end{axis}\end{tikzpicture}. The sensitivity can be increased if you use gnuplot as the backend. – percusse Mar 3 '13 at 17:02
  • Alternatively, read Herbert's answer here : fundamental differences: pstricks tikz pgf and others and then but only then the second part of David's answer. – percusse Mar 3 '13 at 17:04

You can transform many functions into piecewise Bezier approximations by using the derivative to calculate the inner control points (which represent tangent vectors for the curve at the end-points).

A very good write-up is Bill Casselmann's Mathematical Illustrations, ch. 6 Curves and ch. 7 Drawing Curves Automatically, which I will be re-reading before saying more. But, effectively, any system which implements Bezier curves can be used to approximate other functions by sampling and interpolation.

Here's a postscript illustration. It's sometimes necessary to invent an interpretation of x/0 to allow the calculation to procede using /div{dup 0 eq{pop pop 100000}{div}ifelse}bind def. Edit: modified to show endpoints of each curve.

sin(1/x),n=10,with points

sin(1/x),n=100,with points


/circ { % draw a circle at current point, radius: 3*linewidth
        currentpoint newpath % cx cy
        currentlinewidth 3 mul % cx cy r
        0 360 % cx cy r ang^ ang$
        arc fill %draw and fill the circle
} def

% x0 x1 N  sin1x  -
% approximate sin(1/x) in N segments with piecewise Bezier curves
% N: number of segments,
% x0,x1: endpoints (x- ordinates)
/sin1x { 16 dict begin
    {N x1 x0}{exch def}forall   %give names to the arguments
    /f { 1 exch div sin } def   %f(x) = sin(1/x)
    /f' { 1 exch div cos } def  %f'(x) = cos(1/x)
    /h x1 x0 sub N div def      %dx 
    /x x0 def                   %x = x0
    /y x f def                  %y = f(x)
    /s x f' def                 %s = f'(x)
    x y moveto               %place initial point at x0,f(x0)
    N {                         %repeat N times ...
        circ                    %draw circle to show endpoint
        x h 3 div add
        y h 3 div s mul add  % x+(dx/3) y+(dx/3)*s           ctrl pt 1
        /x x h add def          %x = x + dx
        /y x f def              %y = f(x)
        /s x f' def             %s = f'(x)
        x h 3 div sub
        y h 3 div s mul sub  % x+dx-(dx/3) f(x+dx)-(dx/3)*s  ctrl pt 2
        x y                  % x+dx f(x+dx)                  end pt
        curveto                 %draw curve segment, end pt becomes start of next seg
    } repeat
} def

% translate origin to roughly the center of US letter paper
300 400 translate

% scale by 200, but reduce linewidth by same proportion
% ie. scale the *drawing*, not the *image*
1 200 dup dup scale 
div currentlinewidth mul setlinewidth

%x0 x1 N 
-1 1 100 sin1x stroke
  • 1
    Welcome to TeX.sx! – Peter Jansson Apr 4 '13 at 9:08
  • 1
    Thanks. Stumbled on this while searching SE for anything Bezier-related. I'm a big fan of TeX and have read many things by Knuth, but I'm a little intimidated by TeX itself. As a postscript-hacker, I do greatly envy its text- and type- facilities. – luser droog Apr 4 '13 at 9:20
  • My own postscript interpreter can execute the above program as of this revision. – luser droog Dec 12 '13 at 3:29
  • 2
    You are a PostScript master. – kiss my armpit Feb 14 '14 at 3:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.