Code covered by the BSD License  

Highlights from
Move Sphere

image thumbnail
from Move Sphere by Husam Aldahiyat
Creates a randomly coloured sphere and moves it from point A to point B with speed V.

h=movsph(r,A,B,V,op1,ph)
function h=movsph(r,A,B,V,op1,ph)
% MOVSPH move sphere
% movsph(r,A,B,V,op1) creates a randomly coloured sphere with radius r and
% moves it from point A to point B with speed V.
%
%=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
% Parameters:
%
% r  : Radius of sphere
%
% A  : Two element vector specifying starting position of centre of sphere
%
% B  : Two element vector specifying ending position of centre of sphere
%
% V  : Speed of rotation
% 
% op1: 1 -> Plot ground on which sphere moves and adjust axis
%      0 -> Only plot the sphere and move it (default)
%
% ph : Handle of previously created sphere (optional).
%      If this value is granted, then the inputs (A) is ignored
%
% h  : Handle of sphere
%
%=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
%
% The ball moves on the ground, specified by 0z. The code can manually
% adjusts axis limits and even plots the ground with use of op1.
%
% Example:
%
% % create sphere and move it from [0 0] to [15 30] with speed 25
% h=movsph(1,[0,0],[15,30],25,1);
%
% % move same sphere from its location to [1,1] with speed 10
% movsph(1,[rand,rand],[1,1],30,0,h);
%
% numandina@gmail.com 
% Feb. 2009
%

% check inputs
if nargin < 5
	op1=0;
elseif nargin < 6
	ph=[];
end

if length(A)~=length(B) || length(A)~=2
	error('movsph:lengths',...
		['A and B both need to be two element vectors. ',...
		'Please check input documentation.'])
end

% just to make sure (user should put this before calling
% the function)
hold on

if isempty(ph) % no handle of previous sphere present, create new sphere
	
% create unit sphere
[a,b,c]=sphere(25);

% adjust size of sphere my multiplying by the radius
% also, move sphere to starting position by adding
% and put sphere on the ground (0z) by adding r to z
h=surf(a.*r+A(1),b.*r+A(2),c.*r+r);

% give sphere a random colour
set(h,'facecolor','interp','edgecolor','interp')
colormap(rand(2,3).*.7+.3)

% get sphere colour data
s2=get(h,'cdata');

% take the sphere top and change its colour to something 
s2(end-3:end,:)=repmat(.2,4,size(s2,2));

% take the rest of the sphere and give it a different number
s2(s2~=.2)=.4;

% now because of the interpolation of facecolor and randomization
% of the colormap, you'll get two different colours each time for
% both the sphere and its " top spot".
set(h,'cdata',s2)

else % if sphere was already created
	
	% obtain its handle
	h=ph; 
	
	% get sphere's current position
  	A=[(max(max(get(h,'xdata')))+min(min(get(h,'xdata'))))/2,...
 		(max(max(get(h,'ydata')))+min(min(get(h,'ydata'))))/2];
end

% the following are bonus lines of code that should have been applied
% by the user before calling this function
% the lines adjust the axis for proper viewing
% they are only performed if the input op1 is set to 1.
if op1
	axis([min([A(1) B(1) A(2) B(2)]-r*7), max([A(1) B(1) A(2) B(2)]+r*7),...
		min([A(1) B(1) A(2) B(2)]-r*7), max([A(1) B(1) A(2) B(2)]+r*7),...
		-r*5, r*5])
	axis equal
	view(3)
	rotate3d
	xlabel('X')
	ylabel('Y')
	grid on

	% plot destination point
	plot3(B(1),B(2),r,'k.')
	
	% for future reference
	v=axis;

	% create a patch that spans the axis edges (acts as ground)
	% again, this is bonus code
	aaa=[v(1) v(3) 0;
		v(2) v(3) 0;
		v(2) v(4) 0;
		v(1) v(4) 0;
		v(1) v(3) 0;
		v(2) v(3) 0;
		v(2) v(4) 0;
		v(1) v(4) 0];
	b=[1 2 6 5;2 3 7 6;3 4 8 7;4 1 5 8;1 2 3 4;5 6 7 8];
	patch('vertices',aaa,'faces',b,'edgecolor',[1 1 1],'facecolor',[.3 .3 .3],...
		'facevertexalphadata',0.5,'facealpha','flat');
end

% for future reference
v=axis;
	
% for while loop initial status
ctr=[1e9 1e9];

% while centre of the sphere is at least .1 away from the destination points
while mean(abs(ctr-B))>1e-1
	
	% get centre of sphere
	ctr=[(max(max(get(h,'xdata')))+min(min(get(h,'xdata'))))/2,...
		(max(max(get(h,'ydata')))+min(min(get(h,'ydata'))))/2];
	
	% vector from current point to destination
	rot=B-ctr;
	
	% get orthogonal vector (which the ball will spin around)
	yu=rot(2);
	rot(2)=rot(1);
	rot(1)=-yu;

	% rotate around sphere about said vector
	% origin is centre of sphere
	rotate(h,[rot,0],V,[ctr,r])
	
	% move sphere according to its speed
	% the sign commands are for the direction of movement
	% the sphere moves in X and Y the same distance as the one it has rolled
	% in other words it moves V/360
	% but it doesn't move the entirety of this roll since it is divided between
	% X and Y rolling, we find out how much is shared between X and Y using atan
	set(h,'xdata',get(h,'xdata')...
		-(sign(rot(1))-~sign(rot(1)))...
		*V/360*...
		atan(-rot(2)/rot(1)))
	set(h,'ydata',get(h,'ydata')+(sign(rot(2))+sign(rot(2)))*V/360*atan(rot(1)/-rot(2)))
	
	
	% so that axis wouldn't change while animating
	axis(v)
	
	% update plot
	drawnow()
end

end
% EOF

Contact us at files@mathworks.com