Search code examples
matlabtextcurve

Drawing curved text in MATLAB


I wish to draw text along a given vector (which might be anything - not necessarily elliptical or straight). The text must be remain tangential to the curve, like in this example.

The way to do it along some simple equation (a straight or elliptic line) is relatively simple in Java. However, this would be complicated in MATLAB:

  1. converting every character to an image using insertText() or vision.TextInserter
  2. computing the coordinates of each character in a straight line
  3. computing an adequate transformation using TFORM
  4. applying it for each character using imwarp()

Since the code is going to create at least thousands of images, each one with several characters, and will include other rendering operations, I am looking for a simpler/more economical way.

Moreover, this provides no solution in the case of a general vector.

Any suggestions? Adding libraries is not a problem if this can solve the problem.


Solution

  • I was looking for a solution to this as well and decided to write my own:

    Curvy text example

    function curvytext(xy,str,varargin)
    %//
    %// Input: 
    %//     xy          2-by-n matrix of x (row 1) and y (row 2) coordinates
    %//                 describing any 2D path
    %//     str         length m string to be plotted
    %//     varargin    standard variable arguments for modifying text
    %//                 appearance
    %//
        if size(xy,1)>2; xy=xy'; end; 
        n = size(xy,2);
        m = length(str);
    
        XY = spline(1:n,xy,linspace(1,n,m+1));
        dXY = XY(:,2:end)-XY(:,1:end-1);
        theta = (arrayfun(@(y,x) atan2(y,x),dXY(2,:),dXY(1,:)))/2/pi*360;
    
        XY = (XY(:,1:end-1)+XY(:,2:end))/2;
        plot(XY(1,:),XY(2,:),'k-'); hold on;
        for i=1:m
            text(XY(1,i),XY(2,i),str(i),'rotation',theta(i),...
                 'horizontalalignment','center','verticalalignment','bottom',varargin{:});
        end
        axis equal
    end
    

    As written in the commented portion of the code, the input xy is a 2-by-n matrix that describes any 2D path. The input str is the text to plot, and varargin allows you to specify any standard Name,Value pairs just as you would using text.

    How it works:

    spline and linspace(1,n,m+1) together parameterize the curve into m+1 equally spaced pieces, where m is the number of characters in str.

    dXY computes the differences between pairs of consecutive points.

    arrayfun and atan2 compute the rotation angle (in radians) for each letter.

    XY = (XY(:,1:end-1)+XY(:,2:end))/2; averages consecutive pairs of points so that the m letters are plotted in between the m+1 interpolated points.

    Then we loop over each character using text and the rotation property (converted to degrees). Notice varargin is fed into the text command.