function unnecessarily_complicated_gears()
% source code for drawing unnecessarily complicated gearing
% The shape of the gears is not precise, it creates a decent GIF and a SVG.
%
% 2017-06-20 Jahobr (update 2019-04-14 Jahobr)
teethSun = 48; %
teethPlan = 12; %
teethRing = teethSun+teethPlan*2;
nPlan = 12; % number of planets
teethSun_top = 24;
teethHub_spoked = 60;
teethHub_back = 24;
teethBigSpoke = 96;
teethRackTrans_Bottom = 25;
teethRackTrans_Top = 25/5*4;
teethRackDriver = 16;
module_Epicyclic = 1;
module_Hub_Spoke = 1.8;
module_Sun_Hub = 1.5;
module_LL = 0.8;
module_top = 0.9;
module_Rack = 1.4;
RGB.edge = [0 0 0 ]; % Edge color
RGB.bkgd = [1 1 1 ]; % white background
RGB.carrier = [0.1 0.7 0.1 ]; % green
RGB.sun = [0.95 0.65 0 ]; % yellow (obviously)
RGB.palnet = [0.2 0.2 1 ]; % blue (obviously)
RGB.ring = [1 0.2 0.2 ]; % red
RGB.hub = [0.6 0.2 0.8 ]; % violet
RGB.spoke = [0.5 0.5 0.5 ]; %
RGB.rackTrans = [0.4 0.24 0.08]; %
RGB.rack = [1 0.5 0.2 ]; %
RGB.rackDrive = [0.8 0.3 0.2 ]; %
RGB.LL_1 = [0.4 0.6 0.6 ]; %
RGB.LL_2 = [0.3 0.6 0.8 ]; %
RGB.top = [0.5 0.7 1 ]; %
RGB = structfun(@(q)round(q*255)/255, RGB, 'UniformOutput',false); % round to values that are nicely uint8 compatible
diameterSun = module_Epicyclic.*teethSun;
diameterPlan = module_Epicyclic.*teethPlan;
diameterCarr = diameterSun+diameterPlan;
dist_Sun_Hub = mean([module_Sun_Hub*teethSun_top, module_Sun_Hub*teethHub_spoked]);
centerHub = [dist_Sun_Hub*cosd(60) -dist_Sun_Hub*sind(60)];
dist_Hub_Spoke = mean([module_Hub_Spoke*teethHub_back, module_Hub_Spoke*teethBigSpoke]) ;
centerSpoke = [dist_Hub_Spoke*cosd(60) +dist_Hub_Spoke*sind(60)]+centerHub;
dist_Hub_RackTrans = mean([module_Sun_Hub*teethHub_spoked, module_Sun_Hub*teethRackTrans_Bottom]);
centerRackTrans = [dist_Hub_RackTrans*cosd(53) +dist_Hub_RackTrans*sind(53)]+centerHub;
dist_RackTrans_RGB.rackDriver = mean([module_Rack*teethRackTrans_Top, module_Rack*teethRackDriver ]);
centerRackDriver = [dist_RackTrans_RGB.rackDriver*cosd(55) -dist_RackTrans_RGB.rackDriver*sind(55)]+centerRackTrans;
[pathstr,fname] = fileparts(which(mfilename)); % save files under the same name and at file location
xLimits = [-20 100];
yLimits = [-60 40];
xRange = xLimits(2)-xLimits(1);
yRange = yLimits(2)-yLimits(1);
ySize = 700; % final gif size
xSize = floor(ySize/yRange*xRange); % pixel
screenSize = get(groot,'Screensize')-[0 0 5 20]; % [1 1 width height] (minus tolerance for figure borders)
scaleReduction = min(...% reduction for nice antialiasing (for >1 you need a 4K monitor or a virtural combination of several monitors using "Nvidia Surround" to fit the figure)
floor(screenSize(4)/ySize), floor(screenSize(3)/xSize));
linW = 2.5/1000 * (ySize*scaleReduction); % LineWidth
nFrames = 170;
figHandle = figure(15674455); clf
set(figHandle, 'Units','pixel');
set(figHandle, 'Position',[1 1 xSize*scaleReduction ySize*scaleReduction]); % big start image for antialiasing later [x y width height]
set(figHandle, 'GraphicsSmoothing','on') % requires at least version 2014b
set(figHandle,'MenuBar','none', 'ToolBar','none'); % free real estate for a maximally large image
set(figHandle, 'Color',RGB.bkgd); % white background
axesHandle = axes;
hold(axesHandle,'on');
axis off % invisible axes (no ticks)
axis equal;
setXYlim(axesHandle,xLimits,yLimits);
angleCarrier = -linspace(0,pi*2/nPlan,nFrames+1); % define gear position in frames
angleCarrier = angleCarrier(1:end-1); % remove last frame, it would be double
anglePlan = angleCarrier.*( teethSun/teethPlan+1 ); % gear ratio
anglePlan = -anglePlan + (pi/teethPlan); % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
angleSun = angleCarrier.* (1+teethRing/teethSun); % gear ratio
angleSun = angleSun + 0; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
angleRing = zeros(size(anglePlan));
reducedRGBimage = uint8(ones(ySize,xSize,3,nFrames)); % allocate
for iFrame = 1:nFrames
cla(axesHandle); % fresh frame
%% background wheels
% Hub background wheel 24 teeth rotates 2, interacts with spoked
drawSpurWheel(centerHub,teethHub_back ,module_Hub_Spoke,... % center, number of teeth, module
RGB.hub*0.6, linW, RGB.edge,... % patch color, LineWidth, line color
-angleSun(iFrame)/2.5,... % angle of rotaion
NaN, 1, 3, 1); % nSpoke, spokeW, sideOffset, shaftDiameter
% fine Spoked wheel 96 teeth rotates 2
drawSpurWheel(centerSpoke,teethBigSpoke, module_Hub_Spoke,... % center, number of teeth, module
RGB.spoke, linW, RGB.edge,... % patch color, LineWidth, line color
angleSun(iFrame)/2.5/4 + pi/teethBigSpoke,... % angle of rotaion
teethBigSpoke/2, 0.5, 0, 13.2); % nSpoke, spokeW, sideOffset, shaftDiameter
%% %%%%%%%%%% Epicyclic_Gearing %%%%%%%%%%%%%%%%%%%%%
% ring
drawRingGear(teethRing,module_Epicyclic,RGB.ring,linW,RGB.edge,angleRing(iFrame))
% sun
drawSpurWheel([0 0],teethSun ,module_Epicyclic,... % center, number of teeth, module
RGB.sun, linW, RGB.edge,... % patch color, LineWidth, line color
angleSun(iFrame),... % angle of rotaion
NaN, 0, 0, 0); % nSpoke, spokeW, sideOffset, shaftDiameter
% planets
angPlan = linspace(0,2*pi,nPlan+1);
angPlan = angPlan(1:end-1);
for iPlan = angPlan
[X,Y] = pol2cart(iPlan+angleCarrier(iFrame) ,diameterCarr/2);
drawSpurWheel([X,Y],teethPlan,module_Epicyclic,... % center, number of teeth, module
RGB.palnet, linW, RGB.edge,... % patch color, LineWidth, line color
anglePlan(iFrame),... % angle of rotaion
NaN, 0, 0, 0); % nSpoke, spokeW, sideOffset, shaftDiameter
end
% carrier
angCarr = linspace(0,2*pi,nPlan+1);
[X,Y] = pol2cart([angCarr fliplr(angCarr)]+angleCarrier(iFrame) ,[ones(size(angCarr))*diameterCarr/2.07 ones(size(angCarr))* diameterCarr/1.93]);
patch(X,Y,RGB.carrier,'EdgeColor',RGB.edge,'LineWidth',linW) % full outer disc
for iPlan = angPlan
[X,Y] = pol2cart(iPlan+angleCarrier(iFrame) ,diameterCarr/2);
circlePatch(X,Y,diameterPlan*0.25,RGB.carrier,linW,RGB.edge);
circlePatch(X,Y,diameterPlan*0.15,RGB.palnet, linW,RGB.edge);
end
%% connection Epicyclic Gearing and hub
% 24 teeth, rotates 5 teeth
drawSpurWheel([0 0],teethSun_top ,module_Sun_Hub,... % center, number of teeth, module
1-(1-RGB.sun)*0.5, linW, RGB.edge,... % patch color, LineWidth, line color
angleSun(iFrame),... % angle of rotaion
NaN, 0, 0, 3); % nSpoke, spokeW, sideOffset, shaftDiameter
% spoked hub wheel: 60 teeth; rotates 5
drawSpurWheel(centerHub,teethHub_spoked ,module_Sun_Hub,... % center, number of teeth, module
RGB.hub, linW, RGB.edge,... % patch color, LineWidth, line color
-angleSun(iFrame)/2.5 +pi/teethHub_spoked,... % angle of rotaion
teethSun/2*2.5/5,... % 12 nSpoke,
1, 5.5, 7); % spokeW, sideOffset, shaftDiameter
%% chain of wheels on the Top
% on top big spoked (wheel 96 teeth rotates 2) 48 teeth rotates 1
drawSpurWheel(centerSpoke,48 ,module_top,... % center, number of teeth, module
1-(1-RGB.spoke)*0.7, linW, RGB.edge,... % patch color, LineWidth, line color
angleSun(iFrame)/2.5/4+0.2,... % angle of rotaion
NaN, 1, 0, 7); % nSpoke, spokeW, sideOffset, shaftDiameter
% top idler , meshing with small wheel big spoked; 17 teeth rotates 1
drawSpurWheel([57.35 31],17 ,module_top,... % center, number of teeth, module
RGB.top, linW, RGB.edge,... % patch color, LineWidth, line color
-angleSun(iFrame)/2.5/4 * 48/17 - 0.067,... % angle of rotaion
NaN, 1, 0, 3); % nSpoke, spokeW, sideOffset, shaftDiameter
% last on top, meshing with idler; 23 teeth rotates 1
drawSpurWheel([42.34 41],23 ,module_top,... % center, number of teeth, module
RGB.top*0.8, linW, RGB.edge,... % patch color, LineWidth, line color
angleSun(iFrame)/2.5/4 * 48/23 +0.12,... % angle of rotaion
NaN, 1, 0, 3); % nSpoke, spokeW, sideOffset, shaftDiameter
%% Rack
% Rack-Transmission; meshes in Hub-spoked 25 teeth rotates 5
drawSpurWheel(centerRackTrans,teethRackTrans_Bottom,module_Sun_Hub,... % center, number of teeth, module
RGB.rackTrans, linW, RGB.edge,... % patch color, LineWidth, line color
angleSun(iFrame)/teethRackTrans_Bottom*teethSun_top +0.003,... % angle of rotaion
NaN, 1, 0, 0); % nSpoke, spokeW, sideOffset, shaftDiameter
% Rack-Transmission; meshes in Rack-driver; 15 teeth rotates 3
drawSpurWheel(centerRackTrans,teethRackTrans_Top,module_Rack,... % center, number of teeth, module
1-(1-RGB.rackTrans)*0.7,linW, RGB.edge,... % patch color, LineWidth, line color
angleSun(iFrame)/teethRackTrans_Bottom*teethSun_top +0.157,... % angle of rotaion
NaN, 1, 0, 2.5); % nSpoke, spokeW, sideOffset, shaftDiameter
% Rack-driver; idler between Rack-Transmission and Rack
drawSpurWheel(centerRackDriver,teethRackDriver ,module_Rack,... % center, number of teeth, module
RGB.rackDrive, linW, RGB.edge,... % patch color, LineWidth, line color
-angleSun(iFrame)/teethRackTrans_Bottom*teethSun_top *15/12 +pi/teethRackDriver ,... % angle of rotaion
NaN, 0.5, 0, 2); % nSpoke, spokeW, sideOffset, shaftDiameter
drawRack([centerRackDriver(1)+module_Rack*teethRackDriver/2 centerRackDriver(2)],50,module_Rack,...
RGB.rack,linW,RGB.edge,... % patch color, LineWidth, line color
-angleSun(iFrame)/teethRackTrans_Bottom*teethSun_top *module_Rack/2*teethRackTrans_Top)
%% lower left
% on top of hub; rotates 3 teeth
drawSpurWheel(centerHub,36 ,module_LL,... % center, number of teeth, module
1-(1-RGB.hub)*0.9, linW, RGB.edge,... % patch color, LineWidth, line color
-angleSun(iFrame)/2.5,... % angle of rotaion
NaN, 1, 3, 9); % nSpoke, spokeW, sideOffset, shaftDiameter
% next to hub; lower left trasmission; bottom wheel; rotates 3 teeth
drawSpurWheel([centerHub(1)-28.8 centerHub(2)],36 ,module_LL,... % center, number of teeth, module
RGB.LL_1*0.5, linW, RGB.edge,... % patch color, LineWidth, line color
angleSun(iFrame)/2.5 +pi/36,... % angle of rotaion
NaN, 1, 0, 1); % nSpoke, spokeW, sideOffset, shaftDiameter
% lower left trasmission; top wheel; rotates 2 teeth
drawSpurWheel([centerHub(1)-28.8 centerHub(2)],24 ,module_LL,... % center, number of teeth, module
RGB.LL_1, linW, RGB.edge,... % patch color, LineWidth, line color
angleSun(iFrame)/2.5 ,... % angle of rotaion
NaN, 1, 0, 4); % nSpoke, spokeW, sideOffset, shaftDiameter
% lower left wheel; rotates 2 teeth; rotates 1 spoke
drawSpurWheel([centerHub(1)-57.6 centerHub(2)],48 ,module_LL,... % center, number of teeth, module
RGB.LL_2, linW, RGB.edge,... % patch color, LineWidth, line color
-angleSun(iFrame)/2.5 /2 +pi/48,... % angle of rotaion
24, 1, 0, 10); % nSpoke, spokeW, sideOffset, shaftDiameter
%% save animation
setXYlim(axesHandle,xLimits,yLimits);
f = getframe(figHandle);
reducedRGBimage(:,:,:,iFrame) = imReduceSize(f.cdata,scaleReduction); % the size reduction: adds antialiasing
% if iFrame == 10 % SVG
% if ~isempty(which('plot2svg'))
% plot2svg(fullfile(pathstr, [fname '_a.svg']),figHandle) % by Juerg Schwizer
% else
% disp('plot2svg.m not available; see http://www.zhinst.com/blogs/schwizer/');
% end
% end
end
map = createImMap(reducedRGBimage,128,struct2map(RGB)); % colormap
im = uint8(ones(ySize,xSize,1,nFrames)); % allocate
for iFrame = 1:nFrames
im(:,:,1,iFrame) = rgb2ind(reducedRGBimage(:,:,:,iFrame),map,'nodither');
end
imwrite(im,map,fullfile(pathstr, [fname '_a.gif']),'DelayTime',1/25,'LoopCount',inf) % save gif
disp([fname '.gif has ' num2str(numel(im)/10^6 ,4) ' Megapixels']) % Category:Animated GIF files exceeding the 100 MP limit
function drawSpurWheel(center,toothNumber,module,colFilling,linW,linC,startOffset,nSpoke,spokeW,sideOffset,shaftDia)
% DRAWSPURWHEEL - draw a simple Toothed Wheel
% center: [x y]
% toothNumber: scalar
% module: scalar tooth "size"
% colFilling: color of filling [r g b]
% linW: LineWidth (scalar)
% linC: LineColor
% startOffset: start rotation (scalar)[rad]
% nSpoke: number of spokes; NaN for filled wheel (scalar integer)
% spokeW: spoke width [modules]
% sideOffset: spoke side offset [modules]
% shaftDia: inner shaft diameter [modules]
effectiveRadius = module*toothNumber/2; % effective effectiveRadius
outsideRadius = effectiveRadius+1* module; % +---+ +---+
upperRisingRadius = effectiveRadius+0.5*module; % / \ / \
% effective Radius % / \ / \
lowerRisingRadius = effectiveRadius-0.5*module; % I I I I
rootRadius = effectiveRadius-1.1*module; % + - - - + + - - - + +
angleBetweenTeeth = 2*pi/toothNumber; % angle between 2 teeth
angleOffPoints = (0:angleBetweenTeeth/16:(2*pi));
angleOffPoints = angleOffPoints+startOffset; % apply rotation offset
angleOffPoints(7:16:end) = angleOffPoints(7:16:end) + 1/toothNumber^1.2; % hack to create smaller tooth tip
angleOffPoints(11:16:end) = angleOffPoints(11:16:end) - 1/toothNumber^1.2; % hack to create smaller tooth tip
angleOffPoints(8:16:end) = (angleOffPoints(7:16:end) + angleOffPoints(9:16:end))/2; % shift the neighbouring tip point in accordingly
angleOffPoints(10:16:end) = (angleOffPoints(11:16:end) + angleOffPoints(9:16:end))/2; % shift the neighbouring tip point in accordingly
angleOffPoints(6:16:end) = angleOffPoints(6:16:end) + 1/toothNumber^1.7; % hack to create slender upperRisingRadius
angleOffPoints(12:16:end) = angleOffPoints(12:16:end) - 1/toothNumber^1.7; % hack to create slender upperRisingRadius
radiusOffPoints = angleOffPoints; % allocate with correct site
radiusOffPoints( 1:16:end) = rootRadius; % center bottom I
radiusOffPoints( 2:16:end) = rootRadius; % left bottom I
radiusOffPoints( 3:16:end) = rootRadius; % left bottom corner +
radiusOffPoints( 4:16:end) = lowerRisingRadius; % lower rising bottom \
radiusOffPoints( 5:16:end) = effectiveRadius; % rising edge \
radiusOffPoints( 6:16:end) = upperRisingRadius; % upper rising edge \
radiusOffPoints( 7:16:end) = outsideRadius; % right top corner +
radiusOffPoints( 8:16:end) = outsideRadius; % right top I
radiusOffPoints( 9:16:end) = outsideRadius; % center top I
radiusOffPoints(10:16:end) = outsideRadius; % left top I
radiusOffPoints(11:16:end) = outsideRadius; % left top corner +
radiusOffPoints(12:16:end) = upperRisingRadius; % upper falling edge /
radiusOffPoints(13:16:end) = effectiveRadius; % falling edge /
radiusOffPoints(14:16:end) = lowerRisingRadius; % lower falling edge /
radiusOffPoints(15:16:end) = rootRadius; % right bottom corner +
radiusOffPoints(16:16:end) = rootRadius; % right bottom I
[X,Y] = pol2cart(angleOffPoints,radiusOffPoints);
X = X+center(1); % center offset
Y = Y+center(2); % center offset
if ~isnan(nSpoke)
for iSpoke = 1:nSpoke
Xs = ([-1 1 1 -1]+sideOffset)*module*spokeW;
Ys = [ 1 1 0 0]*