Zum Inhalt springen

Datei:AnimatedGears.gif

aus AufEinWort, der freien Forschung
    Originaldatei (903 × 461 Pixel, Dateigröße: 4,68 MB, MIME-Typ: image/gif, Endlosschleife, 240 Bilder, 4,8 s)
    Hinweis: Aufgrund technischer Beschränkungen werden Vorschaubilder hochauflösender GIF-Dateien wie dieser nicht animiert.

    Diese Datei stammt aus Wikimedia Commons und kann von anderen Projekten verwendet werden. Die Beschreibung von deren Dateibeschreibungsseite wird unten angezeigt.

    Beschreibung

    Beschreibung
    English: Two sets of gears. z1=14 (red); z2=42 (blue); z3=14 (yellow); z4=28 (green).
    Français : Un train de deux engrenages : le premier, le pignon rouge et la roue bleue ; le second, le pignon orange et la roue verte.
    Deutsch: Zwei Getriebestufen mit Zahnrädern. z1 = 14 (rot); z2=42 (blau); z3 = 14 (gelb); z4 = 28 (grün).

    Antrieb links, Abtrieb rechts
    iStufe1 = z2 / z1 = 42 / 14 = 3
    iStufe2 = z4 / z3 = 24 / 14 = 2

    iGes = iStufe1 · iStufe2 = 6
    Datum
    Quelle Eigenes Werk
    Urheber Jahobr
    Andere Versionen
    GIF‑Erstellung
    InfoField
     Dieses Diagramm wurde von Jahobr mit MATLAB erstellt.
    Quelltext
    InfoField

    MATLAB code

    Source code
    function animatedGears()
    % Source code for drawing gears
    % The shape of the gears is not precise, it creates a decent GIF and a SVG.
    %
    % 2019-05-12 Jahobr
    
    [pathstr,fname] = fileparts(which(mfilename)); % save files under the same name and at file location
    
    RGB.bkgd   = [1   1   1  ]; % white background
    RGB.black  = [0   0   0  ]; %
    RGB.green  = [0.1 0.7 0.1]; %
    RGB.yellow = [1   0.7 0  ]; %
    RGB.blue   = [0.2 0.2 1  ]; %
    RGB.red    = [1   0.2 0.2]; %
    % violetRGB = [0.6 0.2 0.8]; %
    
    RGB = structfun(@(q)round(q*255)/255, RGB, 'UniformOutput',false); % round to values that are nicely uint8 compatible
    
    figHandle = figure(15674459); clf
    set(figHandle,'Units','pixel');
    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;
    
    for currentCase = 3:8
        switch currentCase
            case 1 % animatedGears
                saveName = 'animatedGears';
                nFrames = 240;
                
                teeth    = [14, 3*14, 14, 2*14];
                module   = [ 2,    2,  3,    3]; % gear size
                diameter = module.*teeth;
                
                center1 = [0                                       0];
                center2 = [(diameter(1)+diameter(2))/2             0];
                center3 = [center2(1)+(diameter(3)+diameter(4))/2  0];
                
                xLimits = [center1(1)-diameter(1)/2-2*module(1)           center3(1)+diameter(4)/2+module(4)+module(1)]; % use a rim of size "module(1)"
                yLimits = [center3(2)-diameter(4)/2-module(4)-module(1)   center3(2)+diameter(4)/2+module(4)+module(1)]; % use a rim of size "module(1)"
                
                maxMovementOfTheSlowestTooth = 2*pi/teeth(4);
                anglesSlow = linspace(0,maxMovementOfTheSlowestTooth,nFrames+1);
                anglesSlow = anglesSlow(1:end-1); % remove last frame, it would be double
                secondRatio  = teeth(4)/teeth(3);
                anglesMedium = anglesSlow.*secondRatio;
                anglesMedium = anglesMedium + (2*pi/teeth(3)) *0.5; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
                firstRatio = teeth(2)/teeth(1);
                anglesFast = anglesMedium.*firstRatio;
                anglesFast = anglesFast + (2*pi/teeth(1)) *0.5; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
                
            case 2 % animated_3_Gear_Row
                saveName = 'animated_3_Gear_Row';
                nFrames  = 80;
                
                teeth    = [14, 2*14, 3*14];
                module   = [1,  1,    1]; % gear size
                diameter = module.*teeth;
                
                center1 = [0                                       0];
                center2 = [(diameter(1)+diameter(2))/2             0];
                center3 = [center2(1)+(diameter(2)+diameter(3))/2  0];
    
                xLimits = [center1(1)-diameter(1)/2-module(1)*2   center3(1)+diameter(3)/2+module(3)*2]; % use a rim of size "module(1)"
                yLimits = [center3(2)-diameter(3)/2-module(3)*2   center3(2)+diameter(3)/2+module(3)*2];  % use a rim of size "module(1)"
                
                maxMovementOfTheSlowestTooth = 2*pi/teeth(3);
                anglesSlow = linspace(0,maxMovementOfTheSlowestTooth,nFrames+1);
                anglesSlow = anglesSlow(1:end-1); % remove last frame, it would be double
                secondRatio  = teeth(3)/teeth(2);
                anglesMedium = anglesSlow.*secondRatio;
                anglesMedium = anglesMedium + (2*pi/teeth(2)) *0.5; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
                firstRatio = teeth(2)/teeth(1);
                anglesFast = anglesMedium.*firstRatio;
                anglesFast = anglesFast + (2*pi/teeth(1)) *0.5; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
                
             case 3 % animated_internal_gear
                saveName = 'animated_internal_gear';
                nFrames  = 80;
                teeth    = [14, 3*14];
    
                module   = [1,  1]; % gear size
                diameter = module.*teeth;
                
                center1 = [0 (diameter(1)-diameter(2))/2];
                center2 = [0                           0];
                
                xLimits = [center2(1)-diameter(2)/1.5   center2(1)+diameter(2)/1.5]; % 
                yLimits = [center2(2)-diameter(2)/1.5   center2(2)+diameter(2)/1.5]; % 
                
                maxMovementOfTheSlowestTooth = 2*pi/teeth(2);
                anglesSlow = linspace(0,maxMovementOfTheSlowestTooth,nFrames+1);
                anglesSlow = anglesSlow(1:end-1); % remove last frame, it would be double
                ratio  = teeth(2)/teeth(1);
                anglesFast = anglesSlow.*ratio;
                anglesFast = anglesFast + (2*pi/teeth(1)) *0.5; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
                
             case 4 % animated_rack_and_pinion
                saveName = 'animated_rack_and_pinion';
                nFrames  = 80;
                teeth    = [14, 2*14];
    
                module   = [1,  1]; % gear size
                diameter = module.*teeth;
                
                center1 = [0              0];
                center2 = [0 -diameter(1)/2];
                
                xLimits = [center1(1)-diameter(1)*1.25       center1(1)+diameter(1)*1.25]; % 
                yLimits = [center1(2)-diameter(1)   center1(2)+diameter(1)/2+module(1)*3]; % 
                
                maxMovementOfTheSlowestTooth = 2*pi/teeth(1);
                anglesSlow = linspace(0,maxMovementOfTheSlowestTooth,nFrames+1);
                anglesSlow = anglesSlow(1:end-1); % remove last frame, it would be double
                sideShift = anglesSlow.*diameter(1)/2;
                sideShift = sideShift + module(1)*3/8; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
                
            case 5 % animated_two_spur_gears
                saveName = 'animated_two_spur_gears_1_1';
                nFrames  = 80;
                teeth    = [14, 14];
                
            case 6 % animated_two_spur_gears
                saveName = 'animated_two_spur_gears_1_2';
                nFrames  = 80;
                teeth    = [14, 2*14];
                
            case 7 % animated_two_spur_gears
                saveName = 'animated_two_spur_gears_1_3';
                nFrames  = 80;
                teeth    = [14, 3*14];
                
            case 8 % animated_two_spur_gears
                saveName = 'animated_two_spur_gears_1_5';
                nFrames  = 80;
                teeth    = [14, 5*14];
        end
        
        if  contains(saveName,'animated_two_spur_gears') % all versions
            module   = [1,  1]; % gear size
            diameter = module.*teeth;
            
            center1 = [0                           0];
            center2 = [(diameter(1)+diameter(2))/2 0];
            
            xLimits = [center1(1)-diameter(1)/2-module(1)*2   center2(1)+diameter(2)/2+module(2)*2]; % use a rim of size "module(1)"
            yLimits = [center2(2)-diameter(2)/2-module(2)*2   center2(2)+diameter(2)/2+module(2)*2]; % use a rim of size "module(1)"
            
            maxMovementOfTheSlowestTooth = 2*pi/teeth(2);
            anglesSlow = linspace(0,maxMovementOfTheSlowestTooth,nFrames+1);
            anglesSlow = anglesSlow(1:end-1); % remove last frame, it would be double
            ratio  = teeth(2)/teeth(1);
            anglesFast = anglesSlow.*ratio;
            anglesFast = anglesFast + (2*pi/teeth(1)) *0.5; % ALLIGNMENT; THIS MAY NEED MANUAL ADJUSTMENT
        end
        
        xRange = xLimits(2)-xLimits(1);
        yRange = yLimits(2)-yLimits(1);
    
        screenSize = get(groot,'Screensize')-[0 0 5 20]; % [1 1 width height] (minus tolerance for figure borders)
        imageAspectRatio = xRange/yRange;
        MegaPixelTarget = 100*10^6; % Category:Animated GIF files exceeding the 100 MP limit
        pxPerImage = MegaPixelTarget/nFrames; % pixel per gif frame
        ySize = sqrt(pxPerImage/imageAspectRatio); % gif height
        xSize = ySize*imageAspectRatio; % gif width
        xSize = floor(xSize); ySize = floor(ySize); % full pixels
        scaleReduction = min(...% repeat as often as possible for nice antialiasing
            floor(screenSize(4)/ySize), floor(screenSize(3)/xSize)); 
        if scaleReduction == 0;   error('"MegaPixelTarget" not possible; use smaller target or bigger monitor'); end % check
        
        figPos = [1 1 xSize*scaleReduction ySize*scaleReduction]; % big start image for antialiasing later [x y width height]
        set(figHandle, 'Position', figPos); 
        if ~all(get(figHandle, 'Position') == figPos);   error('figure Position could not be set');   end % check
    
        setXYlim(axesHandle,xLimits,yLimits); % set limits and drawnow;
        
        reducedRGBimage = uint8(ones(ySize,xSize,3,nFrames)); % allocate
    
        liSc = mean([xSize ySize]*scaleReduction)/350; % LineWidth scale; LineWidth is absolut, a bigger images needs thicker lines to keep them in proportion
    
        for iFrame = 1:nFrames
            cla(axesHandle)
            
            switch currentCase
                case 1 % animatedGears
                    drawSpurWheel(center1,teeth(1),module(1),RGB.red   ,liSc,RGB.black,-anglesFast(iFrame));   % left cogwheel  (fast)
                    drawSpurWheel(center2,teeth(2),module(2),RGB.blue  ,liSc,RGB.black, anglesMedium(iFrame)); % cogwheel  2 (center)
                    drawSpurWheel(center2,teeth(3),module(3),RGB.yellow,liSc,RGB.black, anglesMedium(iFrame)); % cogwheel  3 (center)
                    drawSpurWheel(center3,teeth(4),module(4),RGB.green ,liSc,RGB.black,-anglesSlow(iFrame));   % right cogwheel  (slow)
                case 2 % animated_3_Gear_Row
                    drawSpurWheel(center1,teeth(1),module(1),RGB.red   ,liSc,RGB.black,-anglesFast(iFrame));   % left cogwheel  (fast)
                    drawSpurWheel(center2,teeth(2),module(2),RGB.blue  ,liSc,RGB.black, anglesMedium(iFrame)); % cogwheel  2 (center)
                    drawSpurWheel(center3,teeth(3),module(3),RGB.green ,liSc,RGB.black,-anglesSlow(iFrame));   % right cogwheel  (slow)
                case 3 % animated_internal gear
                    drawSpurWheel(center1,teeth(1),module(1),RGB.red   ,liSc,RGB.black,-anglesFast(iFrame));   % left cogwheel  (fast)
                    drawRingGear(teeth(2),module(2),RGB.green,liSc,RGB.black, -anglesSlow(iFrame));
                case 4 % animated_rack_and_pinion
                    drawSpurWheel(center1,teeth(1),module(1),RGB.red   ,liSc,RGB.black,-anglesSlow(iFrame));   % left cogwheel  (fast)
                    drawRack(center2,teeth(2),module(2),RGB.green,liSc,RGB.black,-sideShift(iFrame),0);
                case {5,6,7,8} % animated_two_spur_gears
                    drawSpurWheel(center1,teeth(1),module(1),RGB.red   ,liSc,RGB.black,-anglesFast(iFrame));   % left cogwheel  (fast)
                    drawSpurWheel(center2,teeth(2),module(2),RGB.green ,liSc,RGB.black, anglesSlow(iFrame));   % right cogwheel  (slow)
            end
            
            setXYlim(axesHandle,xLimits,yLimits); % reset limits and drawnow
    
            f = getframe(figHandle);
            reducedRGBimage(:,:,:,iFrame) = imReduceSize(f.cdata,scaleReduction); % allows subpixel lines       
            
            if iFrame == 1 % SVG
                if ~isempty(which('plot2svg'))
                    plot2svg(fullfile(pathstr, [saveName '_Frame1.svg']),figHandle) % by Juerg Schwizer
                else
                    disp('plot2svg.m not available; see http://www.zhinst.com/blogs/schwizer/');
                end
            end
        end
        
        switch currentCase % 
            case 1 % animatedGears
                map = createImMap(reducedRGBimage,32,[RGB.bkgd; RGB.black; RGB.red; RGB.blue; RGB.yellow; RGB.green]); % colormap
            case 2 % animated_3_Gear_Row
                map = createImMap(reducedRGBimage,32,[RGB.bkgd; RGB.black; RGB.red; RGB.blue;             RGB.green]); % colormap
            case 3 % animated_internal gear
                map = createImMap(reducedRGBimage,16,[RGB.bkgd; RGB.black; RGB.red;                       RGB.green]); % colormap
            case 4 % animated_rack_and_pinion
                map = createImMap(reducedRGBimage,16,[RGB.bkgd; RGB.black; RGB.red;                       RGB.green]); % colormap
            case {5,6,7,8} % animated_two_spur_gears
                map = createImMap(reducedRGBimage,16,[RGB.bkgd; RGB.black; RGB.red;                       RGB.green]); % colormap
        end
        
        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, [saveName '.gif']),'DelayTime',1/60,'LoopCount',inf) % save gif
        disp([saveName '.gif  has ' num2str(numel(im)/10^6 ,4) ' Megapixels']) % Category:Animated GIF files exceeding the 100 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 Radius
    
    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)
    
    % % effective Radius
    % [X,Y] = pol2cart(angleOffPoints,effectiveRadius);
    % X = X+center(1); % center offset
    % Y = Y+center(2); % center offset
    % plot(X,Y,'-.','Color',linC);
    
    %% shaft
    shaftRadius = module*6 /2; % small radius, assuming the effective radius a 6-tooth wheel would have
    [X,Y] = pol2cart(angleOffPoints,shaftRadius);
    X = X+center(1); % center offset
    Y = Y+center(2); % center offset
    plot(X,Y,'LineWidth',linW,'Color',linC);
    % plot(center(1),center(2),'.','Color',linC)
    
    
    function drawRingGear(toothNumber,module,fillC,linW,linC,startOffset)
    % DRAWRINGGEAR - draw a outer gear
    %    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
    
    %% outerEdge
    maxRadius = rootRadius*1.2; % definition of outer line
    [Xout,Yout] = pol2cart(angleOffPoints,maxRadius);
    
    %% inner teeth
    radiusOffPoints = angleOffPoints; % init
    
    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 tooth
    angleOffPoints(12:16:end) = angleOffPoints(12:16:end) - 1/toothNumber^1.7; % hack to create slender tooth
    
    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);
    
    [Xout,Yout] = poly2cw(Xout,Yout);
    [X,   Y   ] = poly2cw(X   ,Y   );
    [Xb,Yb] = polybool('subtraction',Xout,Yout, X,Y);
    Xb = Xb(~isnan(Xb)); % notNaN
    Yb = Yb(~isnan(Yb)); % notNaN
    patch(Xb,Yb,fillC,'EdgeColor','none')
    
    plot(X,   Y,   'LineWidth',linW,'Color',linC); % draw teeth outline
    plot(Xout,Yout,'LineWidth',linW,'Color',linC); % draw outer circle
    
    
    function drawRack(center,toothNumber,module,fillC,linW,linC,startOffset,top)
    %    center:       [x y]
    %    toothNumber:  scalar
    %    module:       scalar tooth "size"
    %    fillC:        color of filling [r g b]
    %    linW:         LineWidth
    %    linC:         LineColor
    %    startOffset: initial shift
    %    top:         1=top 0=bottom
    x = (0:toothNumber*4-2)*pi*module/4;
    x = x-mean(x)+center(1)+startOffset;
    
    y = zeros(size(x));
    
    y(1:4:end) = y(1:4:end)+1.1*module; %    +###I bottom
    y(2:4:end) = y(2:4:end)-1  *module; % +######I tip
    y(3:4:end) = y(3:4:end)-1  *module; % +######I tip
    y(4:4:end) = y(4:4:end)+1.1*module; %    +###I bottom
    
    x(1:4:end) = x(1:4:end)-0.14*module; % bottom smaller
    x(2:4:end) = x(2:4:end)+0.14*module; % tip smaller
    x(3:4:end) = x(3:4:end)-0.14*module; % tip smaller
    x(4:4:end) = x(4:4:end)+0.14*module; % bottom smaller
    
    x = [x(1)     x  x(end)];
    y = [5*module y  5*module];
    
    if ~top
        y = -y; % flip
    end
    y = y+center(2);
    patch(x,y,fillC,'EdgeColor',linC,'LineWidth',linW);
    
    
    function setXYlim(axesHandle,xLimits,yLimits)
    % set limits; practically the axis overhangs the figure all around, to
    % hide rendering error at line-ends.
    % Input:
    %   axesHandle:        
    %   xLimits, yLimits:  [min max]
    overh = 0.05; % 5% overhang all around; 10% bigger in x and y
    xlim([+xLimits(1)*(1+overh)-xLimits(2)*overh  -xLimits(1)*overh+xLimits(2)*(1+overh)])
    ylim([+yLimits(1)*(1+overh)-yLimits(2)*overh  -yLimits(1)*overh+yLimits(2)*(1+overh)])
    set(axesHandle,'Position',[-overh -overh  1+2*overh 1+2*overh]); % stretch axis as bigger as figure, [x y width height]
    drawnow;
    
    
    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];
    

    Lizenz

    Ich, der Urheber dieses Werkes, veröffentliche es unter der folgenden Lizenz:
    Creative Commons CC-Zero Diese Datei wird unter der Creative-Commons-Lizenz CC0 1.0 Verzicht auf das Copyright zur Verfügung gestellt.
    Die Person, die das Werk mit diesem Dokument verbunden hat, übergibt dieses weltweit der Gemeinfreiheit, indem sie alle Urheberrechte und damit verbundenen weiteren Rechte – im Rahmen der jeweils geltenden gesetzlichen Bestimmungen – aufgibt. Das Werk kann – selbst für kommerzielle Zwecke – kopiert, modifiziert und weiterverteilt werden, ohne hierfür um Erlaubnis bitten zu müssen.

    Kurzbeschreibungen

    Ergänze eine einzeilige Erklärung, was diese Datei darstellt.

    In dieser Datei abgebildete Objekte

    Motiv

    image/gif

    8486b0967d1ad82d82205862f1e8db6aed1c054b

    4.910.995 Byte

    4,799999999999986 Sekunde

    461 Pixel

    903 Pixel

    Dateiversionen

    Klicke auf einen Zeitpunkt, um diese Version zu laden.

    Version vomVorschaubildMaßeBenutzerKommentar
    aktuell16:33, 12. Mai 2019Vorschaubild der Version vom 16:33, 12. Mai 2019903 × 461 (4,68 MB)wikimediacommons>Jahobrhigher resolution

    Die folgende Seite verwendet diese Datei: