141 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Matlab
		
	
	
		
		
			
		
	
	
			141 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Matlab
		
	
	
| 
								 | 
							
								function arrowHandle = arrow3D(pos, deltaValues, colorCode, stemRatio, rhoRatio)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								% arrowHandle = arrow3D(pos, deltaValues, colorCode, stemRatio) %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
							 | 
						||
| 
								 | 
							
								% 
							 | 
						||
| 
								 | 
							
								%     Used to plot a single 3D arrow with a cylindrical stem and cone arrowhead
							 | 
						||
| 
								 | 
							
								%     pos = [X,Y,Z] - spatial location of the starting point of the arrow (end of stem)
							 | 
						||
| 
								 | 
							
								%     deltaValues = [QX,QY,QZ] - delta parameters denoting the magnitude of the arrow along the x,y,z-axes (relative to 'pos')
							 | 
						||
| 
								 | 
							
								%     colorCode - Color parameters as per the 'surf' command.  For example, 'r', 'red', [1 0 0] are all examples of a red-colored arrow
							 | 
						||
| 
								 | 
							
								%     stemRatio - The ratio of the length of the stem in proportion to the arrowhead.  For example, a call of:
							 | 
						||
| 
								 | 
							
								%                 arrow3D([0,0,0], [100,0,0] , 'r', 0.82) will produce a red arrow of magnitude 100, with the arrowstem spanning a distance
							 | 
						||
| 
								 | 
							
								%                 of 82 (note 0.82 ratio of length 100) while the arrowhead (cone) spans 18.  
							 | 
						||
| 
								 | 
							
								%     rhoRatio - The ratio of the cylinder radius (0.05 is the default)
							 | 
						||
| 
								 | 
							
								%     value)
							 | 
						||
| 
								 | 
							
								% 
							 | 
						||
| 
								 | 
							
								%     Example:
							 | 
						||
| 
								 | 
							
								%       arrow3D([0,0,0], [4,3,7]);  %---- arrow with default parameters
							 | 
						||
| 
								 | 
							
								%       axis equal;
							 | 
						||
| 
								 | 
							
								% 
							 | 
						||
| 
								 | 
							
								%    Author: Shawn Arseneau
							 | 
						||
| 
								 | 
							
								%    Created: September 14, 2006
							 | 
						||
| 
								 | 
							
								%    Updated: September 18, 2006
							 | 
						||
| 
								 | 
							
								% 
							 | 
						||
| 
								 | 
							
								%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
							 | 
						||
| 
								 | 
							
								    if nargin<2 || nargin>5     
							 | 
						||
| 
								 | 
							
								        error('Incorrect number of inputs to arrow3D');     
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    if numel(pos)~=3 || numel(deltaValues)~=3
							 | 
						||
| 
								 | 
							
								        error('pos and/or deltaValues is incorrect dimensions (should be three)');
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    if nargin<3                 
							 | 
						||
| 
								 | 
							
								        colorCode = 'interp';                             
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    if nargin<4                 
							 | 
						||
| 
								 | 
							
								        stemRatio = 0.75;                                   
							 | 
						||
| 
								 | 
							
								    end    
							 | 
						||
| 
								 | 
							
								    if nargin<5                 
							 | 
						||
| 
								 | 
							
								        rhoRatio = 0.05;                                   
							 | 
						||
| 
								 | 
							
								    end    
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    X = pos(1); %---- with this notation, there is no need to transpose if the user has chosen a row vs col vector
							 | 
						||
| 
								 | 
							
								    Y = pos(2);
							 | 
						||
| 
								 | 
							
								    Z = pos(3);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    [sphi, stheta, srho] = cart2sph(deltaValues(1), deltaValues(2), deltaValues(3));  
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    %******************************************* CYLINDER == STEM *********************************************
							 | 
						||
| 
								 | 
							
								    cylinderRadius = srho*rhoRatio;
							 | 
						||
| 
								 | 
							
								    cylinderLength = srho*stemRatio;
							 | 
						||
| 
								 | 
							
								    [CX,CY,CZ] = cylinder(cylinderRadius);      
							 | 
						||
| 
								 | 
							
								    CZ = CZ.*cylinderLength;    %---- lengthen
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    %----- ROTATE CYLINDER
							 | 
						||
| 
								 | 
							
								    [row, col] = size(CX);      %---- initial rotation to coincide with X-axis
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    newEll = rotatePoints([0 0 -1], [CX(:), CY(:), CZ(:)]);
							 | 
						||
| 
								 | 
							
								    CX = reshape(newEll(:,1), row, col);
							 | 
						||
| 
								 | 
							
								    CY = reshape(newEll(:,2), row, col);
							 | 
						||
| 
								 | 
							
								    CZ = reshape(newEll(:,3), row, col);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    [row, col] = size(CX);    
							 | 
						||
| 
								 | 
							
								    newEll = rotatePoints(deltaValues, [CX(:), CY(:), CZ(:)]);
							 | 
						||
| 
								 | 
							
								    stemX = reshape(newEll(:,1), row, col);
							 | 
						||
| 
								 | 
							
								    stemY = reshape(newEll(:,2), row, col);
							 | 
						||
| 
								 | 
							
								    stemZ = reshape(newEll(:,3), row, col);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    %----- TRANSLATE CYLINDER
							 | 
						||
| 
								 | 
							
								    stemX = stemX + X;
							 | 
						||
| 
								 | 
							
								    stemY = stemY + Y;
							 | 
						||
| 
								 | 
							
								    stemZ = stemZ + Z;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    %******************************************* CONE == ARROWHEAD *********************************************
							 | 
						||
| 
								 | 
							
								    coneLength = srho*(1-stemRatio);
							 | 
						||
| 
								 | 
							
								    coneRadius = cylinderRadius*1.5;
							 | 
						||
| 
								 | 
							
								    incr = 4;  %---- Steps of cone increments
							 | 
						||
| 
								 | 
							
								    coneincr = coneRadius/incr;    
							 | 
						||
| 
								 | 
							
								    [coneX, coneY, coneZ] = cylinder(cylinderRadius*2:-coneincr:0);  %---------- CONE 
							 | 
						||
| 
								 | 
							
								    coneZ = coneZ.*coneLength;
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    %----- ROTATE CONE 
							 | 
						||
| 
								 | 
							
								    [row, col] = size(coneX);    
							 | 
						||
| 
								 | 
							
								    newEll = rotatePoints([0 0 -1], [coneX(:), coneY(:), coneZ(:)]);
							 | 
						||
| 
								 | 
							
								    coneX = reshape(newEll(:,1), row, col);
							 | 
						||
| 
								 | 
							
								    coneY = reshape(newEll(:,2), row, col);
							 | 
						||
| 
								 | 
							
								    coneZ = reshape(newEll(:,3), row, col);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    newEll = rotatePoints(deltaValues, [coneX(:), coneY(:), coneZ(:)]);
							 | 
						||
| 
								 | 
							
								    headX = reshape(newEll(:,1), row, col);
							 | 
						||
| 
								 | 
							
								    headY = reshape(newEll(:,2), row, col);
							 | 
						||
| 
								 | 
							
								    headZ = reshape(newEll(:,3), row, col);
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    %---- TRANSLATE CONE
							 | 
						||
| 
								 | 
							
								    V = [0, 0, srho*stemRatio];    %---- centerline for cylinder: the multiplier is to set the cone 'on the rim' of the cylinder
							 | 
						||
| 
								 | 
							
								    Vp = rotatePoints([0 0 -1], V);
							 | 
						||
| 
								 | 
							
								    Vp = rotatePoints(deltaValues, Vp);
							 | 
						||
| 
								 | 
							
								    headX = headX + Vp(1) + X;
							 | 
						||
| 
								 | 
							
								    headY = headY + Vp(2) + Y;
							 | 
						||
| 
								 | 
							
								    headZ = headZ + Vp(3) + Z;
							 | 
						||
| 
								 | 
							
								    %************************************************************************************************************    
							 | 
						||
| 
								 | 
							
								    hStem = surf(stemX, stemY, stemZ, 'FaceColor', colorCode, 'EdgeColor', 'none'); 
							 | 
						||
| 
								 | 
							
								    hold on;  
							 | 
						||
| 
								 | 
							
								    hHead = surf(headX, headY, headZ, 'FaceColor', colorCode, 'EdgeColor', 'none');
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    if nargout==1   
							 | 
						||
| 
								 | 
							
								        arrowHandle = [hStem, hHead]; 
							 | 
						||
| 
								 | 
							
								    end
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								    
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 |