How can I find a path for each letter containing a list of x and y values?

2 views (last 30 days)
Mohammad Rastegarpanah on 10 Oct 2022
Edited: DGM on 27 Sep 2023
For example;
• For letter M: path1= [ [x1 y1], [x2 y2],...];
• For letter A: path2= [ [x1 y1], [x2 y2],...];
• For letter X: path3= [ [x1 y1], [x2 y2],...];
Thanks,
figure
ax=gca;
t = text(0.05,0.05,'MAX');
s = t.FontSize;
t.FontSize = 50;
ax.Visible='on';
grid on
Mohammad Rastegarpanah on 11 Oct 2022
Edited: Mohammad Rastegarpanah on 11 Oct 2022
@Jan It's not an image; for example, I defined some points (containing x and y values), resulting in the letters M and O!
f = figure();
xlim([1 118]) % set x-axis visible on figure
ylim([1 20]) % set y-axis visible on figure
hold on %keep all lines on one figure
grid on
% letter M
x1 = [1, 1, 5, 9, 9];
y1 = [0, 10, 5, 10, 0];
M = plot(x1,y1,'r','LineWidth',2);
%letter O
xc = 20;
yc = 5;
theta = linspace(0,2*pi,100);
x2 = r*cos(theta);
y2 = r*sin(theta);
x2 = x2+20;
y2 = y2+5;
O = plot(x2,y2,'r','LineWidth',2);
axis equal
Now let's consider the opposite way; you want to give some letters that can be a name, for example, MAX, and in the output, you can have a list of x and y values for each letter M, A, X separately.
figure
ax=gca;
t = text(0.05,0.05,'MAX');
s = t.FontSize;
t.FontSize = 50;
ax.Visible='on';
grid on
The last example is a figure. Consequently, I think it's impossible to extract x and y values.
• Is there any alternative way to solve this problem?
Jan on 11 Oct 2022
@Mohammad Rastegarpanah: The question is still not clear. "you want to give some letters" - what exactly do you call "some letters"? You post a pixel image, which contains some letters (but an axes and their labels also).
What exactly is the input you start with? Do not think in categories like "some letters", but in objects as Matlab can see them: arrays which are coordinates or pixel values or what ever.
Then define, what "x and y values" mean. Values of what? The M is a polygon with 13 corners. Then what do you exactly want as output?
I still think, you want a vectorization of a pixel image. This is solved e.g. by inkScape.

DGM on 27 Sep 2023
Edited: DGM on 27 Sep 2023
If you're trying to vectorize text, and aren't terribly concerned with the font, you could just start with text that's already in vector form. For this, I'm just going to use any pedestrian 2D CAD software to write some text containing the desired characters separated by spaces. Pay attention to the text size, and place it at the origin. Explode the MTEXT object and save the file.
Then, use DXFtool() to read the file. The reason the text is exploded (converted into primitives) is because DXFtool can't read MTEXT. The reason the characters are spaced apart is so that we can tell which primitives belong to which character.
% these are the characters in the DXF
charset = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
% this is the nominal character height
charheight = 1; % whatever you used in the DXF
% DXFtool can't read mtext entities
% but if you explode the text, it can read the primitives
% DXFtool will open a figure; we don't really need that
dxf = DXFtool('vectortext.dxf.txt'); % fake extension for the forum
% of course, once exploded, the primitives aren't associated anymore
% so we have to group them back into characters somehow
% i'm just going to do this based on the character size and distance between chars
% i'm presuming character width is less than character height
n = 1; % initialize
C = cell(1);
for k = 1:dxf.ne
x = dxf.entities(k).handle.XData;
y = dxf.entities(k).handle.YData;
if k == 1
lastxmax = max(x);
end
% if point lists are distant (in x), start a new character
% otherwise, append to the current character
if min(x) > (lastxmax + charheight)
n = n+1;
C{n} = [x(:) y(:)];
else
C{n} = [C{n}; nan(1,2); [x(:) y(:)]];
end
lastxmax = max(x);
end
% go through the characters and remove their x-offsets
for k = 1:numel(C)
C{k}(:,1) = C{k}(:,1) - min(C{k}(:,1));
end
% now you can just save C and charset for later use
save('vectortext.mat','C','charset')
Now we have a character set represented in a char vector, and we have a corresponding set of x-y point lists. Given any new text, we can just draw it.
%% when you want to convert text, use the collected info
% the inputs
mytext = '256 Bananas';
charspacing = 0.25;
spacewidth = 0.55;
% initial position
x0 = 0;
y0 = 0;
% plot the things
figure
for k = 1:numel(mytext)
thischar = mytext(k);
% check to see if this character is in the charset
% if it's not, do something
if ~any(charset == thischar,2)
if thischar == ' '
% if it's a space, we know what to do with that
x0 = x0 + spacewidth;
end
% otherwise, just skip unknown characters
continue;
end
% get xy data for this character
idx = find(charset == thischar);
x = C{idx}(:,1);
y = C{idx}(:,2);
% shift x as needed
cw = max(x);
x = x + x0;
x0 = x0 + cw + charspacing; % update x0
% shift y as needed
y = y + y0;
plot(x,y); hold on
end
axis equal
This example is hardly robust or complete, but it's enough to demonstrate the idea.