Code covered by the BSD License  

Highlights from
Plot 3D vectors/arrow (again ...)

image thumbnail
from Plot 3D vectors/arrow (again ...) by Emmanuel Dinnat
Plot 3D vectors using surfaces

arrowPlot(initPoints, finishPoints, varargin)
% function hArrow = arrowPlot(initPoints, finishPoints, color)  
%  draw N arrow(s) using #d surfaces, from coordinate(s) |initPoints| (3 column x N rows)
%  to coordinate |finishPoints| (coordinates in cartesian).
%  |color| is optional, it is a 3 element row (1 color for all arrows) or a 3 columns by
%  N rows array where N is the number of arrows (and incidently the number of rows for
%  initPoints and finishPoints).
%  Note : color has implementation problems when colored surfaces are already presents.
%			might mess up the colormap => might need to be desactivated!!
%
%
%	Examples:
%
%	sphere(20);
%   hold on;
%	axis equal;
%	arrowPlot([0, 0, 1.2], [0+0.8, 0, 1.2], [1, 0, 0]);
%	arrowPlot([0, 0, 1.2], [0, 0+0.8, 1.2], [0, 1, 0]);
%	arrowPlot([0, 0, 1.2], [0, 0, 1.2+0.8], [0, 0, 1]); 
%	set(gca,'zlim', [-1, 2])
%
%
%		Draw a kind of reference frame centered on position [0, 0, 1.2]
%		above a colored sphere centered on [0,0,0] with radius 1,
%		The 3 reference axis are along X, Y, Z of the figure, with length 0.8 and
%		have each a different color.
%
%	sphere(20);
%   hold on;
%	axis equal;
%	arrowPlot([[0, 0, 1.2]; [0, 0, 1.2]; [0, 0, 1.2]], ...
%			  [[0+0.8, 0, 1.2];[0, 0+0.8, 1.2] ; [0, 0, 1.2+0.8]], ...
%			  [[1, 0, 0]; [0, 1, 0] ; [0, 0, 1] ]);
%	set(gca,'zlim', [-1, 2])
%
%		Does the same as previous example, but arrowPlots uses an array for the 3 vectors.
%	
%
%	TODO : allow for different input type, i.e. origin point & incidence, azimuth and
%		   length of the arrow from this point.
%			Change aspect ratio for the arrow parts
%
%	Author : Emmanuel P. Dinnat
%
%	Date : 2005
%


function hArrow = arrowPlot(initPoints, finishPoints, varargin)  
if length(varargin) == 1
	colorPoints = varargin{1};
else
	colorPoints = [0.1,0.1,0.1];
end
lineWidth = 0.01;
for iPoint = 1:size(initPoints, 1)
init = initPoints(iPoint,:);
finish = finishPoints(iPoint,:);
color = colorPoints(min([iPoint, size(colorPoints, 1)]),:);
%% make surface for the line of the arrow with a cylinder of height = 0.9 and width = lineWidth
	[xc, yc, zc] = cylinder(lineWidth);
	zc = zc*0.9;
%% make surface for the tip of the arrow
	% make a cone with a base 300% larger than the line and a tip = 0
	[xt, yt, zt] = cylinder(lineWidth*3 - [0:0.1:1]*lineWidth*3);	
	% decrease the tip height to be 10% of the total arrow height
	zt = zt/10;
%% join both part, putting tip above line,  to make arrow object
	xa = [xc; xt];
	ya = [yc; yt];
	za = [zc; zt + 0.9];
%% rotate, resize and translate arrow
	lengthArrow = norm(finish - init);
	xa = xa*lengthArrow;
	ya = ya*lengthArrow;
	za = za*lengthArrow;
	% bring the asked arrow coordinates to origin
	finish_temp = finish - init;
	% derive rotation angles
	[phi_rot, th_rot, R] = cart2sph(finish_temp(1), finish_temp(2), finish_temp(3));
	th_rot = pi/2 - th_rot;
	% apply rotations to arrow
	% rotation around Y-axis
	[phiArrowZX, R] = cart2pol(za, xa);
	phiArrowZX = phiArrowZX + th_rot;
	[za2, xa2] = pol2cart(phiArrowZX, R);
	ya2 = ya;
	% rotation around Z-axis
	[phiArrowXY, R] = cart2pol(xa2, ya2);
	phiArrowXY = phiArrowXY + phi_rot;
	[xa3, ya3] = pol2cart(phiArrowXY, R);
	za3 = za2;
	% apply translation to arrow
	xa3 = xa3 + init(1);
	ya3 = ya3 + init(2);
	za3 = za3 + init(3);
%% plot arrow
hArrow = surf(xa3, ya3, za3);
set(hArrow, 'facecolor', color, 'edgecolor', 'none', ...
	'diffuseStrength', 0.5, 'AmbientStrength',0.5, ...
	'SpecularStrength', 1,...
	'meshstyle', 'row')
hold on
% let's try to restore original colors to already existing colored surfaces !!
climval = get(gca, 'clim');
set(hArrow, 'Cdata', zeros(13,21)+climval(1));

end

Contact us at files@mathworks.com