Cone
This class is a child of PrimitiveShape.
Contents
classdef Cone < PrimitiveShape
%This Class defines the Cone object. This is a subclass of Primitive %Shape and defines the geometric properties for a cone. % % URL : $URL: $ % Log : $Id: Cone.html,v 1.1 2008/07/23 12:51:19 jberg Exp $ % Copyright (c) 2008 The MathWorks, Inc.
Class Properties
properties ( SetAccess = 'public', GetAccess = 'public' ) base_radius = 0.5; % (pos def double) top_radius = 0; % (pos semidef double) x and y-axes height = 1; % (pos def double) z-axis end properties ( Dependent = true ) moment_of_inertia_about_CG; % (3x3 double) volume; % (pos def double) end properties ( SetAccess = 'private', GetAccess = 'public', Constant = true ) % The order of dimension_order needs to be the same as that % expected by org.j3d.geom.ConeGenerator.setDimensions() % setDimensions(float height, float radius, boolean hasBottom) dimension_order = {'height','base_radius'}; end properties ( SetAccess = 'private', GetAccess = 'private', Constant = true ) PROPERTY_LIST = { 'base_radius' % 'coord_system' % From parent class Shape 'height' % 'tempProp' 'material' % From parent class PrimitiveShape 'name' % From parent class Shape 'orientation' % From parent class Shape 'origin' % From parent class Shape 'top_radius' % }; end methods
Constructor
function obj = Cone(varargin) if(mod(nargin,2)~=0) error('Expecting inputs as property name-value pairs.') end prop_list = eval([mfilename '.PROPERTY_LIST']); n_props = length(prop_list); error(nargchk(0, 2*n_props, nargin,'string')); % Check to see if any input arguments are CoordSystem objects. If % so, then this object is being created from another similar object % and there is no need to create the Origin and/or CG CoordSystems. if ~nargin || ~strmatch('coord_system',varargin(1:2:end),'exact') obj.add_coord_system; % Add Origin CS end % Child-specific default obj.name = 'New Cone'; % Property Name-Value pair matching for ii=1:2:nargin prop = varargin{ii}; val = varargin{ii+1}; idx = strmatch(lower(prop),lower(prop_list),'exact'); if isempty(idx) error('%s: This property is unknown',... 'or cannot be set during the construction',... 'of the object: %s ',prop,mfilename); else obj.(prop_list{idx}) = val; end end % Create default CoordSystems specific to this Primitive. These are % not editable and are wrt the Origin of this Shape. % CG if obj.n_coord_system < 2 csTmp = CoordSystem('name','CG',... 'is_deletable',false,... 'is_fixed',true,... 'origin',[0 -obj.height/6 0],... 'parent_shape',obj); csTmp.reference_CS = obj.coord_system{1}; obj.add_coord_system(csTmp); end obj.attach_generator(); obj.attach_primitive(); % % Move the CG to where it belongs (Java3D places it at the midpoint % % between the base and the tip). % cur_origin = obj.coord_system{1}.origin; % cur_origin(2) = cur_origin(2) - 1/6*obj.height; % obj.coord_system{1}.origin= cur_origin; end
SET Methods
function set.base_radius(obj, in) prop_name = 'base_radius'; prop_type = 'double'; [valid_flag in] = Validate.SCALAR(in,'type',prop_type,'minVal',eps); if valid_flag obj.(prop_name) = in; end end function set.height(obj, in) prop_name = 'height'; prop_type = 'double'; [valid_flag in] = Validate.SCALAR(in,'type',prop_type,'minVal',eps); if valid_flag obj.(prop_name) = in; if obj.n_coord_system > 1 obj.update_CG(); end end end function set.top_radius(obj, in) prop_name = 'top_radius'; prop_type = 'double'; [valid_flag in] = Validate.SCALAR(in,'type',prop_type,'minVal',0); if valid_flag obj.(prop_name) = in; end end
GET Methods
function vol = get.volume(obj) %volume = pi*h/3(R^2+Rr+r^2) vol = (pi*obj.height/3)*(obj.base_radius^2 + obj.base_radius*obj.top_radius + obj.top_radius^2); end function inertia_tensor = get.moment_of_inertia_about_CG(obj) density = obj.material.density; base_rad = obj.base_radius; top_rad = obj.top_radius; h = obj.height; % if it is a full cone and not a frustum if(base_rad == 0 || top_rad == 0) if (base_rad == 0) R = top_rad; else R = base_rad; end if (R == 0) warndlg('Both the top radius and base radius of the cone are zero.'); end mi = Cone.MI_CG_FullCone(density,R,h); inertia_tensor = [mi.xx 0 0;0 mi.yy 0;0 0 mi.zz]; return; end x = top_rad/base_rad; y = x^2 + x + 1; z = (x^2 + 2*x + 3)/(4*y); if (top_rad > base_rad) R1 = top_rad; R2 = base_rad; CG_from_base_center = z*h; elseif (top_rad < base_rad) R1 = base_rad; R2 = top_rad; CG_from_base_center = (1-z)*h; else warndlg('You have given both the radii to be same. Please use cylindrical primitive instead'); R1 = base_rad; R2 = R1- R1*eps; CG_from_base_center = (1-z)*h; end a = h*R2/(R1-R2); % top cone height mi_topcone = Cone.MI_CG_FullCone(density,R2,a); mi_basecone = Cone.MI_CG_FullCone(density,R1,h+a); Ixx = (mi_basecone.xx + mi_basecone.mass*((h+a)/4 - CG_from_base_center)^2) - (mi_topcone.xx + mi_topcone.mass*(h+(a/4)-CG_from_base_center)^2); Izz = Ixx; Iyy = mi_basecone.yy - mi_topcone.yy; inertia_tensor = [Ixx 0 0;0 Iyy 0;0 0 Izz]; end
end methods ( Access = 'public')
Public HELPER Methods
function attach_primitive(obj) r = obj.base_radius; h = obj.height; the_appearance = obj.material.appearance; p = org.j3d.renderer.java3d.geom.Cone(h, r, the_appearance); p.setName(mfilename); % Store primitive for future modifications as necessary. obj.primitive = p; obj.attach_primitive_common(p); % obj.attach_primitive_common(com.sun.j3d.utils.geometry.Cone(r, h, the_appearance)); % Used to be obj.attach_primitive@PrimitiveShape(...), but resulted % in top down calling sequence, which we don't want. end function attach_generator(obj) % This needs to be a protected method to match the Access level of % the parent's method of the same name. obj.generator = org.j3d.geom.ConeGenerator(); end
end
methods ( Static = true )
LOADOBJ Method
function B = loadobj(A) % We use loadobj so that when a stored object is loaded, we can % perform necessary steps that are contained in the constructor. We % have to do this because the constructor is not executed when an % object is loaded. Log.msg(sprintf('\n%s::%s',mfilename,'loadobj (Entering)')); prop_list = eval([mfilename '.PROPERTY_LIST']); % Construct object using the stored properties storedFields = fieldnames(A); args = cell(0); for ii=1:length(storedFields) prop = storedFields{ii}; idx = strmatch(lower(prop),lower(prop_list),'exact'); if ~isempty(idx) args{end+1} = prop; %#ok<AGROW> args{end+1} = A.(storedFields{ii}); %#ok<AGROW> end end B = Cone(args{:}); Log.msg(sprintf('%s::%s',mfilename,'loadobj (Exiting)')); end
end methods ( Access = 'private')
Private HELPER Methods
function update_CG(obj) % Whenever the Cone height changes, you need to update the CG. obj.coord_system{2}.origin = [0 -obj.height/6 0]; end
end methods ( Access = 'private', Static = true )
Static Private HELPER Methods
function mi = MI_CG_FullCone(rho, r, h) %% assuming cone height is along y-dir % This MI calculation assumes full cone (not a frustum) M = rho*pi*r^2*h/3; mi.xx = 3/80*(M*h^2) + 3/20*(M*r^2); mi.yy = 3/10*(M*r^2); mi.zz = mi.xx; mi.mass = M; end
end
end