mirror of
https://github.com/c-sooyoung/fold_slice.git
synced 2026-09-17 19:39:08 +09:00
initial commit
This commit is contained in:
@@ -0,0 +1,179 @@
|
||||
function h = mArrow3(p1,p2,varargin)
|
||||
%mArrow3 - plot a 3D arrow as patch object (cylinder+cone)
|
||||
%
|
||||
% syntax: h = mArrow3(p1,p2)
|
||||
% h = mArrow3(p1,p2,'propertyName',propertyValue,...)
|
||||
%
|
||||
% with: p1: starting point
|
||||
% p2: end point
|
||||
% properties: 'color': color according to MATLAB specification
|
||||
% (see MATLAB help item 'ColorSpec')
|
||||
% 'stemWidth': width of the line
|
||||
% 'tipWidth': width of the cone
|
||||
%
|
||||
% Additionally, you can specify any patch object properties. (For
|
||||
% example, you can make the arrow semitransparent by using
|
||||
% 'facealpha'.)
|
||||
%
|
||||
% example1: h = mArrow3([0 0 0],[1 1 1])
|
||||
% (Draws an arrow from [0 0 0] to [1 1 1] with default properties.)
|
||||
%
|
||||
% example2: h = mArrow3([0 0 0],[1 1 1],'color','red','stemWidth',0.02,'facealpha',0.5)
|
||||
% (Draws a red semitransparent arrow with a stem width of 0.02 units.)
|
||||
%
|
||||
% hint: use light to achieve 3D impression
|
||||
%
|
||||
% Copyright (c) 2009, Georg Stillfried
|
||||
% All rights reserved.
|
||||
%
|
||||
% Redistribution and use in source and binary forms, with or without
|
||||
% modification, are permitted provided that the following conditions are met:
|
||||
%
|
||||
% * Redistributions of source code must retain the above copyright notice, this
|
||||
% list of conditions and the following disclaimer.
|
||||
%
|
||||
% * Redistributions in binary form must reproduce the above copyright notice,
|
||||
% this list of conditions and the following disclaimer in the documentation
|
||||
% and/or other materials provided with the distribution
|
||||
% * Neither the name of DLR - german aerospace center nor the names of its
|
||||
% contributors may be used to endorse or promote products derived from this
|
||||
% software without specific prior written permission.
|
||||
% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
% AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
% IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
% DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||
% FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
% DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
% SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
% CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
% OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
% OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
propertyNames = {'edgeColor'};
|
||||
propertyValues = {'none'};
|
||||
|
||||
%% evaluate property specifications
|
||||
for argno = 1:2:nargin-2
|
||||
switch varargin{argno}
|
||||
case 'color'
|
||||
propertyNames = {propertyNames{:},'facecolor'};
|
||||
propertyValues = {propertyValues{:},varargin{argno+1}};
|
||||
case 'stemWidth'
|
||||
if isreal(varargin{argno+1})
|
||||
stemWidth = varargin{argno+1};
|
||||
else
|
||||
warning('mArrow3:stemWidth','stemWidth must be a real number');
|
||||
end
|
||||
case 'tipWidth'
|
||||
if isreal(varargin{argno+1})
|
||||
tipWidth = varargin{argno+1};
|
||||
else
|
||||
warning('mArrow3:tipWidth','tipWidth must be a real number');
|
||||
end
|
||||
otherwise
|
||||
propertyNames = {propertyNames{:},varargin{argno}};
|
||||
propertyValues = {propertyValues{:},varargin{argno+1}};
|
||||
end
|
||||
end
|
||||
|
||||
%% default parameters
|
||||
if ~exist('stemWidth','var')
|
||||
ax = axis;
|
||||
if numel(ax)==4
|
||||
stemWidth = norm(ax([2 4])-ax([1 3]))/300;
|
||||
elseif numel(ax)==6
|
||||
stemWidth = norm(ax([2 4 6])-ax([1 3 5]))/300;
|
||||
end
|
||||
end
|
||||
if ~exist('tipWidth','var')
|
||||
tipWidth = 3*stemWidth;
|
||||
end
|
||||
tipAngle = 22.5/180*pi;
|
||||
tipLength = tipWidth/tan(tipAngle/2);
|
||||
ppsc = 50; % (points per small circle)
|
||||
ppbc = 250; % (points per big circle)
|
||||
|
||||
%% ensure column vectors
|
||||
p1 = p1(:);
|
||||
p2 = p2(:);
|
||||
|
||||
%% basic lengths and vectors
|
||||
x = (p2-p1)/norm(p2-p1); % (unit vector in arrow direction)
|
||||
y = cross(x,[0;0;1]); % (y and z are unit vectors orthogonal to arrow)
|
||||
if norm(y)<0.1
|
||||
y = cross(x,[0;1;0]);
|
||||
end
|
||||
y = y/norm(y);
|
||||
z = cross(x,y);
|
||||
z = z/norm(z);
|
||||
|
||||
%% basic angles
|
||||
theta = 0:2*pi/ppsc:2*pi; % (list of angles from 0 to 2*pi for small circle)
|
||||
sintheta = sin(theta);
|
||||
costheta = cos(theta);
|
||||
upsilon = 0:2*pi/ppbc:2*pi; % (list of angles from 0 to 2*pi for big circle)
|
||||
sinupsilon = sin(upsilon);
|
||||
cosupsilon = cos(upsilon);
|
||||
|
||||
%% initialize face matrix
|
||||
f = NaN([ppsc+ppbc+2 ppbc+1]);
|
||||
|
||||
%% normal arrow
|
||||
if norm(p2-p1)>tipLength
|
||||
% vertices of the first stem circle
|
||||
for idx = 1:ppsc+1
|
||||
v(idx,:) = p1 + stemWidth*(sintheta(idx)*y + costheta(idx)*z);
|
||||
end
|
||||
% vertices of the second stem circle
|
||||
p3 = p2-tipLength*x;
|
||||
for idx = 1:ppsc+1
|
||||
v(ppsc+1+idx,:) = p3 + stemWidth*(sintheta(idx)*y + costheta(idx)*z);
|
||||
end
|
||||
% vertices of the tip circle
|
||||
for idx = 1:ppbc+1
|
||||
v(2*ppsc+2+idx,:) = p3 + tipWidth*(sinupsilon(idx)*y + cosupsilon(idx)*z);
|
||||
end
|
||||
% vertex of the tiptip
|
||||
v(2*ppsc+ppbc+4,:) = p2;
|
||||
|
||||
% face of the stem circle
|
||||
f(1,1:ppsc+1) = 1:ppsc+1;
|
||||
% faces of the stem cylinder
|
||||
for idx = 1:ppsc
|
||||
f(1+idx,1:4) = [idx idx+1 ppsc+1+idx+1 ppsc+1+idx];
|
||||
end
|
||||
% face of the tip circle
|
||||
f(ppsc+2,:) = 2*ppsc+3:(2*ppsc+3)+ppbc;
|
||||
% faces of the tip cone
|
||||
for idx = 1:ppbc
|
||||
f(ppsc+2+idx,1:3) = [2*ppsc+2+idx 2*ppsc+2+idx+1 2*ppsc+ppbc+4];
|
||||
end
|
||||
|
||||
%% only cone v
|
||||
else
|
||||
tipWidth = 2*sin(tipAngle/2)*norm(p2-p1);
|
||||
% vertices of the tip circle
|
||||
for idx = 1:ppbc+1
|
||||
v(idx,:) = p1 + tipWidth*(sinupsilon(idx)*y + cosupsilon(idx)*z);
|
||||
end
|
||||
% vertex of the tiptip
|
||||
v(ppbc+2,:) = p2;
|
||||
% face of the tip circle
|
||||
f(1,:) = 1:ppbc+1;
|
||||
% faces of the tip cone
|
||||
for idx = 1:ppbc
|
||||
f(1+idx,1:3) = [idx idx+1 ppbc+2];
|
||||
end
|
||||
end
|
||||
|
||||
%% draw
|
||||
fv.faces = f;
|
||||
fv.vertices = v;
|
||||
h = patch(fv);
|
||||
for propno = 1:numel(propertyNames)
|
||||
try
|
||||
set(h,propertyNames{propno},propertyValues{propno});
|
||||
catch
|
||||
disp(lasterr)
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user