File:LissajousCurvesWithGears a1 b2 p00 p025 p05.gif
Page contents not supported in other languages.
Tools
Actions
General
In other projects
Appearance
LissajousCurvesWithGears_a1_b2_p00_p025_p05.gif (527 × 527 pixels, file size: 7.77 MB, MIME type: image/gif, looped, 360 frames, 14 s)
![]() | This is a file from the Wikimedia Commons. Information from its description page there is shown below. Commons is a freely licensed media file repository. You can help. |
Summary
DescriptionLissajousCurvesWithGears a1 b2 p00 p025 p05.gif |
English: Lissajous curve crafted with gears. The figures shape is determined by the gear ratio between the lower left and the upper right wheel. The idler-wheel just transmits the movement and changes the direction of rotation. The gray markings on the upper right wheel show options of different phase shifts between 0 and π in steps of 1/8 of π.
Deutsch: Lissajous-Figur erstellt mit Zahnrädern. Die Figur ergibt sich aus dem Übersetzungsverhältnis zwischen dem unten linken und dem oberen rechten Rad. Das mittlere Rad überträgt nur die Bewegung; seine Zähnezahl spielt keine Rolle. Die grauen Markierungen am oberen rechten Rad zeigen mögliche Varianten des Phasenversatzes, von 0 bis π in Schritten von 1/8 π. |
Date | |
Source | Own work |
Author | Jahobr |
Other versions |
|
GIF development InfoField | |
Source code InfoField | MATLAB codefunction [] = LissajousCurvesWithGears()
% Source code for drawing gears that produce lissajous curves.
% The shape of the gears is not precise, it creates a decent GIF and a SVG.
%
% 2017-05-01 Jahobr
module = 1; % gear size
[pathstr,fname] = fileparts(which(mfilename)); % save files under the same name and at file location
RGB.black = [0 0 0 ];
RGB.white = [1 1 1 ];
RGB.cyan = [0 0.6 0.7]; % for phase shift 0.125
RGB.green = [0 0.7 0 ]; % for phase shift 0.25
RGB.blue = [0 0 1 ]; % for phase shift 0.5
RGB.red = [1 0 0 ]; % for phase shift 0.0
RGB.violet = [0.6 0.2 0.8]; % for horizontal line
RGB.brightGrey = [0.8 0.8 0.8]; % upper two Idler & "LeftRight gear"
RGB.grey = [0.5 0.5 0.5]; % lower left "UpDown gear"
RGB.paleCyan = 1-(1-RGB.cyan) *0.85; % dotted line
RGB.paleGreen = 1-(1-RGB.green) *0.85; % dotted line
RGB.paleBlue = 1-(1-RGB.blue) *0.85; % dotted line
RGB.paleRed = 1-(1-RGB.red) *0.85; % dotted line
RGB.paleViolet = 1-(1-RGB.violet)*0.85; % dotted line
RGB.violetGreyMix1 = sqrt(mean([RGB.paleViolet.^2;RGB.grey.^2; RGB.grey.^2],1)); % experience shows that matlab does not create...
RGB.violetGreyMix2 = sqrt(mean([RGB.paleViolet.^2;RGB.paleViolet.^2;RGB.grey.^2],1)); %...nice mix colors in this combination; enforced
RGB = structfun(@(q)round(q*255)/255, RGB, 'UniformOutput',false); % round to values that are nicely uint8 compatible
versionList ={};
versionList{end+1} = 'a1_b1_p00';
versionList{end+1} = 'a1_b1_p025';
versionList{end+1} = 'a1_b1_p05';
versionList{end+1} = 'a1_b1_p00_p025_p05';
versionList{end+1} = 'a1_b2_p00';
versionList{end+1} = 'a1_b2_p025';
versionList{end+1} = 'a1_b2_p05';
versionList{end+1} = 'a1_b2_p00_p025_p05';
versionList{end+1} = 'a1_b3_p00';
versionList{end+1} = 'a1_b3_p025';
versionList{end+1} = 'a1_b3_p05';
versionList{end+1} = 'a1_b3_p00_p025_p05';
versionList{end+1} = 'a1_b4_p00';
versionList{end+1} = 'a1_b4_p025';
versionList{end+1} = 'a1_b4_p05';
versionList{end+1} = 'a1_b4_p00_p025_p05';
versionList{end+1} = 'a2_b3_p00';
versionList{end+1} = 'a2_b3_p0125';
versionList{end+1} = 'a2_b3_p025';
versionList{end+1} = 'a2_b3_p00_p0125_p025';
versionList{end+1} = 'a3_b4_p00';
versionList{end+1} = 'a3_b4_p025';
versionList{end+1} = 'a3_b4_p05';
versionList{end+1} = 'a3_b4_p00_p025_p05';
for versionNr = 1:numel(versionList)
curVers = versionList{versionNr};
switch curVers(1:5)
case 'a1_b1'
a=1; b=1;
teeth = [48*a/b 48 48]; % [leftBottom leftTop rightTop]
case 'a1_b2'
a=1; b=2;
teeth = [48*a/b 48 48]; % [leftBottom leftTop rightTop]
case 'a1_b3'
a=1; b=3;
teeth = [48*a/b 50 48]; % [leftBottom leftTop rightTop]
case 'a1_b4'
a=1; b=4;
teeth = [48*a/b 50 48]; % [leftBottom leftTop rightTop]
case 'a2_b3'
a=2; b=3;
teeth = [48*a/b 48 48]; % [leftBottom leftTop rightTop]
case 'a3_b4'
a=3; b=4;
teeth = [48*a/b 48 48]; % [leftBottom leftTop rightTop]
otherwise
error('not defined')
end
ratio = a/b;
rotToRepetition = lcm(a,b)/a; % Least common multiple, to produce a closed curve
nFrames = 180*rotToRepetition; % 180 frames per rotation
MegaPixelTarget = 100*10^6; % Category:Animated GIF files exceeding the 100 MP limit
xySize = floor(sqrt(MegaPixelTarget/nFrames)); % gif size in 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)/xySize), floor(screenSize(3)/xySize));
if scaleReduction == 0; error('"MegaPixelTarget" not possible; use smaller target or bigger monitor'); end % check
diameter = module.*teeth;
% --- ---
% / 2 \ / 3 \
% ( Idler X LR ) Left-Right-Wheel
% \ / \ /
% >---< ---
% / 1 \
% ( UD ) + 0/0 of coordinates
% \ /
% --- Up-Down-Wheel
center_UD_wheel = [-diameter(3) 0]; % wheel for Up-Down movement
center_LR_wheel = [0 diameter(3)]; % wheel for Left-Right movement
[xout,yout] = circcirc(center_UD_wheel(1),center_UD_wheel(2),mean(diameter(1:2)),center_LR_wheel(1),center_LR_wheel(2),mean(diameter(2:3))); % Intersections
[centerIdler(2),ind] = max(yout);
centerIdler(1) = xout(ind);
figPosition = [1 1 xySize*scaleReduction xySize*scaleReduction]; % big start image for antialiasing later [x y width height]
figHandle = figure(15554461); clf
axesHandle = axes; hold(axesHandle,'on')
set(figHandle,'Units','pixel');
set(figHandle,'MenuBar','none', 'ToolBar','none'); % free real estate for a maximally large image
set(figHandle,'Position',figPosition); % big start image; reduction allows for subpixel LineWidth
set(figHandle,'GraphicsSmoothing','on') % requires at least version 2014b
set(figHandle,'Color',RGB.white); % white background
drawnow
if ~all(get(figHandle, 'Position')==figPosition)
error('figure Position could not be set')
end
liSc = xySize*scaleReduction/1000; % LineWidth scale; LineWidth is absolut, a bigger images needs thicker lines to keep them in proportion
xLimits = [-1.55 0.55]*diameter(3); % ADJUST
yLimits = [-0.55 1.55]*diameter(3); % ADJUST
set(axesHandle,'Position',[0 0 1 1]); % stretch axis as big as figure, [x y width height]
xlim(xLimits); ylim(yLimits); % set axis limits
axis off % invisible axes (no ticks)
axis equal; drawnow;
angles_UD_wheel = linspace(0, rotToRepetition *2*pi,nFrames+1); % angles for wheel responsible for Up-Down
angles_UD_wheel = angles_UD_wheel(1:end-1); % remove last frame, it would be double
nShift = find(angles_UD_wheel>pi/6,1,'first');
angles_UD_wheel = circshift(angles_UD_wheel,nShift,2); % shift a view frames to get good visibility of all lines in frame 1
idlerRatio = teeth(1)/teeth(2);
anglesIdler = angles_UD_wheel.*idlerRatio;
angles_LR_wheel = angles_UD_wheel*ratio;
switch curVers(1:5)
case 'a1_b1'
anglesIdlerToothAllign = anglesIdler + (2*pi/teeth(2)) *0.5; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
angles_LR_wheelToothAllign = angles_LR_wheel +(2*pi/teeth(3)) *0; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
case 'a1_b2'
anglesIdlerToothAllign = anglesIdler + (2*pi/teeth(2)) *-0.01; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
angles_LR_wheelToothAllign = angles_LR_wheel +(2*pi/teeth(3)) *0.36; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
case 'a1_b3'
anglesIdlerToothAllign = anglesIdler + (2*pi/teeth(2)) *0.43; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
angles_LR_wheelToothAllign = angles_LR_wheel +(2*pi/teeth(3)) *-0.21; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
case 'a1_b4'
anglesIdlerToothAllign = anglesIdler + (2*pi/teeth(2)) *-0.34; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
angles_LR_wheelToothAllign = angles_LR_wheel +(2*pi/teeth(3)) *-0.29; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
case 'a2_b3'
anglesIdlerToothAllign = anglesIdler + (2*pi/teeth(2)) *-0.29; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
angles_LR_wheelToothAllign = angles_LR_wheel +(2*pi/teeth(3)) *-0.23; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
case 'a3_b4'
anglesIdlerToothAllign = anglesIdler + (2*pi/teeth(2)) *0.62; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
angles_LR_wheelToothAllign = angles_LR_wheel +(2*pi/teeth(3)) *0.03; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
otherwise
error('not defined')
end
curvePoints = linspace(0,2*pi,500);
yCurvePoints00 = NaN(size(curvePoints)); % defaults
yCurvePoints0125 = NaN(size(curvePoints)); % defaults
yCurvePoints025 = NaN(size(curvePoints)); % defaults
yCurvePoints05 = NaN(size(curvePoints)); % defaults
if contains(curVers,'p00') % Phase shift 0
yCurvePoints00 = sin(b*curvePoints )*0.9*diameter(3)/2; % Lissajous curve
end
if contains(curVers,'p0125') % Phase shift 1/8*pi = 0.125*pi
yCurvePoints0125 = sin(b*curvePoints-pi/8)*0.9*diameter(3)/2; % Lissajous curve
end
if contains(curVers,'p025') % Phase shift 1/4*pi = 0.25*pi
yCurvePoints025 = sin(b*curvePoints-pi/4)*0.9*diameter(3)/2; % Lissajous curve
end
if contains(curVers,'p05') % Phase shift 1/2*pi = 0.5*pi
yCurvePoints05 = sin(b*curvePoints-pi/2)*0.9*diameter(3)/2; % Lissajous curve
end
xCurvePoints = sin(a* curvePoints )*0.9*diameter(3)/2; % Lissajous curve
x_y_Crank = [-module*2 -module*2 0.9*diameter(3)/2+module 0.9*diameter(3)/2+module;...
-module*2 module*2 module -module];
anglesPSmakerXw = linspace(0,pi,64+1)*ratio-pi/2; % marker for possible phase shifts
reducedRGBimage = ones(xySize,xySize,3,nFrames, 'uint8'); % allocate
for iFrame = 1:nFrames
cla(axesHandle)
plot([-1 0.51]*diameter(3),[ 0 0 ]*diameter(3),'-','Color',RGB.brightGrey,'LineWidth',3*liSc) % horizontal coordinateSystem
plot([ 0 0 ]*diameter(3),[1 -0.51]*diameter(3),'-','Color',RGB.brightGrey,'LineWidth',3*liSc) % vertival coordinateSystem
drawSpurWheel(center_UD_wheel,teeth(1),module,RGB.grey ,2.5*liSc,RGB.black, angles_UD_wheel(iFrame)); % Up-Down-Wheel [at lower left] (fast)
drawSpurWheel(centerIdler, teeth(2),module,RGB.brightGrey,2.5*liSc,RGB.black,-anglesIdlerToothAllign(iFrame)); % Idler-Wheel [at top left]
drawSpurWheel(center_LR_wheel,teeth(3),module,RGB.brightGrey,2.5*liSc,RGB.black, angles_LR_wheelToothAllign(iFrame)); % Left-Right-Wheel [at top right] (slow)
x_UD_Crank = cos(angles_UD_wheel(iFrame))*0.9*diameter(3)/2+center_UD_wheel(1); % Up-Down-Wheel
y_UD_Crank = sin(angles_UD_wheel(iFrame))*0.9*diameter(3)/2+center_UD_wheel(2); % Up-Down-Wheel
if ratio < 1 % draw extra crank
rotM = [cos(angles_UD_wheel(iFrame)) -sin(angles_UD_wheel(iFrame)); -sin(-angles_UD_wheel(iFrame)) cos(angles_UD_wheel(iFrame))]; % rotation matrix
vecTemp = rotM*x_y_Crank; % rotate crank
patch(vecTemp(1,:)+center_UD_wheel(1),vecTemp(2,:)+center_UD_wheel(2),RGB.grey,'EdgeColor',RGB.black,'LineWidth',2*liSc) % raw the crank trapezoid
end
x_LR_Crank00 = NaN; y_LR_Crank00 = NaN; % Left-Right-Wheel (defaults)
x_LR_Crank0125 = NaN; y_LR_Crank0125 = NaN; % Left-Right-Wheel (defaults)
x_LR_Crank025 = NaN; y_LR_Crank025 = NaN; % Left-Right-Wheel (defaults)
x_LR_Crank05 = NaN; y_LR_Crank05 = NaN; % Left-Right-Wheel (defaults)
if contains(curVers,'p00') % Phase shift 0
x_LR_Crank00 = sin( angles_LR_wheel(iFrame))*0.9*diameter(3)/2+center_LR_wheel(1); % Left-Right-Wheel (if used)
y_LR_Crank00 = -cos( angles_LR_wheel(iFrame))*0.9*diameter(3)/2+center_LR_wheel(2); % Left-Right-Wheel (if used)
end
if contains(curVers,'p0125') % Phase shift 1/8*pi = 0.125*pi
x_LR_Crank0125 = sin(pi/8*ratio+angles_LR_wheel(iFrame))*0.9*diameter(3)/2+center_LR_wheel(1); % Left-Right-Wheel (if used)
y_LR_Crank0125 = -cos(pi/8*ratio+angles_LR_wheel(iFrame))*0.9*diameter(3)/2+center_LR_wheel(2); % Left-Right-Wheel (if used)
end
if contains(curVers,'p025') % Phase shift 1/4*pi = 0.25*pi
x_LR_Crank025 = sin(pi/4*ratio+angles_LR_wheel(iFrame))*0.9*diameter(3)/2+center_LR_wheel(1); % Left-Right-Wheel (if used)
y_LR_Crank025 = -cos(pi/4*ratio+angles_LR_wheel(iFrame))*0.9*diameter(3)/2+center_LR_wheel(2); % Left-Right-Wheel (if used)
end
if contains(curVers,'p05') % Phase shift 1/2*pi = 0.5*pi
x_LR_Crank05 = sin(pi/2*ratio+angles_LR_wheel(iFrame))*0.9*diameter(3)/2+center_LR_wheel(1); % Left-Right-Wheel (if used)
y_LR_Crank05 = -cos(pi/2*ratio+angles_LR_wheel(iFrame))*0.9*diameter(3)/2+center_LR_wheel(2); % Left-Right-Wheel (if used)
end
plot([center_UD_wheel(1) x_UD_Crank ],[center_UD_wheel(2) y_UD_Crank ],'-','Color',RGB.black ,'LineWidth',3*liSc) % base line
plot([0 sin(angles_LR_wheel(iFrame))*0.9*diameter(3)/2]+center_LR_wheel(1),[0 -cos(angles_LR_wheel(iFrame))*0.9*diameter(3)/2]+center_LR_wheel(2),'-','Color',RGB.black,'LineWidth',3*liSc) % base line
for mark = 1:a-1
[X,Y] = pol2cart(2*mark*pi/a +angles_UD_wheel(iFrame),[0.9 0.6]*diameter(1)/2);
X = X+center_UD_wheel(1); % center offset
Y = Y+center_UD_wheel(2); % center offset
plot(X,Y,'-','Color',RGB.black,'LineWidth',3*liSc) % rotation marker line
end
for mark = 1:b-1
[X,Y] = pol2cart(2*mark*pi/b +angles_LR_wheel(iFrame)-pi/2,[0.9 0.6]*diameter(3)/2);
X = X+center_LR_wheel(1); % center offset
Y = Y+center_LR_wheel(2); % center offset
plot(X,Y,'-','Color',RGB.black,'LineWidth',3*liSc) % rotation marker line
end
[X,Y] = pol2cart(anglesPSmakerXw+angles_LR_wheel(iFrame),0.9*diameter(3)/2);
X = X+center_LR_wheel(1); % center offset
Y = Y+center_LR_wheel(2); % center offset
plot(X,Y,'-','Color',RGB.grey,'LineWidth',5*liSc) % marker for possible phase shifts
plot(X(1:8:end), Y(1:8:end) ,'.','Color',RGB.grey,'MarkerSize',30*liSc) % marker for possible phase shifts
plot(X(1:16:end),Y(1:16:end),'.','Color',RGB.grey,'MarkerSize',45*liSc) % marker for possible phase shifts
plot(xCurvePoints,yCurvePoints0125,'-','Color',RGB.cyan ,'LineWidth',5*liSc) % Lissajous curve
plot(xCurvePoints,yCurvePoints025, '-','Color',RGB.green,'LineWidth',5*liSc) % Lissajous curve
plot(xCurvePoints,yCurvePoints05, '-','Color',RGB.blue ,'LineWidth',5*liSc) % Lissajous curve
plot(xCurvePoints,yCurvePoints00, '-','Color',RGB.red ,'LineWidth',5*liSc) % Lissajous curve
plot([x_UD_Crank max(max(x_LR_Crank00,x_LR_Crank0125),max(x_LR_Crank025,x_LR_Crank05))],[y_UD_Crank y_UD_Crank],':','Color',RGB.paleViolet,'LineWidth',6*liSc) % left crank to curve
plot([x_LR_Crank0125 x_LR_Crank0125],[y_LR_Crank0125 y_UD_Crank],'.:','Color',RGB.paleCyan, 'LineWidth',6*liSc,'MarkerEdgeColor',RGB.cyan ,'MarkerSize',55*liSc) % crank to curve - verical
plot([x_LR_Crank025 x_LR_Crank025], [y_LR_Crank025 y_UD_Crank],'.:','Color',RGB.paleGreen,'LineWidth',6*liSc,'MarkerEdgeColor',RGB.green,'MarkerSize',55*liSc) % crank to curve - verical
plot([x_LR_Crank05 x_LR_Crank05], [y_LR_Crank05 y_UD_Crank],'.:','Color',RGB.paleBlue, 'LineWidth',6*liSc,'MarkerEdgeColor',RGB.blue ,'MarkerSize',55*liSc) % crank to curve - verical
plot([x_LR_Crank00 x_LR_Crank00], [y_LR_Crank00 y_UD_Crank],'.:','Color',RGB.paleRed, 'LineWidth',6*liSc,'MarkerEdgeColor',RGB.red ,'MarkerSize',55*liSc) % crank to curve - verical
plot(x_UD_Crank,y_UD_Crank ,'.','Color',RGB.violet,'MarkerSize',55*liSc) % color marker on crank
plot([x_LR_Crank00 x_LR_Crank0125 x_LR_Crank025 x_LR_Crank05],[y_UD_Crank y_UD_Crank y_UD_Crank y_UD_Crank],'o','Color',RGB.violet,'MarkerSize',16*liSc,'LineWidth',4*liSc) % traking points on top of the curve
%% save animation
xlim(xLimits); ylim(yLimits); % set axis limits
drawnow
% pause(0.01)
if iFrame == 1 % save svg
% if ~isempty(which('plot2svg'))
% posSave = get(figHandle, 'Position');
% set(figHandle, 'Position',[1 1 800 800]); % big start image for antialiasing later [x y width height]
% plot2svg(fullfile(pathstr, [fname '_' curVers '.svg']),figHandle) % by Juerg Schwizer
% set(figHandle, 'Position',posSave); % reset size
% else
% disp('plot2svg.m not available; see http://www.zhinst.com/blogs/schwizer/');
% end
end
f = getframe(figHandle);
reducedRGBimage(:,:,:,iFrame) = imReduceSize(f.cdata,scaleReduction); % allows subpixel lines
end
if numel(strfind(curVers,'p')) >= 3 % many curves at once
nColors = 64;
else
nColors = 32;
end
RGBcurrent = RGB; % copy colormap; to be pruned to the used colors
if isnan(x_LR_Crank0125)
RGBcurrent = rmfield(RGBcurrent,{'cyan','paleCyan'}); % remove unused colors
end
if isnan(x_LR_Crank025)
RGBcurrent = rmfield(RGBcurrent,{'green','paleGreen'}); % remove unused colors
end
if isnan(x_LR_Crank05)
RGBcurrent = rmfield(RGBcurrent,{'blue','paleBlue'}); % remove unused colors
end
if isnan(x_LR_Crank00)
RGBcurrent = rmfield(RGBcurrent,{'red','paleRed'}); % remove unused colors
end
startMap = cell2mat(struct2cell(RGBcurrent)); % struct2colormap; % list of map colors that are not allowed to be changed
map = createImMap(reducedRGBimage,nColors,startMap); % full colormap
im = uint8(ones(xySize,xySize,1,nFrames)); % allocate
for iFrame = 1:nFrames
im(:,:,1,iFrame) = rgb2ind(reducedRGBimage(:,:,:,iFrame),map,'nodither'); % rgb to colormap image
end
imwrite(im,map,fullfile(pathstr, [fname '_' curVers '.gif']),'DelayTime',1/25,'LoopCount',inf) % save gif
disp([fname '_' curVers '.gif has ' num2str(numel(im)/10^6 ,4) ' Megapixels']) % Category:Animated GIF files exceeding the 50 MP limit
end
function drawSpurWheel(center,toothNumber,module,fillC,linW,linC,startOffset)
% DRAWSPURWHEEL - draw a simple Toothed Wheel
% center: [x y]
% toothNumber: scalar
% module: scalar tooth "size"
% fillC: color of filling [r g b]
% linW: LineWidth
% linC: LineColor
% startOffset: start rotation (scalar)[rad]
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
patch(X,Y,fillC,'EdgeColor',linC,'LineWidth',linW)
plot(X,Y,'.','MarkerSize',2*linW,'Color',linC); % extra dots make corners look smoother
% %% effective Radius
% circle(center(1),center(2),effectiveRadius,linC,'-.',linW);
%% shaft
shaftRadius = module*6 /2; % small radius, assuming the effective radius a 6-tooth wheel would have
circle(center(1),center(2),shaftRadius,linC,'-',linW);
function h = circle(x,y,r,col,sty,linW)
% x: coordinates of the center
% y: coordinates of the center
% r: is the radius of the circle
% sty: LineStyle
% linW: LineWidth
angleOffPoints = linspace(0,2.001*pi,300);
xc = x + r*cos(angleOffPoints);
yc = y + r*sin(angleOffPoints);
h = plot(xc,yc,'Color',col,'LineWidth',linW,'LineStyle',sty);
function im = imReduceSize(im,redSize)
% Input:
% im: image, [imRows x imColumns x nChannel x nStack] (unit8)
% imRows, imColumns: must be divisible by redSize
% nChannel: usually 3 (RGB) or 1 (grey)
% nStack: number of stacked images
% usually 1; >1 for animations
% redSize: 2 = half the size (quarter of pixels)
% 3 = third the size (ninth of pixels)
% ... and so on
% Output:
% im: [imRows/redSize x imColumns/redSize x nChannel x nStack] (unit8)
%
% an alternative is : imNew = imresize(im,1/scaleReduction ,'bilinear');
% BUT 'bicubic' & 'bilinear' produces fuzzy lines
% IMHO this function produces nicer results as "imresize"
[nRow,nCol,nChannel,nStack] = size(im);
if redSize==1; return; end % nothing to do
if redSize~=round(abs(redSize)); error('"redSize" must be a positive integer'); end
if rem(nRow,redSize)~=0; error('number of pixel-rows must be a multiple of "redSize"'); end
if rem(nCol,redSize)~=0; error('number of pixel-columns must be a multiple of "redSize"'); end
nRowNew = nRow/redSize;
nColNew = nCol/redSize;
im = double(im).^2; % brightness rescaling from "linear to the human eye" to the "physics domain"; see youtube: /watch?v=LKnqECcg6Gw
im = reshape(im, nRow, redSize, nColNew*nChannel*nStack); % packets of width redSize, as columns next to each other
im = sum(im,2); % sum in all rows. Size of result: [nRow, 1, nColNew*nChannel]
im = permute(im, [3,1,2,4]); % move singleton-dimension-2 to dimension-3; transpose image. Size of result: [nColNew*nChannel, nRow, 1]
im = reshape(im, nColNew*nChannel*nStack, redSize, nRowNew); % packets of width redSize, as columns next to each other
im = sum(im,2); % sum in all rows. Size of result: [nColNew*nChannel, 1, nRowNew]
im = permute(im, [3,1,2,4]); % move singleton-dimension-2 to dimension-3; transpose image back. Size of result: [nRowNew, nColNew*nChannel, 1]
im = reshape(im, nRowNew, nColNew, nChannel, nStack); % putting all channels (rgb) back behind each other in the third dimension
im = uint8(sqrt(im./redSize^2)); % mean; re-normalize brightness: "scale linear to the human eye"; back in uint8
function map = createImMap(imRGB,nCol,startMap)
% createImMap creates a color-map including predefined colors.
% "rgb2ind" creates a map but there is no option to predefine some colors,
% and it does not handle stacked images.
% Input:
% imRGB: image, [imRows x imColumns x 3(RGB) x nStack] (unit8)
% nCol: total number of colors the map should have, [integer]
% startMap: predefined colors; colormap format, [p x 3] (double)
imRGB = permute(imRGB,[1 2 4 3]); % step1; make unified column-image (handling possible nStack)
imRGBcolumn = reshape(imRGB,[],1,3,1); % step2; make unified column-image
fullMap = double(permute(imRGBcolumn,[1 3 2]))./255; % "column image" to color map
[fullMap,~,imMapColumn] = unique(fullMap,'rows'); % find all unique colors; create indexed colormap-image
% "cmunique" could be used but is buggy and inconvenient because the output changes between "uint8" and "double"
nColFul = size(fullMap,1);
nColStart = size(startMap,1);
disp(['Number of colors: ' num2str(nColFul) ' (including ' num2str(nColStart) ' self defined)']);
if nCol<=nColStart; error('Not enough colors'); end
if nCol>nColFul; warning('More colors than needed'); end
isPreDefCol = false(size(imMapColumn)); % init
for iCol = 1:nColStart
diff = sum(abs(fullMap-repmat(startMap(iCol,:),nColFul,1)),2); % difference between a predefined and all colors
[mDiff,index] = min(diff); % find matching (or most similar) color
if mDiff>0.05 % color handling is not precise
warning(['Predefined color ' num2str(iCol) ' does not appear in image'])
continue
end
isThisPreDefCol = imMapColumn==index; % find all pixel with predefined color
disp([num2str(sum(isThisPreDefCol(:))) ' pixel have predefined color ' num2str(iCol)]);
isPreDefCol = or(isPreDefCol,isThisPreDefCol); % combine with overall list
end
[~,mapAdditional] = rgb2ind(imRGBcolumn(~isPreDefCol,:,:),nCol-nColStart,'nodither'); % create map of remaining colors
map = [startMap;mapAdditional];
|
Licensing
I, the copyright holder of this work, hereby publish it under the following license:
![]() ![]() |
This file is made available under the Creative Commons CC0 1.0 Universal Public Domain Dedication. |
The person who associated a work with this deed has dedicated the work to the public domain by waiving all of their rights to the work worldwide under copyright law, including all related and neighboring rights, to the extent allowed by law. You can copy, modify, distribute and perform the work, even for commercial purposes, all without asking permission.
http://creativecommons.org/publicdomain/zero/1.0/deed.enCC0Creative Commons Zero, Public Domain Dedicationfalsefalse |
Captions
Add a one-line explanation of what this file represents
Items portrayed in this file
depicts
1 May 2017
File history
Click on a date/time to view the file as it appeared at that time.
Date/Time | Thumbnail | Dimensions | User | Comment | |
---|---|---|---|---|---|
current | 22:27, 24 January 2021 | ![]() | 527 × 527 (7.77 MB) | Jahobr | upscale to 100 megaPixel limit |
16:52, 18 September 2017 | ![]() | 370 × 370 (4.77 MB) | Jahobr | GraphicsSmoothing; code update | |
12:29, 1 May 2017 | ![]() | 350 × 350 (4.07 MB) | Jahobr | User created page with UploadWizard |
File usage
The following pages on the English Wikipedia use this file (pages on other projects are not listed):