⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gear3d.m

📁 matlab源代码,适用于开发研究,带来很好的学习效果.
💻 M
字号:
function gear3d(varargin)
%   GEAR3D   GUI example of 3D gear.
%   GEAR3D will pop up a GUI example of 3D gear. The gear rolls on a geared
%   ground based on the mouse location. It uses the x-location of the mouse
%   pointer for the gear location. Use the arrow keys to change the view.
%   Press SPACEBAR to reset the view. 
%
%   调用命令示例:
%     GEAR3D('teeth', 30)   - 默认值是 50.
%     GEAR3D('spokes', 4)   - 默认值是 8.
%     GEAR3D('ratio', 2)    - 默认值是 3. 
%   该命令只接受正值的参数。


% -----------------------------参数的默认数值-----------------------------------%
% Number of teeth
numteeth  = 50;
% Number of spokes
numspokes = 8;
% Gear ratio 
rr        = 3;
% -----------------------------处理函数的参数属性-----------------------------------%
if mod(nargin, 2) == 1
  error('Optional arguments must come in pairs.');
end
if nargin
  opt = varargin(1:2:end);
  val = varargin(2:2:end);
  validOpts = {'teeth', 'spokes', 'ratio'};
  for iArg = 1:length(opt)
    id = strmatch(lower(opt{iArg}), validOpts);
    if isempty(id)
      error('Invalid option. Valid options: ''teeth'', ''spokes'', ''ratio''');
    else
      switch strmatch(lower(opt{iArg}), validOpts)
        
        case 1
          if isnumeric(val{iArg}) & length(val{iArg}) == 1
            numteeth = round(abs(val{iArg}));
          end
          
        case 2
          if isnumeric(val{iArg}) & length(val{iArg}) == 1
            numspokes = round(abs(val{iArg}));
          end
          
        case 3
          if isnumeric(val{iArg}) & length(val{iArg}) == 1
            rr = round(abs(val{iArg}));
          end
          
      end
    end
  end
end
%------------------------------计算参数的数值--------------------------%
% Gear part radii
r1 = 1;
r2 = 3;
r3 = 10;
r4 = 11;
r5 = 13;
r6 = 12;
% Radius to the center of gear teeth
r = (r5 + r6) / 2;
% Height of gear teeth
h = r5 - r6;
% Radius to the center of ground teeth
l = r * rr;
% Ground radii
l1 = l  - h/2;
l2 = l  + h/2;
l3 = l2 + 2;
%------------------------------定义齿轮对象的数据--------------------------%
[x0,y0,z0]       = cylinder([r6], numteeth*4);  % teeth groove
[x1,y1,z1]       = cylinder([r1, r1, r2, r2, r1], numteeth*4);  % spokes
[x2,y2,z2]       = cylinder([r3, r3, r4, r4, r5, r5, r4, r4, r3], numteeth*4);  % gear teeth
z1([1, 4, 5], :) =  2;
z1(2:3, :)       = -2;
z2([1, 8, 9], :) =  2;
z2(2:3, :)       = -2;
z2(4:5, :)       = -1;
z2(6:7, :)       =  1;
x2(5:6,1:4:end)  = x0(1:2,1:4:end);
x2(5:6,2:4:end)  = x0(1:2,2:4:end);
y2(5:6,1:4:end)  = y0(1:2,1:4:end);
y2(5:6,2:4:end)  = y0(1:2,2:4:end);
%------------------------------定义轮辐对象的数据--------------------------%
interval  = round(length(x1) / numspokes);
for id = 1:4
  x1(3:4, id:interval:end) = x2(1:2, id:interval:end);
  y1(3:4, id:interval:end) = y2(1:2, id:interval:end);
end
%------------------------------定义底面对象的数据--------------------------%
[x3, y3, z3]         = cylinder([l2, l2, l3, l3, l2], numteeth * rr * 4);
[x4, y4, z4]         = cylinder(l1, numteeth * rr * 4);
z3([1 4 5], :)       =  4;
z3([2 3], :)         = -4;
x3([1 2 5], 1:4:end) = x4([1 1 1], 1:4:end);
x3([1 2 5], 2:4:end) = x4([1 1 1], 2:4:end);
y3([1 2 5], 1:4:end) = y4([1 1 1], 1:4:end);
y3([1 2 5], 2:4:end) = y4([1 1 1], 2:4:end);
%------------------------------将底面设置为半圆-----------------------------%
len            = round(length(x3) / 2);
x3(:, len:end) = [];
y3(:, len:end) = [];
z3(:, len:end) = [];
%------------------------------创建图形对象---------------------------------%
fH = findobj('Type', 'figure', 'Tag', 'solidmodelGUI');
if ishandle(fH)
  close(fH);
end
fH = figure(...
  'Name'       , sprintf('3D Gear: View = [%3.0f, %3.0f]', 0, -50), ...
  'NumberTitle', 'off', ...
  'Units'      , 'normalized', ...
  'Position'   , [.1, .1, .8, .8], ...
  'Tag'        , 'solidmodelGUI');
axes(...
  'Units'   , 'normalized', ...
  'Position', [0, .9, 1, .1], ...
  'XLim'    , [-1, 1], ...
  'YLim'    , [-1, 1], ...
  'Visible' , 'off');
text(0, 0, ...
  {'Move the mouse left and right within the figure window to move the gear.',...
    'Use ARROW keys to change the view. SPACE to reset view.'}, ...
  'HorizontalAlignment' , 'center', ...
  'VerticalAlignment'   , 'middle', ...
  'Color'               , 'red');
axH = axes('Units', 'normalized', ...
  'Position', [0, 0, 1, .9]);
%------------------------------绘制齿轮对象-----------------------------%

%------------------------------绘制齿轮---------------------------------%
gearH(1) = surface(x1,y1,z1, ...
  'EdgeColor', [.3, .3, .3], ...
  'EdgeAlpha',  0, ...
  'FaceColor', [.5, .5, 1]);
%------------------------------绘制轮齿--------------------------------%
gearH(2) = surface(x2,y2,z2, ...
  'EdgeColor', [.3, .3, .3], ...
  'EdgeAlpha', .1, ...
  'FaceColor', [.5, .5, 1]);
%------------------------------绘制底面--------------------------------%
surface(x3,y3,z3, ...
  'EdgeColor', [.3, .3, .3], ...
 'EdgeAlpha', .1, ...
  'FaceColor', [.5, 1, .5], ...
  'FaceAlpha', .5);
%------------------------------设置图形的视角---------------------------%
set(axH, 'View', [0, -50]);
axis equal manual off;
set(axH, 'CameraViewAngleMode', 'manual');
%------------------------------添加光源--------------------------------%
light('Position', [50 , 0, -20]);
light('Position', [-50, 0, -20]);
%-----------------------------计算图形大小并传递参数---------------------%
sz1 = size(x1);
sz2 = size(x2);
set(fH, ...
  'Visible'              , 'on', ...
  'KeyPressFcn'          , {@myKeyPressFcn, axH}, ...
  'WindowButtonMotionFcn', {@myMotionFcn, gearH, x1, x2, y1, y2, r, l, sz1, sz2});
%------------------------------设置齿轮的初始位置-------------------------%
myMotionFcn(gcf, [], gearH, x1, x2, y1, y2, r, l, sz1, sz2);

%-----------------myKeyPressFcn函数:单击方向键调整视角--------------------%  
function myKeyPressFcn(obj, edata, axH)
k = get(obj, 'CurrentKey');
aZeL = get(axH, 'View');

switch lower(k)
  case 'uparrow'
    aZeL(2) = min([aZeL(2) + 10,  90]);
  case 'downarrow'
    % -90 doesn't work well when rotated left or right
    aZeL(2) = max([aZeL(2) - 10, -89.9999]);
  case 'leftarrow'
    aZeL(1) = max([aZeL(1) - 10, -90]);
  case 'rightarrow'
    aZeL(1) = min([aZeL(1) + 10,  90]);
  case 'space'
    aZeL    = [0, -50];
end
set(axH, 'View', aZeL);
set(obj, 'Name', sprintf('3D Gear: View = [%3.0f, %3.0f]', aZeL));

%-----------------myMotionFcn函数:使用鼠标来调整齿轮--------------------%  
function myMotionFcn(obj, edata, gearH, x1, x2, y1, y2, r, l, sz1, sz2)
pt = get(obj, 'CurrentPoint');
d = l - r;
x0 = -d + pt(1) * d * 2;
y0 = sqrt(abs(d^2 - x0^2));
th1 = atan2(x0, y0) - pi/2;
th = (th1 - (th1 * (l / r)));
%----------------------------旋转齿轮对象---------------------------------%

%---------------------------设置旋转角度距阵------------------------------%
cosa = cos(-th);
sina = sin(-th);
rot  = [cosa, -sina; sina, cosa]';
newxy1   = [x1(:), y1(:)];
newxy2   = [x2(:), y2(:)];
newxy1   = newxy1 * rot;
newxy2   = newxy2 * rot;
newx1    = x0 + reshape(newxy1(:, 1), sz1);
newy1    = y0 + reshape(newxy1(:, 2), sz1);
newx2    = x0 + reshape(newxy2(:, 1), sz2);
newy2    = y0 + reshape(newxy2(:, 2), sz2);
%---------------------------设置对象的新位置------------------------------%
set(gearH, {'XData', 'YData'}, {newx1, newy1; newx2, newy2});

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -