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:
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.
I was looking for a solution to this as well and decided to write my own:
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.