Wyjaśnienie
Jednym ze sposobów, że można to zrobić, byłoby użyć surface object z texture-map as the FaceColor
.
W programie MATLAB można utworzyć prostą prostokątną powierzchnię. Można ustawić wartość FaceColor
na texturemap
, która spowoduje, że wartość przypisana do CData
zostanie odwzorowana na powierzchnię.
Następnie, aby uzyskać przezroczystość, można również ustawić wartość FaceAlpha
na texturemap
i ustawić wartość AlphaData
, a wartości przezroczystości będą odwzorowane również w zakresie powierzchni.
Aby zastosować to do swojej skrzynki, chcesz ustawić CData
na obraz, który chcesz zastąpić strzałkami. I chcesz, aby rozmiar AlphaData
był taki sam, jak danych obrazu o wartości 1, w której ma być nieprzezroczysty i 0, w którym ma być przezroczysty. Dzięki temu nie będzie wyglądać jak obraz, który opublikowałeś, gdzie wyraźnie widać ramkę obwiedni. Następnie musisz narysować jedną z tych powierzchni, na którą pójdzie każda ze strzałek, i skalować/pozycjonować ją odpowiednio.
Realizacja
Aktualizacja: Bardziej dopracowana wersja tego kodu (ImageQuiver
) jest teraz dostępny na Github jak również MATLAB File Exchange.
Jako demonstrację tego, o czym mówię, stworzyłem następującą funkcję, która w zasadzie właśnie to robi. Przyjmuje te same dane wejściowe, co quiver
(z danymi obrazu dostarczanymi jako pierwsze i opcjonalnym parametrem AlphaData
na końcu) i tworzy powierzchnię dla wszystkich żądanych współrzędnych wskazujących w żądanym kierunku i skaluje się o określoną wartość.
function h = quiverpic(im, X, Y, dX, dY, scale, alpha)
% im - RGB or indexed image
% X - X positions
% Y - Y positions
% dX - X direction vector
% dY - Y direction vector
% scale - Any scaling (Default = 1)
% alpha - Transparency (same size as im), if not specified = ~isnan(im)
h = hggroup();
if ~exist('scale', 'var')
% By default there is no scaling
scale = 1;
end
if ~exist('alpha', 'var')
% By default, any NaN will be transparent
alpha = ~isnan(im);
end
% Determine aspect ratio of the source image
width_to_height = size(im, 2)/size(im, 1);
for k = 1:numel(X)
% Determine angle from displacement vectors
theta = atan2(dY(k), dX(k));
% Subtract pi/2 to +y is considered "up"
theta = theta + pi/2;
% Setup surface plot boundary
[xx,yy] = meshgrid([-0.5, 0.5] * width_to_height, [0 1]);
% Scale depending on magnitude of dX and dY
this_scale = scale * sqrt(dX(k).^2 + dY(k).^2);
% Scale X and Y components prior to rotating
xx = xx .* this_scale;
yy = yy .* this_scale;
% Rotate to align with the desired direction
xdata = xx .* cos(theta) - yy .* sin(theta);
ydata = xx .* sin(theta) + yy .* cos(theta);
% Determine what is considered the "anchor" of the graphic.
% For now this is assumed to be the "bottom-middle"
xoffset = X(k) - mean(xdata(2,:));
yoffset = Y(k) - mean(ydata(2,:));
% Actually plot the surface.
surf(xdata + xoffset, ...
ydata + yoffset, zeros(2), ...
'Parent', h, ...
'FaceColor', 'texture', ...
'EdgeColor', 'none', ...
'CData', im, ...
'FaceAlpha', 'texture', ...
'AlphaData', double(alpha));
end
end
Przykład
napisałem mały skrypt testowy, aby pokazać, jak to może być stosowane i aby pokazać wyniki.
t = linspace(0, 2*pi, 13);
dX = cos(t(1:end-1));
dY = sin(t(1:end-1));
X = (3 * dX) + 5;
Y = (3 * dY) + 5;
scale = 1;
% Load the MATLAB logo as an example image
png = fullfile(matlabroot,'/toolbox/matlab/icons/matlabicon.gif');
[im, map] = imread(png);
im = ind2rgb(im, map);
% Determine alpha channel based on upper left hand corner pixel
flatim = reshape(im, [], 3);
alpha = ~ismember(flatim, squeeze(im(1,1,:)).', 'rows');
alpha = reshape(alpha, size(im(:,:,1)));
% Plot some things prior to creating the quiverpic object
fig = figure();
hax = axes('Parent', fig);
axis(hax, 'equal');
% Plot a full circle
t = linspace(0, 2*pi, 100);
plot((cos(t) * 3) + 5, (sin(t) * 3) + 5, '-')
hold(hax, 'on')
% Plot markers at all the quiver centers
plot(X, Y, 'o', 'MarkerFaceColor', 'w')
% Plot a random image behind everything to demonstrate transparency
him = imagesc(rand(9));
uistack(him, 'bottom')
axis(hax, 'equal')
colormap(fig, 'gray')
set(hax, 'clim', [-4 4]);
% Now plot the quiverpic
h = quiverpic(im, X, Y, dX, dY, 1, alpha);
axis(hax, 'tight')
Wyniki
absurd
sam obraz z różnych kierunków i skalowanie
dowolny obraz z dowolnej proporcji obrazu będzie działać dobrze
[W] (http://stackoverflow.com/questions/18214874/how-to-draw-good-looking-arrows-in-matlab) może pomóc. Aby uzyskać najlepsze wyniki, zaleciłbym samodzielne wykonanie rysowania. – horchler